Android: Refactor AndroidRunner

Refactor the case when running without deployment.

Reuse existing avd recipes and run a task tree instead.

Change-Id: If0b12d2779e64e218c8da6cd07c355d85afd2ec2
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
Jarek Kobus
2024-07-11 17:37:47 +02:00
parent 3fb7008ac6
commit 2b0b5d8824
2 changed files with 35 additions and 70 deletions

View File

@@ -2,17 +2,15 @@
// Copyright (C) 2016 The Qt Company Ltd. // Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "androidrunner.h"
#include "androidavdmanager.h" #include "androidavdmanager.h"
#include "androidconfigurations.h"
#include "androiddevice.h" #include "androiddevice.h"
#include "androidmanager.h" #include "androidmanager.h"
#include "androidrunner.h"
#include "androidrunnerworker.h" #include "androidrunnerworker.h"
#include "androidtr.h" #include "androidtr.h"
#include <coreplugin/messagemanager.h>
#include <projectexplorer/projectexplorersettings.h> #include <projectexplorer/projectexplorersettings.h>
#include <projectexplorer/runconfigurationaspects.h>
#include <projectexplorer/target.h> #include <projectexplorer/target.h>
#include <qtsupport/qtkitaspect.h> #include <qtsupport/qtkitaspect.h>
#include <utils/url.h> #include <utils/url.h>
@@ -25,10 +23,10 @@ static Q_LOGGING_CATEGORY(androidRunnerLog, "qtc.android.run.androidrunner", QtW
} }
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace Tasking;
using namespace Utils; using namespace Utils;
namespace Android { namespace Android::Internal {
namespace Internal {
AndroidRunner::AndroidRunner(RunControl *runControl, const QString &intentName) AndroidRunner::AndroidRunner(RunControl *runControl, const QString &intentName)
: RunWorker(runControl), m_target(runControl->target()) : RunWorker(runControl), m_target(runControl->target())
@@ -41,9 +39,6 @@ AndroidRunner::AndroidRunner(RunControl *runControl, const QString &intentName)
}; };
Q_UNUSED(metaTypes) Q_UNUSED(metaTypes)
m_checkAVDTimer.setInterval(2000);
connect(&m_checkAVDTimer, &QTimer::timeout, this, &AndroidRunner::checkAVD);
QString intent = intentName; QString intent = intentName;
if (intent.isEmpty()) if (intent.isEmpty())
intent = AndroidManager::packageName(m_target) + '/' + AndroidManager::activityName(m_target); intent = AndroidManager::packageName(m_target) + '/' + AndroidManager::activityName(m_target);
@@ -87,27 +82,40 @@ AndroidRunner::~AndroidRunner()
void AndroidRunner::start() void AndroidRunner::start()
{ {
if (!projectExplorerSettings().deployBeforeRun) { if (!projectExplorerSettings().deployBeforeRun && m_target && m_target->project()) {
qCDebug(androidRunnerLog) << "Run without deployment"; qCDebug(androidRunnerLog) << "Run without deployment";
launchAVD();
if (!m_launchedAVDName.isEmpty()) {
m_checkAVDTimer.start();
return;
}
}
const IDevice::ConstPtr device = DeviceKitAspect::device(m_target->kit());
AndroidDeviceInfo info = AndroidDevice::androidDeviceInfoFromIDevice(device.get());
AndroidManager::setDeviceSerialNumber(m_target, info.serialNumber);
emit androidDeviceInfoChanged(info);
if (!info.avdName.isEmpty()) {
const Storage<QString> serialNumberStorage;
const Group recipe {
serialNumberStorage,
AndroidAvdManager::startAvdRecipe(info.avdName, serialNumberStorage)
};
m_startAvdRunner.start(recipe, {}, [this](DoneWith result) {
if (result == DoneWith::Success)
emit asyncStart();
});
return;
}
}
emit asyncStart(); emit asyncStart();
} }
void AndroidRunner::stop() void AndroidRunner::stop()
{ {
if (m_checkAVDTimer.isActive()) { if (m_startAvdRunner.isRunning()) {
m_checkAVDTimer.stop(); m_startAvdRunner.reset();
appendMessage("\n\n" + Tr::tr("\"%1\" terminated.").arg(m_packageName), appendMessage("\n\n" + Tr::tr("\"%1\" terminated.").arg(m_packageName),
Utils::NormalMessageFormat); Utils::NormalMessageFormat);
return; return;
} }
emit asyncStop(); emit asyncStop();
} }
@@ -153,42 +161,4 @@ void AndroidRunner::handleRemoteProcessFinished(const QString &errString)
reportStopped(); reportStopped();
} }
void AndroidRunner::launchAVD() } // namespace Android::Internal
{
if (!m_target || !m_target->project())
return;
// TODO: is this still needed?
AndroidManager::applicationAbis(m_target);
// Get AVD info
const IDevice::ConstPtr device = DeviceKitAspect::device(m_target->kit());
AndroidDeviceInfo info = AndroidDevice::androidDeviceInfoFromIDevice(device.get());
AndroidManager::setDeviceSerialNumber(m_target, info.serialNumber);
emit androidDeviceInfoChanged(info);
if (info.isValid()) {
if (!info.avdName.isEmpty() && AndroidAvdManager::findAvd(info.avdName).isEmpty())
m_launchedAVDName = AndroidAvdManager::startAvdAsync(info.avdName) ? info.avdName : "";
else
m_launchedAVDName.clear();
}
}
void AndroidRunner::checkAVD()
{
const QString serialNumber = AndroidAvdManager::findAvd(m_launchedAVDName);
if (!serialNumber.isEmpty())
return; // try again on next timer hit
if (AndroidAvdManager::isAvdBooted(serialNumber)) {
m_checkAVDTimer.stop();
AndroidManager::setDeviceSerialNumber(m_target, serialNumber);
emit asyncStart();
} else if (!AndroidConfig::isConnected(serialNumber)) {
// device was disconnected
m_checkAVDTimer.stop();
}
}
} // namespace Internal
} // namespace Android

View File

@@ -6,16 +6,15 @@
#include "androidconfigurations.h" #include "androidconfigurations.h"
#include <projectexplorer/runcontrol.h> #include <projectexplorer/runcontrol.h>
#include <qmldebug/qmldebugcommandlinearguments.h> #include <qmldebug/qmldebugcommandlinearguments.h>
#include <qmldebug/qmloutputparser.h> #include <qmldebug/qmloutputparser.h>
#include <QObject> #include <solutions/tasking/tasktreerunner.h>
#include <QTcpSocket>
#include <QThread>
#include <QTimer>
namespace Android { #include <QThread>
namespace Internal {
namespace Android::Internal {
class AndroidRunnerWorker; class AndroidRunnerWorker;
@@ -49,20 +48,16 @@ private:
void gotRemoteOutput(const QString &output); void gotRemoteOutput(const QString &output);
void handleRemoteProcessStarted(Utils::Port debugServerPort, const QUrl &qmlServer, qint64 pid); void handleRemoteProcessStarted(Utils::Port debugServerPort, const QUrl &qmlServer, qint64 pid);
void handleRemoteProcessFinished(const QString &errString = QString()); void handleRemoteProcessFinished(const QString &errString = QString());
void checkAVD();
void launchAVD();
QString m_packageName; QString m_packageName;
QString m_launchedAVDName;
QThread m_thread; QThread m_thread;
QTimer m_checkAVDTimer;
QScopedPointer<AndroidRunnerWorker> m_worker; QScopedPointer<AndroidRunnerWorker> m_worker;
QPointer<ProjectExplorer::Target> m_target; QPointer<ProjectExplorer::Target> m_target;
Utils::Port m_debugServerPort; Utils::Port m_debugServerPort;
QUrl m_qmlServer; QUrl m_qmlServer;
Utils::ProcessHandle m_pid; Utils::ProcessHandle m_pid;
QmlDebug::QmlOutputParser m_outputParser; QmlDebug::QmlOutputParser m_outputParser;
Tasking::TaskTreeRunner m_startAvdRunner;
}; };
} // namespace Internal } // namespace Android::Internal
} // namespace Android