Android: Remove multiple code paths to run adb

Refactor the code to use adb from AndroidManager, do cleanup
and improve logging

Change-Id: I77b682d37c9328e6aa978eaf05b3b5c131907f09
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Vikas Pachdha
2018-08-07 11:12:45 +02:00
parent d905131351
commit 8c95ab7ac8
4 changed files with 174 additions and 141 deletions

View File

@@ -79,18 +79,6 @@ namespace {
Q_LOGGING_CATEGORY(androidManagerLog, "qtc.android.androidManager")
bool runCommand(const QString &executable, const QStringList &args,
QString *output = nullptr, int timeoutS = 30)
{
Utils::SynchronousProcess cmdProc;
cmdProc.setTimeoutS(timeoutS);
qCDebug(androidManagerLog) << executable << args.join(' ');
Utils::SynchronousProcessResponse response = cmdProc.runBlocking(executable, args);
if (output)
*output = response.allOutput();
return response.result == Utils::SynchronousProcessResponse::Finished;
}
QString parseAaptOutput(const QString &output, const QString &regEx) {
const QRegularExpression regRx(regEx,
QRegularExpression::CaseInsensitiveOption |
@@ -162,10 +150,8 @@ bool AndroidManager::packageInstalled(const QString &deviceSerial,
return false;
QStringList args = AndroidDeviceInfo::adbSelector(deviceSerial);
args << "shell" << "pm" << "list" << "packages";
QString output;
runAdbCommand(args, &output);
QStringList lines = output.split(QRegularExpression("[\\n\\r]"),
QString::SkipEmptyParts);
QStringList lines = runAdbCommand(args).stdOut().split(QRegularExpression("[\\n\\r]"),
QString::SkipEmptyParts);
for (const QString &line : lines) {
// Don't want to confuse com.abc.xyz with com.abc.xyz.def so check with
// endsWith
@@ -180,24 +166,24 @@ void AndroidManager::apkInfo(const Utils::FileName &apkPath,
QVersionNumber *version,
QString *activityPath)
{
QString output;
runAaptCommand({"dump", "badging", apkPath.toString()}, &output);
SdkToolResult result;
result = runAaptCommand({"dump", "badging", apkPath.toString()});
QString packageStr;
if (activityPath) {
packageStr = parseAaptOutput(output, packageNameRegEx);
QString path = parseAaptOutput(output, activityRegEx);
packageStr = parseAaptOutput(result.stdOut(), packageNameRegEx);
QString path = parseAaptOutput(result.stdOut(), activityRegEx);
if (!packageStr.isEmpty() && !path.isEmpty())
*activityPath = packageStr + '/' + path;
}
if (packageName) {
*packageName = activityPath ? packageStr :
parseAaptOutput(output, packageNameRegEx);
parseAaptOutput(result.stdOut(), packageNameRegEx);
}
if (version) {
QString versionStr = parseAaptOutput(output, apkVersionRegEx);
QString versionStr = parseAaptOutput(result.stdOut(), apkVersionRegEx);
*version = QVersionNumber::fromString(versionStr);
}
}
@@ -477,8 +463,11 @@ void AndroidManager::cleanLibsOnDevice(ProjectExplorer::Target *target)
}
QStringList arguments = AndroidDeviceInfo::adbSelector(deviceSerialNumber);
arguments << QLatin1String("shell") << QLatin1String("rm") << QLatin1String("-r") << QLatin1String("/data/local/tmp/qt");
runAdbCommandDetached(arguments);
arguments << "shell" << "rm" << "-r" << "/data/local/tmp/qt";
QString error;
if (!runAdbCommandDetached(arguments, &error))
Core::MessageManager::write(tr("Cleaning Qt libraries on device failed.\n%1").arg(error));
}
void AndroidManager::installQASIPackage(ProjectExplorer::Target *target, const QString &packagePath)
@@ -499,8 +488,10 @@ void AndroidManager::installQASIPackage(ProjectExplorer::Target *target, const Q
}
QStringList arguments = AndroidDeviceInfo::adbSelector(deviceSerialNumber);
arguments << QLatin1String("install") << QLatin1String("-r ") << packagePath;
runAdbCommandDetached(arguments);
arguments << "install" << "-r " << packagePath;
QString error;
if (!runAdbCommandDetached(arguments, &error, true))
Core::MessageManager::write(tr("Android package installation failed.\n%1").arg(error));
}
bool AndroidManager::checkKeystorePassword(const QString &keystorePath, const QString &keystorePasswd)
@@ -683,27 +674,57 @@ int AndroidManager::findApiLevel(const Utils::FileName &platformPath)
return apiLevel;
}
void AndroidManager::runAdbCommandDetached(const QStringList &args)
QProcess *AndroidManager::runAdbCommandDetached(const QStringList &args, QString *err,
bool deleteOnFinish)
{
auto process = new QProcess();
connect(process, static_cast<void (QProcess::*)(int)>(&QProcess::finished),
process, &QObject::deleteLater);
std::unique_ptr<QProcess> p(new QProcess);
const QString adb = AndroidConfigurations::currentConfig().adbToolPath().toString();
qCDebug(androidManagerLog) << adb << args.join(' ');
process->start(adb, args);
if (!process->waitForStarted(500) && process->state() != QProcess::Running)
delete process;
qCDebug(androidManagerLog) << "Running command:" << adb << args.join(' ');
p->start(adb, args);
if (p->waitForStarted(500) && p->state() == QProcess::Running) {
if (deleteOnFinish) {
connect(p.get(), static_cast<void (QProcess::*)(int)>(&QProcess::finished),
p.get(), &QObject::deleteLater);
}
return p.release();
}
QString errorStr = QString::fromUtf8(p->readAllStandardError());
qCDebug(androidManagerLog) << "Running command failed" << adb << args.join(' ') << errorStr;
if (err)
*err = errorStr;
return nullptr;
}
bool AndroidManager::runAdbCommand(const QStringList &args, QString *output)
SdkToolResult AndroidManager::runCommand(const QString &executable, const QStringList &args,
const QByteArray &writeData, int timeoutS)
{
return runCommand(AndroidConfigurations::currentConfig().adbToolPath().toString(),
args, output);
Android::SdkToolResult cmdResult;
Utils::SynchronousProcess cmdProc;
cmdProc.setTimeoutS(timeoutS);
qCDebug(androidManagerLog) << "Running command: " << executable << args.join(' ');
Utils::SynchronousProcessResponse response = cmdProc.run(executable, args, writeData);
cmdResult.m_stdOut = response.stdOut().trimmed();
cmdResult.m_stdErr = response.stdErr().trimmed();
cmdResult.m_success = response.result == Utils::SynchronousProcessResponse::Finished;
qCDebug(androidManagerLog) << "Running command finshed:" << executable << args.join(' ')
<< "Success:" << cmdResult.m_success
<< "Output:" << response.allRawOutput();
if (!cmdResult.success())
cmdResult.m_exitMessage = response.exitMessage(executable, timeoutS);
return cmdResult;
}
bool AndroidManager::runAaptCommand(const QStringList &args, QString *output)
SdkToolResult AndroidManager::runAdbCommand(const QStringList &args,
const QByteArray &writeData, int timeoutS)
{
return runCommand(AndroidConfigurations::currentConfig().aaptToolPath().toString(),
args, output);
return runCommand(AndroidConfigurations::currentConfig().adbToolPath().toString(), args,
writeData, timeoutS);
}
SdkToolResult AndroidManager::runAaptCommand(const QStringList &args, int timeoutS)
{
return runCommand(AndroidConfigurations::currentConfig().aaptToolPath().toString(), args, {},
timeoutS);
}
} // namespace Android

View File

@@ -31,6 +31,10 @@
#include <QObject>
#include <QVersionNumber>
QT_BEGIN_NAMESPACE
class QProcess;
QT_END_NAMESPACE
namespace ProjectExplorer {
class Kit;
class Target;
@@ -42,6 +46,22 @@ namespace Android {
class AndroidQtSupport;
class SdkToolResult {
public:
SdkToolResult() = default;
bool success() const { return m_success; }
const QString &stdOut() { return m_stdOut; }
const QString &stdErr() { return m_stdErr; }
const QString &exitMessage() { return m_exitMessage; }
private:
bool m_success = false;
QString m_stdOut;
QString m_stdErr;
QString m_exitMessage;
friend class AndroidManager;
};
class ANDROID_EXPORT AndroidManager : public QObject
{
Q_OBJECT
@@ -94,9 +114,15 @@ public:
static bool updateGradleProperties(ProjectExplorer::Target *target);
static int findApiLevel(const Utils::FileName &platformPath);
static void runAdbCommandDetached(const QStringList &args);
static bool runAdbCommand(const QStringList &args, QString *output = nullptr);
static bool runAaptCommand(const QStringList &args, QString *output = nullptr);
static QProcess *runAdbCommandDetached(const QStringList &args, QString *err = nullptr,
bool deleteOnFinish = false);
static SdkToolResult runAdbCommand(const QStringList &args, const QByteArray &writeData = {},
int timeoutS = 30);
static SdkToolResult runAaptCommand(const QStringList &args, int timeoutS = 30);
private:
static SdkToolResult runCommand(const QString &executable, const QStringList &args,
const QByteArray &writeData = {}, int timeoutS = 30);
};
} // namespace Android

View File

@@ -94,14 +94,14 @@ static bool isTimedOut(const chrono::high_resolution_clock::time_point &start,
return timedOut;
}
static qint64 extractPID(const QByteArray &output, const QString &packageName)
static qint64 extractPID(const QString &output, const QString &packageName)
{
qint64 pid = -1;
foreach (auto tuple, output.split('\n')) {
tuple = tuple.simplified();
if (!tuple.isEmpty()) {
auto parts = tuple.split(':');
QString commandName = QString::fromLocal8Bit(parts.first());
QString commandName = parts.first();
if (parts.length() == 2 && commandName == packageName) {
pid = parts.last().toLongLong();
break;
@@ -111,9 +111,8 @@ static qint64 extractPID(const QByteArray &output, const QString &packageName)
return pid;
}
static void findProcessPID(QFutureInterface<qint64> &fi, const QString &adbPath,
QStringList selector, const QString &packageName,
bool preNougat)
static void findProcessPID(QFutureInterface<qint64> &fi, QStringList selector,
const QString &packageName, bool preNougat)
{
qCDebug(androidRunWorkerLog) << "Finding PID. PreNougat:" << preNougat;
if (packageName.isEmpty())
@@ -127,12 +126,12 @@ static void findProcessPID(QFutureInterface<qint64> &fi, const QString &adbPath,
do {
QThread::msleep(200);
const QByteArray out = Utils::SynchronousProcess().runBlocking(adbPath, selector).allRawOutput();
SdkToolResult result = AndroidManager::runAdbCommand(selector);
if (preNougat) {
processPID = extractPID(out, packageName);
processPID = extractPID(result.stdOut(), packageName);
} else {
if (!out.isEmpty())
processPID = out.trimmed().toLongLong();
if (!result.stdOut().isEmpty())
processPID = result.stdOut().trimmed().toLongLong();
}
} while (processPID == -1 && !isTimedOut(start) && !fi.isCanceled());
@@ -188,7 +187,6 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunWorker *runner, const QString &packa
m_qmlServer.setPort(server.serverPort());
qCDebug(androidRunWorkerLog) << "QML server:" << m_qmlServer.toDisplayString();
}
m_adb = AndroidConfigurations::currentConfig().adbToolPath().toString();
m_localJdbServerPort = Utils::Port(5038);
QTC_CHECK(m_localJdbServerPort.isValid());
@@ -236,40 +234,16 @@ AndroidRunnerWorker::~AndroidRunnerWorker()
m_pidFinder.cancel();
}
bool AndroidRunnerWorker::adbShellAmNeedsQuotes()
{
// Between Android SDK Tools version 24.3.1 and 24.3.4 the quoting
// needs for the 'adb shell am start ...' parameters changed.
// Run a test to find out on what side of the fence we live.
// The command will fail with a complaint about the "--dummy"
// option on newer SDKs, and with "No intent supplied" on older ones.
// In case the test itself fails assume a new SDK.
Utils::SynchronousProcess adb;
adb.setTimeoutS(10);
Utils::SynchronousProcessResponse response
= adb.run(m_adb, selector() << "shell" << "am" << "start"
<< "-e" << "dummy" << "dummy --dummy");
if (response.result == Utils::SynchronousProcessResponse::StartFailed
|| response.result != Utils::SynchronousProcessResponse::Finished)
return true;
const QString output = response.allOutput();
const bool oldSdk = output.contains("Error: No intent supplied");
return !oldSdk;
}
bool AndroidRunnerWorker::runAdb(const QStringList &args, int timeoutS, const QByteArray &writeData)
bool AndroidRunnerWorker::runAdb(const QStringList &args, QString *stdOut,
const QByteArray &writeData)
{
QStringList adbArgs = selector() + args;
qCDebug(androidRunWorkerLog) << "ADB command: " << m_adb << adbArgs.join(' ');
Utils::SynchronousProcess adb;
adb.setTimeoutS(timeoutS);
Utils::SynchronousProcessResponse response = adb.run(m_adb, adbArgs, writeData);
m_lastRunAdbError = response.exitMessage(m_adb, timeoutS);
m_lastRunAdbRawOutput = response.allRawOutput();
bool success = response.result == Utils::SynchronousProcessResponse::Finished;
qCDebug(androidRunWorkerLog) << "ADB command result:" << success << response.allRawOutput();
return success;
SdkToolResult result = AndroidManager::runAdbCommand(adbArgs, writeData);
if (!result.success())
emit remoteErrorOutput(result.exitMessage() + "\n" + result.stdErr());
if (stdOut)
*stdOut = result.stdOut();
return result.success();
}
bool AndroidRunnerWorker::uploadFile(const QString &from, const QString &to, const QString &flags)
@@ -278,7 +252,8 @@ bool AndroidRunnerWorker::uploadFile(const QString &from, const QString &to, con
if (!f.open(QIODevice::ReadOnly))
return false;
runAdb({"shell", "run-as", m_packageName, "rm", to});
auto res = runAdb({"shell", "run-as", m_packageName, "sh", "-c", QString("'cat > %1'").arg(to)}, 60, f.readAll());
auto res = runAdb({"shell", "run-as", m_packageName, "sh", "-c", QString("'cat > %1'").arg(to)},
nullptr, f.readAll());
if (!res)
return false;
return runAdb({"shell", "run-as", m_packageName, "chmod", flags, to});
@@ -297,17 +272,14 @@ QStringList AndroidRunnerWorker::selector() const
void AndroidRunnerWorker::forceStop()
{
runAdb({"shell", "am", "force-stop", m_packageName}, 30);
runAdb({"shell", "am", "force-stop", m_packageName});
// try killing it via kill -9
const QByteArray out = Utils::SynchronousProcess()
.runBlocking(m_adb, selector() << QStringLiteral("shell") << pidScriptPreNougat)
.allRawOutput();
QString out;
runAdb({"shell", pidScriptPreNougat}, &out);
qint64 pid = extractPID(out.simplified(), m_packageName);
if (pid != -1) {
if (pid != -1)
adbKill(pid);
}
}
void AndroidRunnerWorker::logcatReadStandardError()
@@ -395,17 +367,18 @@ void AndroidRunnerWorker::asyncStartHelper()
{
forceStop();
// Start the logcat process before app starts.
std::unique_ptr<QProcess, Deleter> logcatProcess(new QProcess, deleter);
connect(logcatProcess.get(), &QProcess::readyReadStandardOutput,
this, &AndroidRunnerWorker::logcatReadStandardOutput);
connect(logcatProcess.get(), &QProcess::readyReadStandardError,
this, &AndroidRunnerWorker::logcatReadStandardError);
// Its assumed that the device or avd returned by selector() is online.
logcatProcess->start(m_adb, selector() << "logcat");
// Start the logcat process before app starts.
QTC_ASSERT(!m_adbLogcatProcess, /**/);
m_adbLogcatProcess = std::move(logcatProcess);
m_adbLogcatProcess->setObjectName("AdbLogcatProcess");
m_adbLogcatProcess.reset(AndroidManager::runAdbCommandDetached(selector() << "logcat"));
if (m_adbLogcatProcess) {
m_adbLogcatProcess->setObjectName("AdbLogcatProcess");
connect(m_adbLogcatProcess.get(), &QProcess::readyReadStandardOutput,
this, &AndroidRunnerWorker::logcatReadStandardOutput);
connect(m_adbLogcatProcess.get(), &QProcess::readyReadStandardError,
this, &AndroidRunnerWorker::logcatReadStandardError);
}
for (const QString &entry : m_beforeStartAdbCommands)
runAdb(entry.split(' ', QString::SkipEmptyParts));
@@ -415,42 +388,27 @@ void AndroidRunnerWorker::asyncStartHelper()
if (m_useCppDebugger) {
args << "-D";
// run-as <package-name> pwd fails on API 22 so route the pwd through shell.
if (!runAdb({"shell", "run-as", m_packageName, "/system/bin/sh", "-c", "pwd"})) {
emit remoteProcessFinished(tr("Failed to get process path. Reason: %1.").arg(m_lastRunAdbError));
QString packageDir;
if (!runAdb({"shell", "run-as", m_packageName, "/system/bin/sh", "-c", "pwd"},
&packageDir)) {
emit remoteProcessFinished(tr("Failed to find application directory."));
return;
}
QString packageDir = QString::fromUtf8(m_lastRunAdbRawOutput.trimmed());
// Add executable flag to package dir. Gdb can't connect to running server on device on
// e.g. on Android 8 with NDK 10e
runAdb({"shell", "run-as", m_packageName, "chmod", "a+x", packageDir});
runAdb({"shell", "run-as", m_packageName, "chmod", "a+x", packageDir.trimmed()});
if (m_gdbserverPath.isEmpty() || !uploadFile(m_gdbserverPath, "gdbserver")) {
emit remoteProcessFinished(tr("Can not find/copy C++ debug server."));
return;
}
QString gdbServerSocket = packageDir + "/debug-socket";
runAdb({"shell", "run-as", m_packageName, "killall", "gdbserver"});
runAdb({"shell", "run-as", m_packageName, "rm", gdbServerSocket});
std::unique_ptr<QProcess, Deleter> gdbServerProcess(new QProcess, deleter);
gdbServerProcess->start(m_adb, selector() << "shell" << "run-as"
<< m_packageName << "./gdbserver"
<< "--multi" << "+" + gdbServerSocket);
if (!gdbServerProcess->waitForStarted()) {
emit remoteProcessFinished(tr("Failed to start C++ debugger."));
QString debuggerServerErr;
if (!startDebuggerServer(packageDir, &debuggerServerErr)) {
emit remoteProcessFinished(debuggerServerErr);
return;
}
m_gdbServerProcess = std::move(gdbServerProcess);
m_gdbServerProcess->setObjectName("GdbServerProcess");
QStringList removeForward{"forward", "--remove", "tcp:" + m_localGdbServerPort.toString()};
runAdb(removeForward);
if (!runAdb({"forward", "tcp:" + m_localGdbServerPort.toString(),
"localfilesystem:" + gdbServerSocket})) {
emit remoteProcessFinished(tr("Failed to forward C++ debugging ports. Reason: %1.").arg(m_lastRunAdbError));
return;
}
m_afterFinishAdbCommands.push_back(removeForward.join(' '));
}
if (m_qmlDebugServices != QmlDebug::NoQmlDebugServices) {
@@ -459,8 +417,7 @@ void AndroidRunnerWorker::asyncStartHelper()
QStringList removeForward{{"forward", "--remove", port}};
runAdb(removeForward);
if (!runAdb({"forward", port, port})) {
emit remoteProcessFinished(tr("Failed to forward QML debugging ports. Reason: %1.")
.arg(m_lastRunAdbError) + "\n" + m_lastRunAdbRawOutput);
emit remoteProcessFinished(tr("Failed to forward QML debugging ports."));
return;
}
m_afterFinishAdbCommands.push_back(removeForward.join(' '));
@@ -487,17 +444,49 @@ void AndroidRunnerWorker::asyncStartHelper()
}
if (!runAdb(args)) {
emit remoteProcessFinished(tr("Failed to start the activity. Reason: %1.")
.arg(m_lastRunAdbError));
emit remoteProcessFinished(tr("Failed to start the activity"));
return;
}
}
bool AndroidRunnerWorker::startDebuggerServer(QString packageDir, QString *errorStr)
{
QString gdbServerSocket = packageDir + "/debug-socket";
runAdb({"shell", "run-as", m_packageName, "killall", "gdbserver"});
runAdb({"shell", "run-as", m_packageName, "rm", gdbServerSocket});
QString gdbProcessErr;
QStringList gdbServerArgs = selector();
gdbServerArgs << "shell" << "run-as" << m_packageName << "./gdbserver" << "--multi"
<< "+" + gdbServerSocket;
m_gdbServerProcess.reset(AndroidManager::runAdbCommandDetached(gdbServerArgs, &gdbProcessErr));
if (!m_gdbServerProcess) {
qCDebug(androidRunWorkerLog) << "Debugger process failed to start" << gdbProcessErr;
if (errorStr)
*errorStr = tr("Failed to start debugger server.");
return false;
}
qCDebug(androidRunWorkerLog) << "Debugger process started";
m_gdbServerProcess->setObjectName("AndroidDebugServerProcess");
QStringList removeForward{"forward", "--remove", "tcp:" + m_localGdbServerPort.toString()};
runAdb(removeForward);
if (!runAdb({"forward", "tcp:" + m_localGdbServerPort.toString(),
"localfilesystem:" + gdbServerSocket})) {
if (errorStr)
*errorStr = tr("Failed to forward C++ debugging ports.");
return false;
}
m_afterFinishAdbCommands.push_back(removeForward.join(' '));
return true;
}
void AndroidRunnerWorker::asyncStart()
{
asyncStartHelper();
m_pidFinder = Utils::onResultReady(Utils::runAsync(findProcessPID, m_adb, selector(),
m_pidFinder = Utils::onResultReady(Utils::runAsync(findProcessPID, selector(),
m_packageName, m_isPreNougat),
bind(&AndroidRunnerWorker::onProcessIdChanged, this, _1));
}
@@ -520,7 +509,7 @@ void AndroidRunnerWorker::handleJdbWaiting()
runAdb(removeForward);
if (!runAdb({"forward", "tcp:" + m_localJdbServerPort.toString(),
"jdwp:" + QString::number(m_processPID)})) {
emit remoteProcessFinished(tr("Failed to forward jdb debugging ports. Reason: %1.").arg(m_lastRunAdbError));
emit remoteProcessFinished(tr("Failed to forward jdb debugging ports."));
return;
}
m_afterFinishAdbCommands.push_back(removeForward.join(' '));
@@ -579,8 +568,7 @@ void AndroidRunnerWorker::handleJdbSettled()
}
}
}
emit remoteProcessFinished(tr("Cannot attach jdb to the running application. Reason: %1.")
.arg(m_lastRunAdbError));
emit remoteProcessFinished(tr("Cannot attach jdb to the running application"));
}
void AndroidRunnerWorker::onProcessIdChanged(qint64 pid)
@@ -608,13 +596,13 @@ void AndroidRunnerWorker::onProcessIdChanged(qint64 pid)
emit remoteProcessStarted(m_localGdbServerPort, m_qmlServer, m_processPID);
logcatReadStandardOutput();
QTC_ASSERT(!m_psIsAlive, /**/);
m_psIsAlive.reset(new QProcess);
QStringList isAliveArgs = selector() << "shell" << pidPollingScript.arg(m_processPID);
m_psIsAlive.reset(AndroidManager::runAdbCommandDetached(isAliveArgs));
QTC_ASSERT(m_psIsAlive, return);
m_psIsAlive->setObjectName("IsAliveProcess");
m_psIsAlive->setProcessChannelMode(QProcess::MergedChannels);
connect(m_psIsAlive.get(), static_cast<void(QProcess::*)(int)>(&QProcess::finished),
this, bind(&AndroidRunnerWorker::onProcessIdChanged, this, -1));
m_psIsAlive->start(m_adb, selector() << QStringLiteral("shell")
<< pidPollingScript.arg(m_processPID));
}
}

View File

@@ -46,9 +46,9 @@ class AndroidRunnerWorker : public QObject
public:
AndroidRunnerWorker(ProjectExplorer::RunWorker *runner, const QString &packageName);
~AndroidRunnerWorker() override;
bool adbShellAmNeedsQuotes();
bool runAdb(const QStringList &args, int timeoutS = 10, const QByteArray &writeData = {});
bool uploadFile(const QString &from, const QString &to, const QString &flags = QString("+x"));
bool runAdb(const QStringList &args, QString *stdOut = nullptr, const QByteArray &writeData = {});
void adbKill(qint64 pid);
QStringList selector() const;
void forceStop();
@@ -73,6 +73,7 @@ signals:
protected:
void asyncStartHelper();
bool startDebuggerServer(QString packageDir, QString *errorStr = nullptr);
enum class JDBState {
Idle,
@@ -88,7 +89,6 @@ protected:
QString m_intentName;
QStringList m_beforeStartAdbCommands;
QStringList m_afterFinishAdbCommands;
QString m_adb;
QStringList m_amStartExtraArgs;
qint64 m_processPID = -1;
std::unique_ptr<QProcess, Deleter> m_adbLogcatProcess;
@@ -101,8 +101,6 @@ protected:
QmlDebug::QmlDebugServicesPreset m_qmlDebugServices;
Utils::Port m_localGdbServerPort; // Local end of forwarded debug socket.
QUrl m_qmlServer;
QByteArray m_lastRunAdbRawOutput;
QString m_lastRunAdbError;
JDBState m_jdbState = JDBState::Idle;
Utils::Port m_localJdbServerPort;
std::unique_ptr<QProcess, Deleter> m_gdbServerProcess;