35
35
#include "blackberrydeviceconnectionmanager.h"
36
36
#include "blackberryrunconfiguration.h"
37
37
#include "blackberrylogprocessrunner.h"
38
#include "blackberrydeviceinformation.h"
38
39
#include "qnxconstants.h"
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>
49
#include <QMessageBox>
52
#include <QTemporaryFile>
55
enum { debugCheckQmlJSArgs = 0 };
49
57
bool parseRunningState(const QString &line)
51
59
QTC_ASSERT(line.startsWith(QLatin1String("result::")), return false);
57
65
using namespace Qnx;
58
66
using namespace Qnx::Internal;
60
BlackBerryApplicationRunner::BlackBerryApplicationRunner(bool debugMode, BlackBerryRunConfiguration *runConfiguration, QObject *parent)
68
BlackBerryApplicationRunner::BlackBerryApplicationRunner(const BlackBerryApplicationRunner::LaunchFlags &launchFlags, BlackBerryRunConfiguration *runConfiguration, QObject *parent)
62
, m_debugMode(debugMode)
70
, m_launchFlags(launchFlags)
64
72
, m_appId(QString())
66
74
, m_stopping(false)
67
75
, m_launchProcess(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)
73
84
QTC_ASSERT(runConfiguration, return);
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());
131
150
emit output(msg, Utils::StdErrFormat);
153
void BlackBerryApplicationRunner::checkDeviceRuntimeVersion(int status)
155
if (status != BlackBerryNdkProcess::Success) {
156
emit output(tr("Cannot determine device runtime version."), Utils::StdErrFormat);
160
if (m_bbApiLevelVersion.isEmpty()) {
161
emit output(tr("Cannot determine API level version."), Utils::StdErrFormat);
162
checkQmlJsDebugArguments();
166
const QString runtimeVersion = m_deviceInfo->scmBundle();
167
if (m_bbApiLevelVersion.toString() != runtimeVersion) {
168
const QMessageBox::StandardButton answer =
169
QMessageBox::question(Core::ICore::mainWindow(),
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);
178
if (answer == QMessageBox::No) {
179
emit startFailed(tr("API level version does not match Runtime version."));
184
checkQmlJsDebugArguments();
187
void BlackBerryApplicationRunner::queryDeviceInformation()
190
m_deviceInfo = new BlackBerryDeviceInformation(this);
191
connect(m_deviceInfo, SIGNAL(finished(int)),
192
this, SLOT(checkDeviceRuntimeVersion(int)));
195
m_deviceInfo->setDeviceTarget(m_sshParams.host, m_sshParams.password);
196
emit output(tr("Querying device runtime version..."), Utils::StdOutFormat);
134
199
void BlackBerryApplicationRunner::startFinished(int exitCode, QProcess::ExitStatus exitStatus)
136
201
if (exitCode == 0 && exitStatus == QProcess::NormalExit && m_pid > -1) {
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;
305
void BlackBerryApplicationRunner::checkQmlJsDebugArguments()
307
if (!m_launchFlags.testFlag(QmlDebugLaunch)) {
308
// no need to change anytning in app manifest for this kind of run
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);
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()));
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);
330
void BlackBerryApplicationRunner::checkQmlJsDebugArgumentsManifestLoaded()
332
m_checkQmlJsDebugArgumentsProcess->deleteLater();
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();
341
QString manifestContent = QString::fromUtf8(m_checkQmlJsDebugArgumentsProcess->readAllStandardOutput());
343
QRegExp rxEoln(QLatin1String("(\\r\\n|\\n|\\r)"));
344
QStringList manifestLines = manifestContent.split(rxEoln);
346
QMutableListIterator<QString> it(manifestLines);
347
QLatin1String entryPoint("Entry-Point: ");
348
while (it.hasNext()) {
350
if (it.value().startsWith(entryPoint)) {
351
while (it.hasNext() && it.peekNext().startsWith(QLatin1Char(' ')))
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"));
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()));
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);
374
manifestFile->write(manifestContent.toUtf8());
375
manifestFile->flush();
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);
390
void BlackBerryApplicationRunner::checkQmlJsDebugArgumentsManifestSaved()
392
m_checkQmlJsDebugArgumentsProcess->deleteLater();
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();
240
404
void BlackBerryApplicationRunner::launchApplication()
242
406
// If original device connection fails before launching, this method maybe triggered
263
427
m_launchProcess->setEnvironment(m_environment.toStringList());
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;
436
void BlackBerryApplicationRunner::checkDeployMode()
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()))
443
if (m_launchFlags.testFlag(CppDebugLaunch))
444
queryDeviceInformation(); // check API version vs Runtime version
446
checkQmlJsDebugArguments();
271
449
void BlackBerryApplicationRunner::startRunningStateTimer()