forked from qt-creator/qt-creator
Android: Convert into a RunWorker based setup
This moves all of the RunControl implementation into a single RunWorker, not yet splitting it up into separate RunWorkers which is the final goal of this series. Change-Id: I7373105603505aa4fffd7fe5ff0145f0128b34bc Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -46,28 +46,23 @@ using namespace ProjectExplorer;
|
||||
namespace Android {
|
||||
namespace Internal {
|
||||
|
||||
RunControl *AndroidAnalyzeSupport::createAnalyzeRunControl(RunConfiguration *runConfig, Core::Id runMode)
|
||||
{
|
||||
auto runControl = new RunControl(runConfig, runMode);
|
||||
runControl->createWorker(runMode);
|
||||
QTC_ASSERT(runControl, return 0);
|
||||
AnalyzerConnection connection;
|
||||
if (runMode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) {
|
||||
QTcpServer server;
|
||||
QTC_ASSERT(server.listen(QHostAddress::LocalHost)
|
||||
|| server.listen(QHostAddress::LocalHostIPv6), return 0);
|
||||
connection.analyzerHost = server.serverAddress().toString();
|
||||
}
|
||||
runControl->setDisplayName(AndroidManager::packageName(runConfig->target()));
|
||||
runControl->setConnection(connection);
|
||||
(void) new AndroidAnalyzeSupport(runControl);
|
||||
return runControl;
|
||||
}
|
||||
|
||||
AndroidAnalyzeSupport::AndroidAnalyzeSupport(RunControl *runControl)
|
||||
: RunWorker(runControl)
|
||||
{
|
||||
auto runner = new AndroidRunner(this, runControl->runConfiguration(), runControl->runMode());
|
||||
setDisplayName("AndroidAnalyzeSupport");
|
||||
|
||||
AnalyzerConnection connection;
|
||||
if (runMode() == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) {
|
||||
QTcpServer server;
|
||||
QTC_ASSERT(server.listen(QHostAddress::LocalHost)
|
||||
|| server.listen(QHostAddress::LocalHostIPv6), return);
|
||||
connection.analyzerHost = server.serverAddress().toString();
|
||||
}
|
||||
RunConfiguration *runConfig = runControl->runConfiguration();
|
||||
runControl->setDisplayName(AndroidManager::packageName(runConfig->target()));
|
||||
runControl->setConnection(connection);
|
||||
|
||||
auto runner = new AndroidRunner(runControl);
|
||||
|
||||
connect(runControl, &RunControl::finished, runner, [runner] { runner->stop(); });
|
||||
|
||||
@@ -78,16 +73,16 @@ AndroidAnalyzeSupport::AndroidAnalyzeSupport(RunControl *runControl)
|
||||
runControl->notifyRemoteSetupDone(m_qmlPort);
|
||||
});
|
||||
|
||||
connect(runner, &AndroidRunner::remoteProcessStarted, this,
|
||||
[this](Utils::Port, Utils::Port qmlPort) {
|
||||
m_qmlPort = qmlPort;
|
||||
});
|
||||
// connect(runner, &AndroidRunner::handleRemoteProcessStarted, this,
|
||||
// [this](Utils::Port, Utils::Port qmlPort) {
|
||||
// m_qmlPort = qmlPort;
|
||||
// });
|
||||
|
||||
connect(runner, &AndroidRunner::remoteProcessFinished, this,
|
||||
[this, runControl](const QString &errorMsg) {
|
||||
runControl->notifyRemoteFinished();
|
||||
appendMessage(errorMsg, Utils::NormalMessageFormat);
|
||||
});
|
||||
// connect(runner, &AndroidRunner::handleRemoteProcessFinished, this,
|
||||
// [this, runControl](const QString &errorMsg) {
|
||||
// runControl->notifyRemoteFinished();
|
||||
// appendMessage(errorMsg, Utils::NormalMessageFormat);
|
||||
// });
|
||||
|
||||
connect(runner, &AndroidRunner::remoteErrorOutput, this,
|
||||
[this, runControl](const QString &msg) {
|
||||
|
||||
@@ -41,9 +41,6 @@ class AndroidAnalyzeSupport : public ProjectExplorer::RunWorker
|
||||
public:
|
||||
explicit AndroidAnalyzeSupport(ProjectExplorer::RunControl *runControl);
|
||||
|
||||
static ProjectExplorer::RunControl *createAnalyzeRunControl(ProjectExplorer::RunConfiguration *runConfig,
|
||||
Core::Id runMode);
|
||||
|
||||
private:
|
||||
QmlDebug::QmlOutputParser m_outputParser;
|
||||
Utils::Port m_qmlPort;
|
||||
|
||||
@@ -45,7 +45,6 @@
|
||||
#include <utils/hostosinfo.h>
|
||||
|
||||
#include <QDirIterator>
|
||||
#include <QTcpServer>
|
||||
|
||||
using namespace Debugger;
|
||||
using namespace ProjectExplorer;
|
||||
@@ -95,44 +94,47 @@ static QString toNdkArch(const QString &arch)
|
||||
return QLatin1String("arch-") + arch;
|
||||
}
|
||||
|
||||
RunControl *AndroidDebugSupport::createDebugRunControl(RunConfiguration *runConfig, QString *errorMessage)
|
||||
AndroidDebugSupport::AndroidDebugSupport(RunControl *runControl)
|
||||
: Debugger::DebuggerRunTool(runControl)
|
||||
{
|
||||
setDisplayName("AndroidDebugger");
|
||||
m_runner = new AndroidRunner(runControl);
|
||||
addDependency(m_runner);
|
||||
}
|
||||
|
||||
void AndroidDebugSupport::start()
|
||||
{
|
||||
auto runConfig = runControl()->runConfiguration();
|
||||
Target *target = runConfig->target();
|
||||
Kit *kit = target->kit();
|
||||
|
||||
DebuggerStartParameters params;
|
||||
params.startMode = AttachToRemoteServer;
|
||||
params.displayName = AndroidManager::packageName(target);
|
||||
params.remoteSetupNeeded = true;
|
||||
params.useContinueInsteadOfRun = true;
|
||||
params.attachPID = m_runner->pid();
|
||||
if (!Utils::HostOsInfo::isWindowsHost() &&
|
||||
AndroidConfigurations::currentConfig().ndkVersion() >= QVersionNumber(11, 0, 0)) {
|
||||
params.useTargetAsync = true;
|
||||
}
|
||||
|
||||
auto aspect = runConfig->extraAspect<DebuggerRunConfigurationAspect>();
|
||||
|
||||
if (aspect->useCppDebugger()) {
|
||||
Kit *kit = target->kit();
|
||||
params.symbolFile = target->activeBuildConfiguration()->buildDirectory().toString()
|
||||
+ QLatin1String("/app_process");
|
||||
if (isCppDebugging()) {
|
||||
Utils::Port gdbServerPort = m_runner->gdbServerPort();
|
||||
params.symbolFile = target->activeBuildConfiguration()->buildDirectory().toString() + "/app_process";
|
||||
params.skipExecutableValidation = true;
|
||||
auto androidRunConfig = qobject_cast<AndroidRunConfiguration *>(runConfig);
|
||||
params.remoteChannel = androidRunConfig->remoteChannel();
|
||||
params.useExtendedRemote = true;
|
||||
params.remoteChannel = ":" + gdbServerPort.toString();
|
||||
params.solibSearchPath = AndroidManager::androidQtSupport(target)->soLibSearchPath(target);
|
||||
QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(kit);
|
||||
params.solibSearchPath.append(qtSoPaths(version));
|
||||
params.solibSearchPath.append(uniquePaths(AndroidManager::androidQtSupport(target)->androidExtraLibs(target)));
|
||||
params.sysRoot = AndroidConfigurations::currentConfig().ndkLocation().appendPath(QLatin1String("platforms"))
|
||||
.appendPath(QLatin1String("android-") + QString::number(AndroidManager::minimumSDK(target)))
|
||||
params.sysRoot = AndroidConfigurations::currentConfig().ndkLocation().appendPath("platforms")
|
||||
.appendPath(QString("android-%1").arg(AndroidManager::minimumSDK(target)))
|
||||
.appendPath(toNdkArch(AndroidManager::targetArch(target))).toString();
|
||||
}
|
||||
if (aspect->useQmlDebugger()) {
|
||||
QTcpServer server;
|
||||
QTC_ASSERT(server.listen(QHostAddress::LocalHost)
|
||||
|| server.listen(QHostAddress::LocalHostIPv6), return 0);
|
||||
params.qmlServer.host = server.serverAddress().toString();
|
||||
if (isQmlDebugging()) {
|
||||
params.qmlServer.port = m_runner->qmlServerPort();
|
||||
//TODO: Not sure if these are the right paths.
|
||||
Kit *kit = target->kit();
|
||||
QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(kit);
|
||||
if (version) {
|
||||
const QString qmlQtDir = version->qmakeProperty("QT_INSTALL_QML");
|
||||
@@ -140,61 +142,18 @@ RunControl *AndroidDebugSupport::createDebugRunControl(RunConfiguration *runConf
|
||||
}
|
||||
}
|
||||
|
||||
auto runControl = new ProjectExplorer::RunControl(runConfig, ProjectExplorer::Constants::DEBUG_RUN_MODE);
|
||||
(void) new AndroidDebugSupport(runControl, params, errorMessage);
|
||||
return runControl;
|
||||
}
|
||||
|
||||
AndroidDebugSupport::AndroidDebugSupport(RunControl *runControl,
|
||||
const Debugger::DebuggerStartParameters &sp,
|
||||
QString *errorMessage)
|
||||
: DebuggerRunTool(runControl, sp, errorMessage),
|
||||
m_runner(new AndroidRunner(this, runControl->runConfiguration(), runControl->runMode()))
|
||||
{
|
||||
connect(runControl, &RunControl::finished,
|
||||
m_runner, &AndroidRunner::stop);
|
||||
|
||||
connect(this, &DebuggerRunTool::requestRemoteSetup,
|
||||
m_runner, &AndroidRunner::start);
|
||||
setStartParameters(params);
|
||||
|
||||
// FIXME: Move signal to base class and generalize handling.
|
||||
connect(this, &DebuggerRunTool::aboutToNotifyInferiorSetupOk,
|
||||
m_runner, &AndroidRunner::remoteDebuggerRunning);
|
||||
|
||||
connect(m_runner, &AndroidRunner::remoteServerRunning,
|
||||
[this](const QByteArray &serverChannel, int pid) {
|
||||
notifyEngineRemoteServerRunning(serverChannel, pid);
|
||||
});
|
||||
|
||||
connect(m_runner, &AndroidRunner::remoteProcessStarted,
|
||||
this, &AndroidDebugSupport::handleRemoteProcessStarted);
|
||||
|
||||
connect(m_runner, &AndroidRunner::remoteProcessFinished,
|
||||
[this](const QString &errorMsg) {
|
||||
appendMessage(errorMsg, Utils::DebugFormat);
|
||||
QMetaObject::invokeMethod(this->runControl(), "notifyInferiorExited", Qt::QueuedConnection);
|
||||
});
|
||||
|
||||
connect(m_runner, &AndroidRunner::remoteErrorOutput,
|
||||
[this](const QString &output) {
|
||||
showMessage(output, AppError);
|
||||
});
|
||||
|
||||
connect(m_runner, &AndroidRunner::remoteOutput,
|
||||
[this](const QString &output) {
|
||||
showMessage(output, AppOutput);
|
||||
});
|
||||
DebuggerRunTool::start();
|
||||
}
|
||||
|
||||
void AndroidDebugSupport::handleRemoteProcessStarted(Utils::Port gdbServerPort, Utils::Port qmlPort)
|
||||
void AndroidDebugSupport::stop()
|
||||
{
|
||||
disconnect(m_runner, &AndroidRunner::remoteProcessStarted,
|
||||
this, &AndroidDebugSupport::handleRemoteProcessStarted);
|
||||
RemoteSetupResult result;
|
||||
result.success = true;
|
||||
result.gdbServerPort = gdbServerPort;
|
||||
result.qmlServerPort = qmlPort;
|
||||
notifyEngineRemoteSetupFinished(result);
|
||||
DebuggerRunTool::stop();
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -25,31 +25,24 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "androidrunner.h"
|
||||
#include <debugger/debuggerruncontrol.h>
|
||||
|
||||
#include "androidrunconfiguration.h"
|
||||
|
||||
namespace Android {
|
||||
namespace Internal {
|
||||
|
||||
class AndroidRunner;
|
||||
|
||||
class AndroidDebugSupport : public Debugger::DebuggerRunTool
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AndroidDebugSupport(ProjectExplorer::RunControl *runControl,
|
||||
const Debugger::DebuggerStartParameters &sp,
|
||||
QString *errorMessage);
|
||||
AndroidDebugSupport(ProjectExplorer::RunControl *runControl);
|
||||
|
||||
static ProjectExplorer::RunControl *createDebugRunControl(ProjectExplorer::RunConfiguration *runConfig,
|
||||
QString *errorMessage);
|
||||
void start() override;
|
||||
void stop() override;
|
||||
|
||||
private:
|
||||
void handleRemoteProcessStarted(Utils::Port gdbServerPort, Utils::Port qmlPort);
|
||||
|
||||
AndroidRunner * const m_runner;
|
||||
AndroidRunner *m_runner = nullptr;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -59,9 +59,4 @@ Utils::OutputFormatter *AndroidRunConfiguration::createOutputFormatter() const
|
||||
return new QtSupport::QtOutputFormatter(target()->project());
|
||||
}
|
||||
|
||||
const QString AndroidRunConfiguration::remoteChannel() const
|
||||
{
|
||||
return QLatin1String(":5039");
|
||||
}
|
||||
|
||||
} // namespace Android
|
||||
|
||||
@@ -43,7 +43,6 @@ public:
|
||||
|
||||
QWidget *createConfigurationWidget() override;
|
||||
Utils::OutputFormatter *createOutputFormatter() const override;
|
||||
const QString remoteChannel() const;
|
||||
|
||||
protected:
|
||||
AndroidRunConfiguration(ProjectExplorer::Target *parent, AndroidRunConfiguration *source);
|
||||
|
||||
@@ -38,60 +38,25 @@ using namespace ProjectExplorer;
|
||||
namespace Android {
|
||||
namespace Internal {
|
||||
|
||||
AndroidRunControl::AndroidRunControl(RunConfiguration *rc)
|
||||
: RunControl(rc, ProjectExplorer::Constants::NORMAL_RUN_MODE)
|
||||
, m_runner(new AndroidRunner(this, rc, ProjectExplorer::Constants::NORMAL_RUN_MODE))
|
||||
AndroidRunSupport::AndroidRunSupport(RunControl *runControl)
|
||||
: AndroidRunner(runControl)
|
||||
{
|
||||
setRunnable(m_runner->runnable());
|
||||
setIcon(Utils::Icons::RUN_SMALL_TOOLBAR);
|
||||
runControl->setIcon(Utils::Icons::RUN_SMALL_TOOLBAR);
|
||||
}
|
||||
|
||||
AndroidRunControl::~AndroidRunControl()
|
||||
AndroidRunSupport::~AndroidRunSupport()
|
||||
{
|
||||
stop();
|
||||
}
|
||||
|
||||
void AndroidRunControl::start()
|
||||
void AndroidRunSupport::start()
|
||||
{
|
||||
reportApplicationStart();
|
||||
disconnect(m_runner, 0, this, 0);
|
||||
|
||||
connect(m_runner, &AndroidRunner::remoteErrorOutput,
|
||||
this, &AndroidRunControl::handleRemoteErrorOutput);
|
||||
connect(m_runner, &AndroidRunner::remoteOutput,
|
||||
this, &AndroidRunControl::handleRemoteOutput);
|
||||
connect(m_runner, &AndroidRunner::remoteProcessFinished,
|
||||
this, &AndroidRunControl::handleRemoteProcessFinished);
|
||||
appendMessage(tr("Starting remote process."), Utils::NormalMessageFormat);
|
||||
m_runner->setRunnable(runnable().as<AndroidRunnable>());
|
||||
m_runner->start();
|
||||
AndroidRunner::start();
|
||||
}
|
||||
|
||||
void AndroidRunControl::stop()
|
||||
void AndroidRunSupport::stop()
|
||||
{
|
||||
m_runner->stop();
|
||||
}
|
||||
|
||||
void AndroidRunControl::handleRemoteProcessFinished(const QString &error)
|
||||
{
|
||||
appendMessage(error, Utils::ErrorMessageFormat);
|
||||
disconnect(m_runner, 0, this, 0);
|
||||
reportApplicationStop();
|
||||
}
|
||||
|
||||
void AndroidRunControl::handleRemoteOutput(const QString &output)
|
||||
{
|
||||
appendMessage(output, Utils::StdOutFormatSameLine);
|
||||
}
|
||||
|
||||
void AndroidRunControl::handleRemoteErrorOutput(const QString &output)
|
||||
{
|
||||
appendMessage(output, Utils::StdErrFormatSameLine);
|
||||
}
|
||||
|
||||
QString AndroidRunControl::displayName() const
|
||||
{
|
||||
return m_runner->displayName();
|
||||
AndroidRunner::stop();
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "androidrunner.h"
|
||||
|
||||
#include <projectexplorer/runconfiguration.h>
|
||||
|
||||
namespace Android {
|
||||
@@ -32,24 +34,16 @@ namespace Internal {
|
||||
|
||||
class AndroidRunner;
|
||||
|
||||
class AndroidRunControl : public ProjectExplorer::RunControl
|
||||
class AndroidRunSupport : public AndroidRunner
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AndroidRunControl(ProjectExplorer::RunConfiguration *runConfig);
|
||||
~AndroidRunControl() override;
|
||||
explicit AndroidRunSupport(ProjectExplorer::RunControl *runControl);
|
||||
~AndroidRunSupport() override;
|
||||
|
||||
void start() override;
|
||||
void stop() override;
|
||||
QString displayName() const override;
|
||||
|
||||
private:
|
||||
void handleRemoteProcessFinished(const QString &error);
|
||||
void handleRemoteOutput(const QString &output);
|
||||
void handleRemoteErrorOutput(const QString &output);
|
||||
|
||||
AndroidRunner *const m_runner;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -55,16 +55,27 @@ bool AndroidRunControlFactory::canRun(RunConfiguration *runConfiguration, Core::
|
||||
return qobject_cast<AndroidRunConfiguration *>(runConfiguration);
|
||||
}
|
||||
|
||||
RunControl *AndroidRunControlFactory::create(RunConfiguration *runConfig,
|
||||
Core::Id mode, QString *errorMessage)
|
||||
RunControl *AndroidRunControlFactory::create(RunConfiguration *runConfig, Core::Id mode, QString *)
|
||||
{
|
||||
Q_ASSERT(canRun(runConfig, mode));
|
||||
if (mode == ProjectExplorer::Constants::NORMAL_RUN_MODE)
|
||||
return new AndroidRunControl(runConfig);
|
||||
if (mode == ProjectExplorer::Constants::DEBUG_RUN_MODE || mode == ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN)
|
||||
return AndroidDebugSupport::createDebugRunControl(runConfig, errorMessage);
|
||||
if (mode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE)
|
||||
return AndroidAnalyzeSupport::createAnalyzeRunControl(runConfig, mode);
|
||||
if (mode == ProjectExplorer::Constants::NORMAL_RUN_MODE) {
|
||||
auto runControl = new RunControl(runConfig, mode);
|
||||
(void) new AndroidRunSupport(runControl);
|
||||
return runControl;
|
||||
}
|
||||
if (mode == ProjectExplorer::Constants::DEBUG_RUN_MODE
|
||||
|| mode == ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN) {
|
||||
auto runControl = new RunControl(runConfig, mode);
|
||||
(void) new AndroidDebugSupport(runControl);
|
||||
return runControl;
|
||||
}
|
||||
if (mode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) {
|
||||
auto runControl = new RunControl(runConfig, mode);
|
||||
auto profiler = runControl->createWorker(mode);
|
||||
auto profilee = new AndroidAnalyzeSupport(runControl);
|
||||
profiler->addDependency(profilee);
|
||||
return runControl;
|
||||
}
|
||||
QTC_CHECK(false); // The other run modes are not supported
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
using namespace std;
|
||||
using namespace std::placeholders;
|
||||
using namespace ProjectExplorer;
|
||||
using namespace Utils;
|
||||
|
||||
/*
|
||||
This uses explicit handshakes between the application and the
|
||||
@@ -212,8 +213,8 @@ class AndroidRunnerWorker : public QObject
|
||||
};
|
||||
|
||||
public:
|
||||
AndroidRunnerWorker(AndroidRunConfiguration *runConfig, Core::Id runMode,
|
||||
const QString &packageName, const QStringList &selector);
|
||||
AndroidRunnerWorker(RunControl *runControl, const QString &packageName,
|
||||
const QStringList &selector);
|
||||
~AndroidRunnerWorker();
|
||||
|
||||
void asyncStart(const QString &intentName, const QVector<QStringList> &adbCommands);
|
||||
@@ -222,9 +223,10 @@ public:
|
||||
void setAdbParameters(const QString &packageName, const QStringList &selector);
|
||||
void handleRemoteDebuggerRunning();
|
||||
|
||||
Utils::Port localGdbServerPort() const { return m_localGdbServerPort; }
|
||||
|
||||
signals:
|
||||
void remoteServerRunning(const QByteArray &serverChannel, int pid);
|
||||
void remoteProcessStarted(Utils::Port gdbServerPort, Utils::Port qmlPort);
|
||||
void remoteProcessStarted(Utils::Port gdbServerPort, Utils::Port qmlServerPort, int pid);
|
||||
void remoteProcessFinished(const QString &errString = QString());
|
||||
|
||||
void remoteOutput(const QString &output);
|
||||
@@ -270,16 +272,17 @@ private:
|
||||
int m_socketHandShakePort = MIN_SOCKET_HANDSHAKE_PORT;
|
||||
};
|
||||
|
||||
AndroidRunnerWorker::AndroidRunnerWorker(AndroidRunConfiguration *runConfig, Core::Id runMode,
|
||||
const QString &packageName, const QStringList &selector)
|
||||
AndroidRunnerWorker::AndroidRunnerWorker(RunControl *runControl, const QString &packageName,
|
||||
const QStringList &selector)
|
||||
: m_adbLogcatProcess(nullptr, deleter)
|
||||
, m_psIsAlive(nullptr, deleter)
|
||||
, m_selector(selector)
|
||||
, m_logCatRegExp(regExpLogcat)
|
||||
, m_packageName(packageName)
|
||||
{
|
||||
Debugger::DebuggerRunConfigurationAspect *aspect
|
||||
= runConfig->extraAspect<Debugger::DebuggerRunConfigurationAspect>();
|
||||
auto runConfig = runControl->runConfiguration();
|
||||
auto aspect = runConfig->extraAspect<Debugger::DebuggerRunConfigurationAspect>();
|
||||
Core::Id runMode = runControl->runMode();
|
||||
const bool debuggingMode =
|
||||
(runMode == ProjectExplorer::Constants::DEBUG_RUN_MODE
|
||||
|| runMode == ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN);
|
||||
@@ -290,9 +293,7 @@ AndroidRunnerWorker::AndroidRunnerWorker(AndroidRunConfiguration *runConfig, Cor
|
||||
m_qmlDebugServices = QmlDebug::QmlProfilerServices;
|
||||
else
|
||||
m_qmlDebugServices = QmlDebug::NoQmlDebugServices;
|
||||
QString channel = runConfig->remoteChannel();
|
||||
QTC_CHECK(channel.startsWith(QLatin1Char(':')));
|
||||
m_localGdbServerPort = Utils::Port(channel.mid(1).toUShort());
|
||||
m_localGdbServerPort = Utils::Port(5039);
|
||||
QTC_CHECK(m_localGdbServerPort.isValid());
|
||||
if (m_qmlDebugServices != QmlDebug::NoQmlDebugServices) {
|
||||
QTcpServer server;
|
||||
@@ -384,8 +385,11 @@ void AndroidRunnerWorker::asyncStart(const QString &intentName,
|
||||
args << "shell" << "am" << "start" << "-n" << intentName;
|
||||
|
||||
if (m_useCppDebugger) {
|
||||
if (!runAdb(selector() << "forward" << "--remove" << "tcp:" + m_localGdbServerPort.toString())) {
|
||||
QTC_CHECK(false);
|
||||
}
|
||||
if (!runAdb(selector() << "forward"
|
||||
<< QString::fromLatin1("tcp:%1").arg(m_localGdbServerPort.number())
|
||||
<< "tcp:" + m_localGdbServerPort.toString()
|
||||
<< "localfilesystem:" + m_gdbserverSocket, &errorMessage)) {
|
||||
emit remoteProcessFinished(tr("Failed to forward C++ debugging ports. Reason: %1.").arg(errorMessage));
|
||||
return;
|
||||
@@ -511,6 +515,7 @@ void AndroidRunnerWorker::asyncStart(const QString &intentName,
|
||||
m_pidFinder = Utils::onResultReady(Utils::runAsync(&findProcessPID, m_adb, selector(),
|
||||
m_packageName),
|
||||
bind(&AndroidRunnerWorker::onProcessIdChanged, this, _1));
|
||||
|
||||
}
|
||||
|
||||
bool AndroidRunnerWorker::adbShellAmNeedsQuotes()
|
||||
@@ -539,8 +544,7 @@ bool AndroidRunnerWorker::runAdb(const QStringList &args, QString *exitMessage,
|
||||
{
|
||||
Utils::SynchronousProcess adb;
|
||||
adb.setTimeoutS(timeoutS);
|
||||
Utils::SynchronousProcessResponse response
|
||||
= adb.run(m_adb, args);
|
||||
Utils::SynchronousProcessResponse response = adb.run(m_adb, args);
|
||||
if (exitMessage)
|
||||
*exitMessage = response.exitMessage(m_adb, timeoutS);
|
||||
return response.result == Utils::SynchronousProcessResponse::Finished;
|
||||
@@ -561,7 +565,7 @@ void AndroidRunnerWorker::handleRemoteDebuggerRunning()
|
||||
}
|
||||
QTC_CHECK(m_processPID != -1);
|
||||
}
|
||||
emit remoteProcessStarted(m_localGdbServerPort, m_qmlPort);
|
||||
// emit remoteProcessStarted(m_localGdbServerPort, m_qmlPort);
|
||||
}
|
||||
|
||||
void AndroidRunnerWorker::asyncStop(const QVector<QStringList> &adbCommands)
|
||||
@@ -637,22 +641,9 @@ void AndroidRunnerWorker::onProcessIdChanged(qint64 pid)
|
||||
m_adbLogcatProcess.reset();
|
||||
m_psIsAlive.reset();
|
||||
} else {
|
||||
if (m_useCppDebugger) {
|
||||
// This will be funneled to the engine to actually start and attach
|
||||
// gdb. Afterwards this ends up in handleRemoteDebuggerRunning() below.
|
||||
QByteArray serverChannel = ':' + QByteArray::number(m_localGdbServerPort.number());
|
||||
emit remoteServerRunning(serverChannel, m_processPID);
|
||||
} else if (m_qmlDebugServices == QmlDebug::QmlDebuggerServices) {
|
||||
// This will be funneled to the engine to actually start and attach
|
||||
// gdb. Afterwards this ends up in handleRemoteDebuggerRunning() below.
|
||||
QByteArray serverChannel = QByteArray::number(m_qmlPort.number());
|
||||
emit remoteServerRunning(serverChannel, m_processPID);
|
||||
} else if (m_qmlDebugServices == QmlDebug::QmlProfilerServices) {
|
||||
emit remoteProcessStarted(Utils::Port(), m_qmlPort);
|
||||
} else {
|
||||
// Start without debugging.
|
||||
emit remoteProcessStarted(Utils::Port(), Utils::Port());
|
||||
}
|
||||
// In debugging cases this will be funneled to the engine to actually start
|
||||
// and attach gdb. Afterwards this ends up in handleRemoteDebuggerRunning() below.
|
||||
emit remoteProcessStarted(m_localGdbServerPort, m_qmlPort, m_processPID);
|
||||
logcatReadStandardOutput();
|
||||
QTC_ASSERT(!m_psIsAlive, /**/);
|
||||
m_psIsAlive.reset(new QProcess);
|
||||
@@ -685,9 +676,10 @@ void AndroidRunnerWorker::adbKill(qint64 pid)
|
||||
<< "kill" << "-9" << QString::number(pid));
|
||||
}
|
||||
|
||||
AndroidRunner::AndroidRunner(QObject *parent, RunConfiguration *runConfig, Core::Id runMode)
|
||||
: QObject(parent), m_runConfig(qobject_cast<AndroidRunConfiguration *>(runConfig))
|
||||
AndroidRunner::AndroidRunner(RunControl *runControl)
|
||||
: RunWorker(runControl), m_target(runControl->runConfiguration()->target())
|
||||
{
|
||||
setDisplayName("AndroidRunner");
|
||||
static const int metaTypes[] = {
|
||||
qRegisterMetaType<QVector<QStringList> >("QVector<QStringList>"),
|
||||
qRegisterMetaType<Utils::Port>("Utils::Port")
|
||||
@@ -697,14 +689,12 @@ AndroidRunner::AndroidRunner(QObject *parent, RunConfiguration *runConfig, Core:
|
||||
m_checkAVDTimer.setInterval(2000);
|
||||
connect(&m_checkAVDTimer, &QTimer::timeout, this, &AndroidRunner::checkAVD);
|
||||
|
||||
Target *target = runConfig->target();
|
||||
m_androidRunnable.intentName = AndroidManager::intentName(target);
|
||||
m_androidRunnable.intentName = AndroidManager::intentName(m_target);
|
||||
m_androidRunnable.packageName = m_androidRunnable.intentName.left(
|
||||
m_androidRunnable.intentName.indexOf(QLatin1Char('/')));
|
||||
m_androidRunnable.deviceSerialNumber = AndroidManager::deviceSerialNumber(target);
|
||||
m_androidRunnable.deviceSerialNumber = AndroidManager::deviceSerialNumber(m_target);
|
||||
|
||||
m_worker.reset(new AndroidRunnerWorker(
|
||||
m_runConfig, runMode, m_androidRunnable.packageName,
|
||||
m_worker.reset(new AndroidRunnerWorker(runControl, m_androidRunnable.packageName,
|
||||
AndroidDeviceInfo::adbSelector(m_androidRunnable.deviceSerialNumber)));
|
||||
m_worker->moveToThread(&m_thread);
|
||||
|
||||
@@ -712,15 +702,13 @@ AndroidRunner::AndroidRunner(QObject *parent, RunConfiguration *runConfig, Core:
|
||||
connect(this, &AndroidRunner::asyncStop, m_worker.data(), &AndroidRunnerWorker::asyncStop);
|
||||
connect(this, &AndroidRunner::adbParametersChanged,
|
||||
m_worker.data(), &AndroidRunnerWorker::setAdbParameters);
|
||||
connect(this, &AndroidRunner::remoteDebuggerRunning, m_worker.data(),
|
||||
&AndroidRunnerWorker::handleRemoteDebuggerRunning);
|
||||
connect(this, &AndroidRunner::remoteDebuggerRunning,
|
||||
m_worker.data(), &AndroidRunnerWorker::handleRemoteDebuggerRunning);
|
||||
|
||||
connect(m_worker.data(), &AndroidRunnerWorker::remoteServerRunning,
|
||||
this, &AndroidRunner::remoteServerRunning);
|
||||
connect(m_worker.data(), &AndroidRunnerWorker::remoteProcessStarted,
|
||||
this, &AndroidRunner::remoteProcessStarted);
|
||||
this, &AndroidRunner::handleRemoteProcessStarted);
|
||||
connect(m_worker.data(), &AndroidRunnerWorker::remoteProcessFinished,
|
||||
this, &AndroidRunner::remoteProcessFinished);
|
||||
this, &AndroidRunner::handleRemoteProcessFinished);
|
||||
connect(m_worker.data(), &AndroidRunnerWorker::remoteOutput,
|
||||
this, &AndroidRunner::remoteOutput);
|
||||
connect(m_worker.data(), &AndroidRunnerWorker::remoteErrorOutput,
|
||||
@@ -753,17 +741,36 @@ void AndroidRunner::stop()
|
||||
{
|
||||
if (m_checkAVDTimer.isActive()) {
|
||||
m_checkAVDTimer.stop();
|
||||
emit remoteProcessFinished(QLatin1String("\n\n") + tr("\"%1\" terminated.")
|
||||
.arg(m_androidRunnable.packageName));
|
||||
appendMessage("\n\n" + tr("\"%1\" terminated.").arg(m_androidRunnable.packageName),
|
||||
Utils::DebugFormat);
|
||||
return;
|
||||
}
|
||||
|
||||
emit asyncStop(m_androidRunnable.afterFinishADBCommands);
|
||||
}
|
||||
|
||||
QString AndroidRunner::displayName() const
|
||||
void AndroidRunner::remoteOutput(const QString &output)
|
||||
{
|
||||
return m_androidRunnable.packageName;
|
||||
appendMessage(output, Utils::StdOutFormatSameLine);
|
||||
}
|
||||
|
||||
void AndroidRunner::remoteErrorOutput(const QString &output)
|
||||
{
|
||||
appendMessage(output, Utils::StdErrFormatSameLine);
|
||||
}
|
||||
|
||||
void AndroidRunner::handleRemoteProcessStarted(Utils::Port gdbServerPort, Utils::Port qmlServerPort, int pid)
|
||||
{
|
||||
m_pid = ProcessHandle(pid);
|
||||
m_gdbServerPort = gdbServerPort;
|
||||
m_qmlServerPort = qmlServerPort;
|
||||
reportStarted();
|
||||
}
|
||||
|
||||
void AndroidRunner::handleRemoteProcessFinished(const QString &errString)
|
||||
{
|
||||
appendMessage(errString, Utils::DebugFormat);
|
||||
reportStopped();
|
||||
}
|
||||
|
||||
void AndroidRunner::setRunnable(const AndroidRunnable &runnable)
|
||||
@@ -777,14 +784,17 @@ void AndroidRunner::setRunnable(const AndroidRunnable &runnable)
|
||||
|
||||
void AndroidRunner::launchAVD()
|
||||
{
|
||||
int deviceAPILevel = AndroidManager::minimumSDK(m_runConfig->target());
|
||||
QString targetArch = AndroidManager::targetArch(m_runConfig->target());
|
||||
if (!m_target && !m_target->project())
|
||||
return;
|
||||
|
||||
int deviceAPILevel = AndroidManager::minimumSDK(m_target);
|
||||
QString targetArch = AndroidManager::targetArch(m_target);
|
||||
|
||||
// Get AVD info.
|
||||
AndroidDeviceInfo info = AndroidConfigurations::showDeviceDialog(
|
||||
m_runConfig->target()->project(), deviceAPILevel, targetArch,
|
||||
m_target->project(), deviceAPILevel, targetArch,
|
||||
AndroidConfigurations::None);
|
||||
AndroidManager::setDeviceSerialNumber(m_runConfig->target(), info.serialNumber);
|
||||
AndroidManager::setDeviceSerialNumber(m_target, info.serialNumber);
|
||||
m_androidRunnable.deviceSerialNumber = info.serialNumber;
|
||||
emit adbParametersChanged(m_androidRunnable.packageName,
|
||||
AndroidDeviceInfo::adbSelector(info.serialNumber));
|
||||
@@ -809,7 +819,7 @@ void AndroidRunner::checkAVD()
|
||||
|
||||
if (avdManager.isAvdBooted(serialNumber)) {
|
||||
m_checkAVDTimer.stop();
|
||||
AndroidManager::setDeviceSerialNumber(m_runConfig->target(), serialNumber);
|
||||
AndroidManager::setDeviceSerialNumber(m_target, serialNumber);
|
||||
emit asyncStart(m_androidRunnable.intentName, m_androidRunnable.beforeStartADBCommands);
|
||||
} else if (!config.isConnected(serialNumber)) {
|
||||
// device was disconnected
|
||||
|
||||
@@ -40,51 +40,54 @@
|
||||
#include <QMutex>
|
||||
|
||||
namespace Android {
|
||||
class AndroidRunConfiguration;
|
||||
|
||||
namespace Internal {
|
||||
|
||||
class AndroidRunnerWorker;
|
||||
class AndroidRunner : public QObject
|
||||
|
||||
class AndroidRunner : public ProjectExplorer::RunWorker
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AndroidRunner(QObject *parent, ProjectExplorer::RunConfiguration *runConfig, Core::Id runMode);
|
||||
~AndroidRunner();
|
||||
explicit AndroidRunner(ProjectExplorer::RunControl *runControl);
|
||||
~AndroidRunner() override;
|
||||
|
||||
QString displayName() const;
|
||||
void setRunnable(const AndroidRunnable &runnable);
|
||||
const AndroidRunnable &runnable() const { return m_androidRunnable; }
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
Utils::Port gdbServerPort() const { return m_gdbServerPort; }
|
||||
Utils::Port qmlServerPort() const { return m_qmlServerPort; }
|
||||
Utils::ProcessHandle pid() const { return m_pid; }
|
||||
|
||||
void start() override;
|
||||
void stop() override;
|
||||
|
||||
virtual void remoteOutput(const QString &output);
|
||||
virtual void remoteErrorOutput(const QString &output);
|
||||
|
||||
signals:
|
||||
void remoteServerRunning(const QByteArray &serverChannel, int pid);
|
||||
void remoteProcessStarted(Utils::Port gdbServerPort, Utils::Port qmlPort);
|
||||
void remoteProcessFinished(const QString &errString = QString());
|
||||
void remoteDebuggerRunning();
|
||||
|
||||
void remoteOutput(const QString &output);
|
||||
void remoteErrorOutput(const QString &output);
|
||||
|
||||
void asyncStart(const QString &intentName, const QVector<QStringList> &adbCommands);
|
||||
void asyncStop(const QVector<QStringList> &adbCommands);
|
||||
void remoteDebuggerRunning();
|
||||
|
||||
void adbParametersChanged(const QString &packageName, const QStringList &selector);
|
||||
void avdDetected();
|
||||
|
||||
private:
|
||||
void handleRemoteProcessStarted(Utils::Port gdbServerPort, Utils::Port qmlServerPort, int pid);
|
||||
void handleRemoteProcessFinished(const QString &errString = QString());
|
||||
void checkAVD();
|
||||
void launchAVD();
|
||||
|
||||
AndroidRunnable m_androidRunnable;
|
||||
AndroidRunConfiguration *m_runConfig;
|
||||
QString m_launchedAVDName;
|
||||
QThread m_thread;
|
||||
QTimer m_checkAVDTimer;
|
||||
QScopedPointer<AndroidRunnerWorker> m_worker;
|
||||
QPointer<ProjectExplorer::Target> m_target;
|
||||
Utils::Port m_gdbServerPort;
|
||||
Utils::Port m_qmlServerPort;
|
||||
Utils::ProcessHandle m_pid;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
Reference in New Issue
Block a user