From 5e46ff6cc31d0a139d3edef6432f205a3cf02255 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Tue, 23 Jul 2024 12:09:46 +0200 Subject: [PATCH] Android: Refactor part of asyncStartHelper() into recipe Change-Id: I2bda72784ef5c0512f0a48b02c9f49da57a597df Reviewed-by: hjk Reviewed-by: Alessandro Portale --- src/plugins/android/androidrunnerworker.cpp | 145 ++++++++++++-------- src/plugins/android/androidrunnerworker.h | 1 + 2 files changed, 86 insertions(+), 60 deletions(-) diff --git a/src/plugins/android/androidrunnerworker.cpp b/src/plugins/android/androidrunnerworker.cpp index d4d6d7d7a1e..cd35a3ddc09 100644 --- a/src/plugins/android/androidrunnerworker.cpp +++ b/src/plugins/android/androidrunnerworker.cpp @@ -445,65 +445,6 @@ void AndroidRunnerWorker::asyncStartHelper() { forceStop(); asyncStartLogcat(); - - // 1. For loop - for (const QString &entry : std::as_const(m_beforeStartAdbCommands)) - runAdb(entry.split(' ', Qt::SkipEmptyParts)); - - QStringList args({"shell", "am", "start"}); - args << "-n" << m_intentName; - if (m_useCppDebugger) - args << "-D"; - - if (m_qmlDebugServices != QmlDebug::NoQmlDebugServices) { - // currently forward to same port on device and host - const QString port = "tcp:" + QString::number(m_qmlServer.port()); - // 2. removeForwardPort recipe - if (!removeForwardPort(port, port, "QML")) - return; - - const QString qmljsdebugger = QString("port:%1,block,services:%2") - .arg(m_qmlServer.port()).arg(QmlDebug::qmlDebugServices(m_qmlDebugServices)); - - if (m_useAppParamsForQmlDebugger) { - if (!m_extraAppParams.isEmpty()) - m_extraAppParams.prepend(' '); - m_extraAppParams.prepend("-qmljsdebugger=" + qmljsdebugger); - } else { - args << "-e" << "qml_debug" << "true" - << "-e" << "qmljsdebugger" - << qmljsdebugger; - } - } - - args << m_amStartExtraArgs; - - if (!m_extraAppParams.isEmpty()) { - QStringList appArgs = - Utils::ProcessArgs::splitArgs(m_extraAppParams, Utils::OsType::OsTypeLinux); - qCDebug(androidRunWorkerLog).noquote() << "Using application arguments: " << appArgs; - args << "-e" << "extraappparams" - << QString::fromLatin1(appArgs.join(' ').toUtf8().toBase64()); - } - - if (m_extraEnvVars.hasChanges()) { - args << "-e" << "extraenvvars" - << QString::fromLatin1(m_extraEnvVars.toStringList().join('\t') - .toUtf8().toBase64()); - } - - QString stdErr; - // 3. run adb recipe - const bool startResult = runAdb(args, nullptr, &stdErr); - if (!startResult) { - emit remoteProcessFinished(Tr::tr("Failed to start the activity.")); - return; - } - - if (!stdErr.isEmpty()) { - emit remoteErrorOutput(Tr::tr("Activity Manager threw the error: %1").arg(stdErr)); - return; - } } void AndroidRunnerWorker::startNativeDebugging() @@ -644,6 +585,85 @@ ExecutableItem AndroidRunnerWorker::removeForwardPortRecipe( }; } +ExecutableItem AndroidRunnerWorker::preStartRecipe() +{ + const QString port = "tcp:" + QString::number(m_qmlServer.port()); + + const Storage argsStorage; + const LoopList iterator(m_beforeStartAdbCommands); + + const auto onArgsSetup = [this, argsStorage] { + *argsStorage = {"shell", "am", "start", "-n", m_intentName}; + if (m_useCppDebugger) + *argsStorage << "-D"; + }; + + const auto onPreCommandSetup = [this, iterator](Process &process) { + process.setCommand({AndroidConfig::adbToolPath(), + {selector(), iterator->split(' ', Qt::SkipEmptyParts)}}); + }; + const auto onPreCommandDone = [this](const Process &process) { + emit remoteErrorOutput(process.cleanedStdErr().trimmed()); + }; + + const auto onQmlDebugSetup = [this] { + return m_qmlDebugServices == QmlDebug::NoQmlDebugServices ? SetupResult::StopWithSuccess + : SetupResult::Continue; + }; + const auto onQmlDebugDone = [this, argsStorage] { + const QString qmljsdebugger = QString("port:%1,block,services:%2") + .arg(m_qmlServer.port()).arg(QmlDebug::qmlDebugServices(m_qmlDebugServices)); + + if (m_useAppParamsForQmlDebugger) { + if (!m_extraAppParams.isEmpty()) + m_extraAppParams.prepend(' '); + m_extraAppParams.prepend("-qmljsdebugger=" + qmljsdebugger); + } else { + *argsStorage << "-e" << "qml_debug" << "true" + << "-e" << "qmljsdebugger" << qmljsdebugger; + } + }; + + const auto onActivitySetup = [this, argsStorage](Process &process) { + QStringList args = *argsStorage; + args << m_amStartExtraArgs; + + if (!m_extraAppParams.isEmpty()) { + const QStringList appArgs = + ProcessArgs::splitArgs(m_extraAppParams, Utils::OsType::OsTypeLinux); + qCDebug(androidRunWorkerLog).noquote() << "Using application arguments: " << appArgs; + args << "-e" << "extraappparams" + << QString::fromLatin1(appArgs.join(' ').toUtf8().toBase64()); + } + + if (m_extraEnvVars.hasChanges()) { + args << "-e" << "extraenvvars" + << QString::fromLatin1(m_extraEnvVars.toStringList().join('\t') + .toUtf8().toBase64()); + } + process.setCommand({AndroidConfig::adbToolPath(), {selector(), args}}); + }; + const auto onActivityDone = [this](const Process &process) { + emit remoteProcessFinished(Tr::tr("Activity Manager error: %1") + .arg(process.cleanedStdErr().trimmed())); + }; + + return Group { + argsStorage, + onGroupSetup(onArgsSetup), + For { + iterator, + ProcessTask(onPreCommandSetup, onPreCommandDone, CallDoneIf::Error) + }, + Group { + onGroupSetup(onQmlDebugSetup), + removeForwardPortRecipe(port, port, "QML"), + onGroupDone(onQmlDebugDone, CallDoneIf::Success) + }, + ProcessTask(onActivitySetup, onActivityDone, CallDoneIf::Error) + }; +} + ExecutableItem AndroidRunnerWorker::pidRecipe() { const Storage pidStorage; @@ -706,7 +726,12 @@ void AndroidRunnerWorker::asyncStart() { asyncStartHelper(); - m_taskTreeRunner.start({pidRecipe()}); + const Group recipe { + preStartRecipe(), + pidRecipe() + }; + + m_taskTreeRunner.start(recipe); } void AndroidRunnerWorker::asyncStop() diff --git a/src/plugins/android/androidrunnerworker.h b/src/plugins/android/androidrunnerworker.h index ed287f2bf4e..033cf2d91ed 100644 --- a/src/plugins/android/androidrunnerworker.h +++ b/src/plugins/android/androidrunnerworker.h @@ -76,6 +76,7 @@ private: bool isPreNougat() const { return m_apiLevel > 0 && m_apiLevel <= 23; } Tasking::ExecutableItem removeForwardPortRecipe(const QString &port, const QString &adbArg, const QString &portType); + Tasking::ExecutableItem preStartRecipe(); Tasking::ExecutableItem pidRecipe(); // Create the processes and timer in the worker thread, for correct thread affinity