~ubuntu-sdk-team/qtcreator-plugin-remotelinux/trunk

« back to all changes in this revision

Viewing changes to src/qnx/blackberryapplicationrunner.cpp

  • Committer: CI bot
  • Author(s): Benjamin Zeller
  • Date: 2014-06-16 10:28:43 UTC
  • mfrom: (4.2.4 remotelinux)
  • Revision ID: ps-jenkins@lists.canonical.com-20140616102843-8juvmjvzwlzsboyw
Migrating to Qt5.3 and QtC 3.1 

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
#include "blackberrydeviceconnectionmanager.h"
36
36
#include "blackberryrunconfiguration.h"
37
37
#include "blackberrylogprocessrunner.h"
 
38
#include "blackberrydeviceinformation.h"
38
39
#include "qnxconstants.h"
39
40
 
 
41
#include <coreplugin/icore.h>
 
42
#include <projectexplorer/kit.h>
40
43
#include <projectexplorer/target.h>
41
44
#include <qmakeprojectmanager/qmakebuildconfiguration.h>
 
45
#include <debugger/debuggerrunconfigurationaspect.h>
42
46
#include <ssh/sshremoteprocessrunner.h>
43
47
#include <utils/qtcassert.h>
44
48
 
 
49
#include <QMessageBox>
45
50
#include <QTimer>
46
51
#include <QDir>
 
52
#include <QTemporaryFile>
47
53
 
48
54
namespace {
 
55
enum { debugCheckQmlJSArgs = 0 };
 
56
 
49
57
bool parseRunningState(const QString &line)
50
58
{
51
59
    QTC_ASSERT(line.startsWith(QLatin1String("result::")), return false);
57
65
using namespace Qnx;
58
66
using namespace Qnx::Internal;
59
67
 
60
 
BlackBerryApplicationRunner::BlackBerryApplicationRunner(bool debugMode, BlackBerryRunConfiguration *runConfiguration, QObject *parent)
 
68
BlackBerryApplicationRunner::BlackBerryApplicationRunner(const BlackBerryApplicationRunner::LaunchFlags &launchFlags, BlackBerryRunConfiguration *runConfiguration, QObject *parent)
61
69
    : QObject(parent)
62
 
    , m_debugMode(debugMode)
 
70
    , m_launchFlags(launchFlags)
63
71
    , m_pid(-1)
64
72
    , m_appId(QString())
65
73
    , m_running(false)
66
74
    , m_stopping(false)
67
75
    , m_launchProcess(0)
68
76
    , m_stopProcess(0)
 
77
    , m_deviceInfo(0)
69
78
    , m_logProcessRunner(0)
70
79
    , m_runningStateTimer(new QTimer(this))
71
80
    , m_runningStateProcess(0)
 
81
    , m_qmlDebugServerPort(0)
 
82
    , m_checkQmlJsDebugArgumentsProcess(0)
72
83
{
73
84
    QTC_ASSERT(runConfiguration, return);
74
85
 
77
88
    m_environment = buildConfig->environment();
78
89
    m_deployCmd = m_environment.searchInPath(QLatin1String(Constants::QNX_BLACKBERRY_DEPLOY_CMD));
79
90
 
 
91
    QFileInfo fi(target->kit()->autoDetectionSource());
 
92
    m_bbApiLevelVersion = BlackBerryVersionNumber::fromNdkEnvFileName(fi.baseName());
 
93
 
80
94
    m_device = BlackBerryDeviceConfiguration::device(target->kit());
81
95
    m_barPackage = runConfiguration->barPackage();
82
96
 
84
98
    m_sshParams = m_device->sshParameters();
85
99
    m_sshParams.authenticationType = QSsh::SshConnectionParameters::AuthenticationTypePublicKey;
86
100
 
 
101
    Debugger::DebuggerRunConfigurationAspect *aspect =
 
102
    runConfiguration->extraAspect<Debugger::DebuggerRunConfigurationAspect>();
 
103
    if (aspect)
 
104
        m_qmlDebugServerPort = aspect->qmlDebugServerPort();
 
105
 
87
106
    m_runningStateTimer->setInterval(3000);
88
107
    m_runningStateTimer->setSingleShot(true);
89
108
    connect(m_runningStateTimer, SIGNAL(timeout()), this, SLOT(determineRunningState()));
97
116
{
98
117
    if (!BlackBerryDeviceConnectionManager::instance()->isConnected(m_device->id())) {
99
118
        connect(BlackBerryDeviceConnectionManager::instance(), SIGNAL(deviceConnected()),
100
 
                this, SLOT(launchApplication()));
 
119
                this, SLOT(checkDeployMode()));
101
120
        connect(BlackBerryDeviceConnectionManager::instance(), SIGNAL(deviceDisconnected(Core::Id)),
102
121
                this, SLOT(disconnectFromDeviceSignals(Core::Id)));
103
122
        connect(BlackBerryDeviceConnectionManager::instance(), SIGNAL(connectionOutput(Core::Id,QString)),
104
123
                this, SLOT(displayConnectionOutput(Core::Id,QString)));
105
124
        BlackBerryDeviceConnectionManager::instance()->connectDevice(m_device->id());
106
125
    } else {
107
 
        launchApplication();
 
126
        checkDeployMode();
108
127
    }
109
128
}
110
129
 
131
150
        emit output(msg, Utils::StdErrFormat);
132
151
}
133
152
 
 
153
void BlackBerryApplicationRunner::checkDeviceRuntimeVersion(int status)
 
154
{
 
155
    if (status != BlackBerryNdkProcess::Success) {
 
156
        emit output(tr("Cannot determine device runtime version."), Utils::StdErrFormat);
 
157
        return;
 
158
    }
 
159
 
 
160
    if (m_bbApiLevelVersion.isEmpty()) {
 
161
        emit output(tr("Cannot determine API level version."), Utils::StdErrFormat);
 
162
        checkQmlJsDebugArguments();
 
163
        return;
 
164
    }
 
165
 
 
166
    const QString runtimeVersion = m_deviceInfo->scmBundle();
 
167
    if (m_bbApiLevelVersion.toString() != runtimeVersion) {
 
168
        const QMessageBox::StandardButton answer =
 
169
                QMessageBox::question(Core::ICore::mainWindow(),
 
170
                                      tr("Confirmation"),
 
171
                                      tr("The device runtime version(%1) does not match "
 
172
                                         "the API level version(%2).\n"
 
173
                                         "This may cause unexpected behavior when debugging.\n"
 
174
                                         "Do you want to continue anyway?")
 
175
                                      .arg(runtimeVersion, m_bbApiLevelVersion.toString()),
 
176
                                      QMessageBox::Yes | QMessageBox::No);
 
177
 
 
178
        if (answer == QMessageBox::No) {
 
179
            emit startFailed(tr("API level version does not match Runtime version."));
 
180
            return;
 
181
        }
 
182
    }
 
183
 
 
184
    checkQmlJsDebugArguments();
 
185
}
 
186
 
 
187
void BlackBerryApplicationRunner::queryDeviceInformation()
 
188
{
 
189
    if (!m_deviceInfo) {
 
190
        m_deviceInfo = new BlackBerryDeviceInformation(this);
 
191
        connect(m_deviceInfo, SIGNAL(finished(int)),
 
192
                this, SLOT(checkDeviceRuntimeVersion(int)));
 
193
    }
 
194
 
 
195
    m_deviceInfo->setDeviceTarget(m_sshParams.host, m_sshParams.password);
 
196
    emit output(tr("Querying device runtime version..."), Utils::StdOutFormat);
 
197
}
 
198
 
134
199
void BlackBerryApplicationRunner::startFinished(int exitCode, QProcess::ExitStatus exitStatus)
135
200
{
136
201
    if (exitCode == 0 && exitStatus == QProcess::NormalExit && m_pid > -1) {
219
284
{
220
285
    if (m_device->id() == deviceId) {
221
286
        disconnect(BlackBerryDeviceConnectionManager::instance(), SIGNAL(deviceConnected()),
222
 
                   this, SLOT(launchApplication()));
 
287
                   this, SLOT(checkDeployMode()));
223
288
        disconnect(BlackBerryDeviceConnectionManager::instance(), SIGNAL(deviceDisconnected(Core::Id)),
224
289
                   this, SLOT(disconnectFromDeviceSignals(Core::Id)));
225
290
        disconnect(BlackBerryDeviceConnectionManager::instance(), SIGNAL(connectionOutput(Core::Id,QString)),
237
302
    m_appId = applicationId;
238
303
}
239
304
 
 
305
void BlackBerryApplicationRunner::checkQmlJsDebugArguments()
 
306
{
 
307
    if (!m_launchFlags.testFlag(QmlDebugLaunch)) {
 
308
        // no need to change anytning in app manifest for this kind of run
 
309
        launchApplication();
 
310
    }
 
311
 
 
312
    emit output(tr("Checking qmljsdebugger command line argument."), Utils::StdOutFormat);
 
313
    QString nativePackagerCmd = m_environment.searchInPath(QLatin1String("blackberry-nativepackager"));
 
314
    if (nativePackagerCmd.isEmpty()) {
 
315
        emit output(tr("Cannot find Native Packager executable."), Utils::StdErrFormat);
 
316
        return;
 
317
    }
 
318
 
 
319
    m_checkQmlJsDebugArgumentsProcess = new QProcess(this);
 
320
    connect(m_checkQmlJsDebugArgumentsProcess, SIGNAL(error(QProcess::ProcessError)), this, SLOT(checkQmlJsDebugArgumentsManifestLoaded()));
 
321
    connect(m_checkQmlJsDebugArgumentsProcess, SIGNAL(finished(int)), this, SLOT(checkQmlJsDebugArgumentsManifestLoaded()));
 
322
 
 
323
    QStringList args;
 
324
    args << QLatin1String("-listManifest") << QDir::toNativeSeparators(m_barPackage);
 
325
    if (debugCheckQmlJSArgs)
 
326
        qDebug() << "get manifest:" << nativePackagerCmd << args.join(QLatin1String(" "));
 
327
    m_checkQmlJsDebugArgumentsProcess->start(nativePackagerCmd, args);
 
328
}
 
329
 
 
330
void BlackBerryApplicationRunner::checkQmlJsDebugArgumentsManifestLoaded()
 
331
{
 
332
    m_checkQmlJsDebugArgumentsProcess->deleteLater();
 
333
 
 
334
    if (m_checkQmlJsDebugArgumentsProcess->exitStatus() != QProcess::NormalExit) {
 
335
        emit output(tr("Cannot read bar package manifest."), Utils::StdErrFormat);
 
336
        qWarning() << "Cannot read bar package manifest:" << m_checkQmlJsDebugArgumentsProcess->errorString();
 
337
        qWarning() << m_checkQmlJsDebugArgumentsProcess->readAllStandardError();
 
338
        return;
 
339
    }
 
340
 
 
341
    QString manifestContent = QString::fromUtf8(m_checkQmlJsDebugArgumentsProcess->readAllStandardOutput());
 
342
 
 
343
    QRegExp rxEoln(QLatin1String("(\\r\\n|\\n|\\r)"));
 
344
    QStringList manifestLines = manifestContent.split(rxEoln);
 
345
 
 
346
    QMutableListIterator<QString> it(manifestLines);
 
347
    QLatin1String entryPoint("Entry-Point: ");
 
348
    while (it.hasNext()) {
 
349
        it.next();
 
350
        if (it.value().startsWith(entryPoint)) {
 
351
            while (it.hasNext() && it.peekNext().startsWith(QLatin1Char(' ')))
 
352
                it.next();
 
353
            QString qmljsdbgArg = QString::fromLatin1("-qmljsdebugger=port:%1%2")
 
354
                .arg(m_qmlDebugServerPort)
 
355
                .arg(m_launchFlags.testFlag(QmlDebugLaunchBlocking)? QLatin1String(",block"): QLatin1String(""));
 
356
            it.insert(QLatin1String("  ") + qmljsdbgArg);
 
357
            manifestContent = manifestLines.join(QLatin1String("\n"));
 
358
            break;
 
359
        }
 
360
    }
 
361
 
 
362
    m_checkQmlJsDebugArgumentsProcess = new QProcess(this);
 
363
    connect(m_checkQmlJsDebugArgumentsProcess, SIGNAL(error(QProcess::ProcessError)), this, SLOT(checkQmlJsDebugArgumentsManifestSaved()));
 
364
    connect(m_checkQmlJsDebugArgumentsProcess, SIGNAL(finished(int)), this, SLOT(checkQmlJsDebugArgumentsManifestSaved()));
 
365
 
 
366
    QTemporaryFile *manifestFile = new QTemporaryFile(m_checkQmlJsDebugArgumentsProcess);
 
367
    if (!manifestFile->open()) {
 
368
        emit output(tr("Internal error: Cannot create temporary manifest file '%1'")
 
369
            .arg(manifestFile->fileName()), Utils::StdErrFormat);
 
370
        delete manifestFile;
 
371
        return;
 
372
    }
 
373
 
 
374
    manifestFile->write(manifestContent.toUtf8());
 
375
    manifestFile->flush();
 
376
 
 
377
    QStringList args;
 
378
    args << QLatin1String("-device") << m_sshParams.host;
 
379
    if (!m_sshParams.password.isEmpty())
 
380
        args << QLatin1String("-password") << m_sshParams.password;
 
381
    args << QLatin1String("-package") << QDir::toNativeSeparators(m_barPackage);
 
382
    args << QLatin1String("-putFile");
 
383
    args << manifestFile->fileName();
 
384
    args << QLatin1String("app/META-INF/MANIFEST.MF");
 
385
    if (debugCheckQmlJSArgs)
 
386
        qDebug() << "set manifest:" << m_deployCmd << args.join(QLatin1String(" "));
 
387
    m_checkQmlJsDebugArgumentsProcess->start(m_deployCmd, args);
 
388
}
 
389
 
 
390
void BlackBerryApplicationRunner::checkQmlJsDebugArgumentsManifestSaved()
 
391
{
 
392
    m_checkQmlJsDebugArgumentsProcess->deleteLater();
 
393
 
 
394
    if (m_checkQmlJsDebugArgumentsProcess->exitStatus() != QProcess::NormalExit) {
 
395
        emit output(tr("Cannot set command line arguments."), Utils::StdErrFormat);
 
396
        qWarning() << "Cannot set command line arguments:" << m_checkQmlJsDebugArgumentsProcess->errorString();
 
397
        qWarning() << m_checkQmlJsDebugArgumentsProcess->readAllStandardError();
 
398
        return;
 
399
    }
 
400
 
 
401
    launchApplication();
 
402
}
 
403
 
240
404
void BlackBerryApplicationRunner::launchApplication()
241
405
{
242
406
    // If original device connection fails before launching, this method maybe triggered
246
410
 
247
411
    QStringList args;
248
412
    args << QLatin1String("-launchApp");
249
 
    if (m_debugMode)
 
413
    if (m_launchFlags.testFlag(CppDebugLaunch))
250
414
        args << QLatin1String("-debugNative");
251
415
    args << QLatin1String("-device") << m_sshParams.host;
252
416
    if (!m_sshParams.password.isEmpty())
253
417
        args << QLatin1String("-password") << m_sshParams.password;
254
 
    args << QDir::toNativeSeparators(m_barPackage);
 
418
    args << QLatin1String("-package") << QDir::toNativeSeparators(m_barPackage);
255
419
 
256
420
    if (!m_launchProcess) {
257
421
        m_launchProcess = new QProcess(this);
262
426
 
263
427
        m_launchProcess->setEnvironment(m_environment.toStringList());
264
428
    }
265
 
 
 
429
    if (debugCheckQmlJSArgs)
 
430
        qDebug() << "launch:" << m_deployCmd << args.join(QLatin1String(" "));
266
431
    m_launchProcess->start(m_deployCmd, args);
267
432
    m_runningStateTimer->start();
268
433
    m_running = true;
269
434
}
270
435
 
 
436
void BlackBerryApplicationRunner::checkDeployMode()
 
437
{
 
438
    // If original device connection fails before launching, this method maybe triggered
 
439
    // if any other device is connected
 
440
    if (!BlackBerryDeviceConnectionManager::instance()->isConnected(m_device->id()))
 
441
        return;
 
442
 
 
443
    if (m_launchFlags.testFlag(CppDebugLaunch))
 
444
        queryDeviceInformation(); // check API version vs Runtime version
 
445
    else
 
446
        checkQmlJsDebugArguments();
 
447
}
 
448
 
271
449
void BlackBerryApplicationRunner::startRunningStateTimer()
272
450
{
273
451
    if (m_running)