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
|
// 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 "androidsignaloperation.h"
#include "androidconfigurations.h"
#include <utils/qtcprocess.h>
using namespace Tasking;
using namespace Utils;
using namespace std::chrono_literals;
namespace Android::Internal {
AndroidSignalOperation::AndroidSignalOperation() = default;
void AndroidSignalOperation::signalOperationViaADB(qint64 pid, int signal)
{
struct InternalStorage {
FilePath adbPath = AndroidConfig::adbToolPath();
QString runAs = {};
Result<> result = ResultOk;
};
const Storage<InternalStorage> storage;
const auto onCatSetup = [storage, pid](Process &process) {
process.setCommand({storage->adbPath, {"shell", "cat", QString("/proc/%1/cmdline").arg(pid)}});
};
const auto onCatDone = [storage, pid](const Process &process, DoneWith result) {
if (result == DoneWith::Success) {
storage->runAs = process.stdOut();
if (!storage->runAs.isEmpty())
return true;
storage->result = ResultError("Cannot find User for process: " + QString::number(pid));
} else if (result == DoneWith::Error) {
QString result = " adb process exit code: " + QString::number(process.exitCode());
const QString adbError = process.errorString();
if (!adbError.isEmpty())
result += " adb process error: " + adbError;
storage->result = ResultError(result);
} else {
storage->result = ResultError("adb process timed out");
}
return false;
};
const auto onKillSetup = [storage, pid, signal](Process &process) {
process.setCommand({storage->adbPath, {"shell", "run-as", storage->runAs, "kill",
QString("-%1").arg(signal), QString::number(pid)}});
};
const auto onKillDone = [storage, pid](const Process &process, DoneWith result) {
if (result == DoneWith::Error) {
storage->result = ResultError("Cannot kill process: " + QString::number(pid)
+ process.stdErr());
} else if (result == DoneWith::Cancel) {
storage->result = ResultError("adb process timed out");
}
};
const auto onDone = [this, storage] { emit finished(storage->result); };
const Group recipe {
storage,
ProcessTask(onCatSetup, onCatDone).withTimeout(5s),
ProcessTask(onKillSetup, onKillDone).withTimeout(5s),
onGroupDone(onDone)
};
m_taskTreeRunner.start(recipe);
}
void AndroidSignalOperation::killProcess(qint64 pid)
{
signalOperationViaADB(pid, 9);
}
void AndroidSignalOperation::killProcess(const QString &filePath)
{
Q_UNUSED(filePath)
emit finished(ResultError("The android signal operation does not support killing by filepath."));
}
void AndroidSignalOperation::interruptProcess(qint64 pid)
{
signalOperationViaADB(pid, 2);
}
} // namespace Android::Internal
|