1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
// Copyright (C) 2016 BogDan Vatra <bog_dan_ro@yahoo.com>
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "androidrunner.h"
#include "androidconstants.h"
#include "androiddevice.h"
#include "androidrunnerworker.h"
#include "androidutils.h"
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/devicesupport/devicekitaspects.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/projectexplorersettings.h>
#include <projectexplorer/target.h>
#include <qtsupport/qtkitaspect.h>
#include <utils/url.h>
#include <utils/utilsicons.h>
#include <QHostAddress>
#include <QLoggingCategory>
namespace {
static Q_LOGGING_CATEGORY(androidRunnerLog, "qtc.android.run.androidrunner", QtWarningMsg)
}
using namespace ProjectExplorer;
using namespace Tasking;
using namespace Utils;
namespace Android::Internal {
Group androidRecipe(RunControl *runControl)
{
BuildConfiguration *bc = runControl->buildConfiguration();
QTC_ASSERT(bc, return {});
QString deviceSerialNumber;
int apiLevel = -1;
const Storage<RunnerInterface> glueStorage;
std::optional<ExecutableItem> avdRecipe;
if (!projectExplorerSettings().deployBeforeRun && runControl->project()) {
qCDebug(androidRunnerLog) << "Run without deployment";
const IDevice::ConstPtr device = RunDeviceKitAspect::device(runControl->kit());
AndroidDeviceInfo info = AndroidDevice::androidDeviceInfoFromDevice(device);
setDeviceSerialNumber(bc, info.serialNumber);
deviceSerialNumber = info.serialNumber;
apiLevel = info.sdk;
qCDebug(androidRunnerLog) << "Android Device Info changed" << deviceSerialNumber
<< apiLevel;
if (!info.avdName.isEmpty()) {
const Storage<QString> serialNumberStorage;
avdRecipe = Group {
serialNumberStorage,
startAvdRecipe(info.avdName, serialNumberStorage)
}.withCancel([glueStorage] {
return std::make_pair(glueStorage.activeStorage(), &RunnerInterface::canceled);
});
}
} else {
deviceSerialNumber = Internal::deviceSerialNumber(bc);
apiLevel = Internal::deviceApiLevel(bc);
}
const auto onSetup = [runControl, glueStorage, deviceSerialNumber, apiLevel] {
RunnerInterface *glue = glueStorage.activeStorage();
glue->setRunControl(runControl);
glue->setDeviceSerialNumber(deviceSerialNumber);
glue->setApiLevel(apiLevel);
auto iface = runStorage().activeStorage();
QObject::connect(iface, &RunInterface::canceled, glue, &RunnerInterface::cancel);
QObject::connect(glue, &RunnerInterface::started, runControl, [runControl, iface](qint64 pid) {
runControl->setAttachPid(ProcessHandle(pid));
emit iface->started();
});
QObject::connect(glue, &RunnerInterface::finished, runControl, [runControl](const QString &errorString) {
runControl->postMessage(errorString, Utils::NormalMessageFormat);
if (runControl->isRunning())
runControl->initiateStop();
});
};
return {
glueStorage,
onGroupSetup(onSetup),
avdRecipe ? *avdRecipe : nullItem,
runnerRecipe(glueStorage)
};
}
class AndroidRunWorkerFactory final : public RunWorkerFactory
{
public:
AndroidRunWorkerFactory()
{
setRecipeProducer(androidRecipe);
addSupportedRunMode(ProjectExplorer::Constants::NORMAL_RUN_MODE);
addSupportedRunConfig(Constants::ANDROID_RUNCONFIG_ID);
}
};
void setupAndroidRunWorker()
{
static AndroidRunWorkerFactory theAndroidRunWorkerFactory;
}
} // namespace Android::Internal
|