From 83ad1724f4ee57465b4ac007901d9b3b9fcdd974 Mon Sep 17 00:00:00 2001 From: Mehdi Fekari Date: Mon, 3 Mar 2014 09:58:13 +0100 Subject: [PATCH] Qnx: Check runtime version when debugging This cannot be done in the "check device" deploy step since the deploy configuration does not know which run mode will be used, which is mandatory since this check is only required with debug mode. Task-number: QTCREATORBUG-11513 Change-Id: I25121cf61afcf947c3873a6d2767877892ab4afc Reviewed-by: Nicolas Arnaud-Cormos --- .../qnx/blackberryapplicationrunner.cpp | 84 ++++++++++++++++--- src/plugins/qnx/blackberryapplicationrunner.h | 7 ++ 2 files changed, 80 insertions(+), 11 deletions(-) diff --git a/src/plugins/qnx/blackberryapplicationrunner.cpp b/src/plugins/qnx/blackberryapplicationrunner.cpp index c698e7a36e8..571fcbd855f 100644 --- a/src/plugins/qnx/blackberryapplicationrunner.cpp +++ b/src/plugins/qnx/blackberryapplicationrunner.cpp @@ -35,13 +35,18 @@ #include "blackberrydeviceconnectionmanager.h" #include "blackberryrunconfiguration.h" #include "blackberrylogprocessrunner.h" +#include "blackberrydeviceinformation.h" +#include "blackberryversionnumber.h" #include "qnxconstants.h" +#include +#include #include #include #include #include +#include #include #include @@ -66,18 +71,18 @@ BlackBerryApplicationRunner::BlackBerryApplicationRunner(bool cppDebugMode, Blac , m_stopping(false) , m_launchProcess(0) , m_stopProcess(0) + , m_deviceInfo(0) , m_logProcessRunner(0) , m_runningStateTimer(new QTimer(this)) , m_runningStateProcess(0) + , m_target(runConfiguration->target()) { QTC_ASSERT(runConfiguration, return); - - Target *target = runConfiguration->target(); - BuildConfiguration *buildConfig = target->activeBuildConfiguration(); + BuildConfiguration *buildConfig = m_target->activeBuildConfiguration(); m_environment = buildConfig->environment(); m_deployCmd = m_environment.searchInPath(QLatin1String(Constants::QNX_BLACKBERRY_DEPLOY_CMD)); - m_device = BlackBerryDeviceConfiguration::device(target->kit()); + m_device = BlackBerryDeviceConfiguration::device(m_target->kit()); m_barPackage = runConfiguration->barPackage(); // The BlackBerry device always uses key authentication @@ -97,14 +102,14 @@ void BlackBerryApplicationRunner::start() { if (!BlackBerryDeviceConnectionManager::instance()->isConnected(m_device->id())) { connect(BlackBerryDeviceConnectionManager::instance(), SIGNAL(deviceConnected()), - this, SLOT(launchApplication())); + this, SLOT(checkDeployMode())); connect(BlackBerryDeviceConnectionManager::instance(), SIGNAL(deviceDisconnected(Core::Id)), this, SLOT(disconnectFromDeviceSignals(Core::Id))); connect(BlackBerryDeviceConnectionManager::instance(), SIGNAL(connectionOutput(Core::Id,QString)), this, SLOT(displayConnectionOutput(Core::Id,QString))); BlackBerryDeviceConnectionManager::instance()->connectDevice(m_device->id()); } else { - launchApplication(); + checkDeployMode(); } } @@ -131,6 +136,55 @@ void BlackBerryApplicationRunner::displayConnectionOutput(Core::Id deviceId, con emit output(msg, Utils::StdErrFormat); } +void BlackBerryApplicationRunner::checkDeviceRuntimeVersion(int status) +{ + if (status != BlackBerryNdkProcess::Success) { + emit output(tr("Cannot determine device runtime version."), Utils::StdErrFormat); + return; + } + + QFileInfo fi(m_target->kit()->autoDetectionSource()); + BlackBerryVersionNumber apiVersion = + BlackBerryVersionNumber::fromNdkEnvFileName(fi.baseName()); + if (apiVersion.isEmpty()) { + emit output(tr("Cannot determine API level version."), Utils::StdErrFormat); + launchApplication(); + return; + } + + const QString runtimeVersion = m_deviceInfo->scmBundle(); + if (apiVersion.toString() != runtimeVersion) { + const QMessageBox::StandardButton answer = + QMessageBox::question(Core::ICore::mainWindow(), + tr("Confirmation"), + tr("The device runtime version(%1) does not match " + "the API level version(%2).\n" + "This may cause unexpected behavior when debugging.\n" + "Do you want to continue anyway?") + .arg(runtimeVersion, apiVersion.toString()), + QMessageBox::Yes | QMessageBox::No); + + if (answer == QMessageBox::No) { + emit startFailed(tr("API level version does not match Runtime version.")); + return; + } + } + + launchApplication(); +} + +void BlackBerryApplicationRunner::queryDeviceInformation() +{ + if (!m_deviceInfo) { + m_deviceInfo = new BlackBerryDeviceInformation(this); + connect(m_deviceInfo, SIGNAL(finished(int)), + this, SLOT(checkDeviceRuntimeVersion(int))); + } + + m_deviceInfo->setDeviceTarget(m_sshParams.host, m_sshParams.password); + emit output(tr("Querying device runtime version..."), Utils::StdOutFormat); +} + void BlackBerryApplicationRunner::startFinished(int exitCode, QProcess::ExitStatus exitStatus) { if (exitCode == 0 && exitStatus == QProcess::NormalExit && m_pid > -1) { @@ -239,11 +293,6 @@ void BlackBerryApplicationRunner::setApplicationId(const QString &applicationId) void BlackBerryApplicationRunner::launchApplication() { - // If original device connection fails before launching, this method maybe triggered - // if any other device is connected(?) - if (!BlackBerryDeviceConnectionManager::instance()->isConnected(m_device->id())) - return; - QStringList args; args << QLatin1String("-launchApp"); if (m_cppDebugMode) @@ -268,6 +317,19 @@ void BlackBerryApplicationRunner::launchApplication() m_running = true; } +void BlackBerryApplicationRunner::checkDeployMode() +{ + // If original device connection fails before launching, this method maybe triggered + // if any other device is connected + if (!BlackBerryDeviceConnectionManager::instance()->isConnected(m_device->id())) + return; + + if (m_debugMode) + queryDeviceInformation(); // check API version vs Runtime version + else + launchApplication(); +} + void BlackBerryApplicationRunner::startRunningStateTimer() { if (m_running) diff --git a/src/plugins/qnx/blackberryapplicationrunner.h b/src/plugins/qnx/blackberryapplicationrunner.h index 4cd3a90f58c..26b3eb01d6b 100644 --- a/src/plugins/qnx/blackberryapplicationrunner.h +++ b/src/plugins/qnx/blackberryapplicationrunner.h @@ -45,12 +45,14 @@ #include namespace QSsh { class SshRemoteProcessRunner; } +namespace ProjectExplorer { class Target; } namespace Qnx { namespace Internal { class BlackBerryRunConfiguration; class BlackBerryLogProcessRunner; +class BlackBerryDeviceInformation; class BlackBerryApplicationRunner : public QObject { @@ -89,12 +91,15 @@ private slots: void setApplicationId(const QString &applicationId); void launchApplication(); + void checkDeployMode(); void startLogProcessRunner(); void displayConnectionOutput(Core::Id deviceId, const QString &output); + void checkDeviceRuntimeVersion(int status); private: void reset(); + void queryDeviceInformation(); bool m_cppDebugMode; @@ -113,11 +118,13 @@ private: QProcess *m_launchProcess; QProcess *m_stopProcess; BlackBerryProcessParser m_launchStopProcessParser; + BlackBerryDeviceInformation *m_deviceInfo; BlackBerryLogProcessRunner *m_logProcessRunner; QTimer *m_runningStateTimer; QProcess *m_runningStateProcess; + ProjectExplorer::Target *m_target; }; } // namespace Internal