diff --git a/src/plugins/qnx/blackberryapplicationrunner.cpp b/src/plugins/qnx/blackberryapplicationrunner.cpp index c698e7a36e816008b624d4400f4d72d0d2b1795d..571fcbd855f73b41f2319745eae7c33224356bfb 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 <coreplugin/icore.h> +#include <projectexplorer/kit.h> #include <projectexplorer/target.h> #include <qmakeprojectmanager/qmakebuildconfiguration.h> #include <ssh/sshremoteprocessrunner.h> #include <utils/qtcassert.h> +#include <QMessageBox> #include <QTimer> #include <QDir> @@ -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 4cd3a90f58cb6e130078ec4e999071e5dfe94c05..26b3eb01d6bec34bb3174a6e536955f6f5d9c033 100644 --- a/src/plugins/qnx/blackberryapplicationrunner.h +++ b/src/plugins/qnx/blackberryapplicationrunner.h @@ -45,12 +45,14 @@ #include <QDateTime> 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