From dee57f69fe10fce39bcf7c367491109a63dc7b52 Mon Sep 17 00:00:00 2001
From: El Mehdi Fekari <mfekari@blackberry.com>
Date: Wed, 5 Mar 2014 14:59:15 +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: I0356f792a8f08e5521a80675b60c64b337cabafb
Reviewed-by: Tobias Hunger <tobias.hunger@digia.com>
---
 .../qnx/blackberryapplicationrunner.cpp       | 67 +++++++++++++++++++
 src/plugins/qnx/blackberryapplicationrunner.h |  8 +++
 2 files changed, 75 insertions(+)

diff --git a/src/plugins/qnx/blackberryapplicationrunner.cpp b/src/plugins/qnx/blackberryapplicationrunner.cpp
index c698e7a36e8..c894235bcd1 100644
--- a/src/plugins/qnx/blackberryapplicationrunner.cpp
+++ b/src/plugins/qnx/blackberryapplicationrunner.cpp
@@ -35,13 +35,17 @@
 #include "blackberrydeviceconnectionmanager.h"
 #include "blackberryrunconfiguration.h"
 #include "blackberrylogprocessrunner.h"
+#include "blackberrydeviceinformation.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,6 +70,7 @@ 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)
@@ -77,6 +82,9 @@ BlackBerryApplicationRunner::BlackBerryApplicationRunner(bool cppDebugMode, Blac
     m_environment = buildConfig->environment();
     m_deployCmd = m_environment.searchInPath(QLatin1String(Constants::QNX_BLACKBERRY_DEPLOY_CMD));
 
+    QFileInfo fi(target->kit()->autoDetectionSource());
+    m_bbApiLevelVersion = BlackBerryVersionNumber::fromNdkEnvFileName(fi.baseName());
+
     m_device = BlackBerryDeviceConfiguration::device(target->kit());
     m_barPackage = runConfiguration->barPackage();
 
@@ -131,6 +139,52 @@ 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;
+    }
+
+    if (m_bbApiLevelVersion.isEmpty()) {
+        emit output(tr("Cannot determine API level version."), Utils::StdErrFormat);
+        launchApplication();
+        return;
+    }
+
+    const QString runtimeVersion = m_deviceInfo->scmBundle();
+    if (m_bbApiLevelVersion.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, m_bbApiLevelVersion.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) {
@@ -268,6 +322,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_cppDebugMode)
+        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..fc8f2a0f3d3 100644
--- a/src/plugins/qnx/blackberryapplicationrunner.h
+++ b/src/plugins/qnx/blackberryapplicationrunner.h
@@ -34,6 +34,7 @@
 
 #include "blackberrydeviceconfiguration.h"
 #include "blackberryprocessparser.h"
+#include "blackberryversionnumber.h"
 
 #include <projectexplorer/runconfiguration.h>
 
@@ -51,6 +52,7 @@ 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,14 @@ private:
     QProcess *m_launchProcess;
     QProcess *m_stopProcess;
     BlackBerryProcessParser m_launchStopProcessParser;
+    BlackBerryDeviceInformation *m_deviceInfo;
 
     BlackBerryLogProcessRunner *m_logProcessRunner;
 
     QTimer *m_runningStateTimer;
     QProcess *m_runningStateProcess;
+
+    BlackBerryVersionNumber m_bbApiLevelVersion;
 };
 
 } // namespace Internal
-- 
GitLab