Refactor ADB utilities to use dynamic adb paths and streamline processes.
Updated all ADB operations to use the dynamically determined adb path for better platform compatibility. Consolidated redundant process-handling code using a new `startProcess` helper method to simplify and standardize command execution. Enhanced `getScreenDumpAsXml` and related functions to improve modularity and maintainability.
This commit is contained in:
parent
b8b2b38f8a
commit
6988794657
@ -9,12 +9,36 @@ AdbUtils::AdbUtils(QObject *parent) : QObject(parent) {
|
||||
|
||||
QString AdbUtils::adbPath() {
|
||||
#ifdef Q_OS_WIN
|
||||
return QCoreApplication::applicationDirPath() + "/tools/adb/adb.exe";
|
||||
return QCoreApplication::applicationDirPath() + "/tools/adb/windows/adb.exe";
|
||||
#else
|
||||
return QCoreApplication::applicationDirPath() + "/tools/adb/macos/adb";
|
||||
#endif
|
||||
}
|
||||
|
||||
bool AdbUtils::startProcess(const QString &cmd, QString *stdOut = nullptr, QString *stdErr = nullptr) {
|
||||
QProcess process;
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
process.start("cmd.exe", {"/C", cmd});
|
||||
#else
|
||||
process.start("sh", {"-c", cmd});
|
||||
#endif
|
||||
|
||||
if (!process.waitForFinished() ||
|
||||
process.exitStatus() != QProcess::NormalExit ||
|
||||
process.exitCode() != 0) {
|
||||
if (stdErr) {
|
||||
*stdErr = QString::fromUtf8(process.readAllStandardError());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stdOut) {
|
||||
*stdOut = QString::fromUtf8(process.readAllStandardOutput());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// adb shell dumpsys package ru.rshb.dbo | grep permission
|
||||
// TODO доделать обработку пермишинов
|
||||
// adb shell pm revoke ru.rshb.dbo android.permission.WRITE_CONTACTS; adb shell pm revoke ru.rshb.dbo android.permission.READ_CONTACTS; adb shell pm revoke ru.rshb.dbo android.permission.ACCESS_COARSE_LOCATION; adb shell pm revoke ru.rshb.dbo android.permission.ACCESS_FINE_LOCATION
|
||||
@ -26,7 +50,7 @@ QString AdbUtils::adbPath() {
|
||||
*/
|
||||
QList<QPair<QString, QString> > AdbUtils::getListDevices() {
|
||||
QProcess process;
|
||||
process.start("adb", {"devices"});
|
||||
process.start(adbPath(), {"devices"});
|
||||
process.waitForFinished();
|
||||
|
||||
const QString output = process.readAllStandardOutput();
|
||||
@ -56,7 +80,7 @@ QList<QPair<QString, QString> > AdbUtils::getListDevices() {
|
||||
|
||||
QString AdbUtils::tryToGetRunningAppPid(const QString &deviceId, const QString &packageName) {
|
||||
QProcess process;
|
||||
process.start("adb", {
|
||||
process.start(adbPath(), {
|
||||
"-s", deviceId,
|
||||
"shell", "pidof", packageName
|
||||
});
|
||||
@ -67,7 +91,7 @@ QString AdbUtils::tryToGetRunningAppPid(const QString &deviceId, const QString &
|
||||
|
||||
bool AdbUtils::tryToStartApplication(const QString &deviceId, const QString &packageName) {
|
||||
QProcess process;
|
||||
process.start("adb", {
|
||||
process.start(adbPath(), {
|
||||
"-s", deviceId,
|
||||
"shell", "monkey",
|
||||
"-p", packageName,
|
||||
@ -90,7 +114,7 @@ bool AdbUtils::tryToStartApplication(const QString &deviceId, const QString &pac
|
||||
|
||||
bool AdbUtils::tryToKillApplication(const QString &deviceId, const QString &packageName) {
|
||||
QProcess process;
|
||||
process.start("adb", {
|
||||
process.start(adbPath(), {
|
||||
"-s", deviceId,
|
||||
"shell", "am",
|
||||
"force-stop", packageName
|
||||
@ -101,65 +125,73 @@ bool AdbUtils::tryToKillApplication(const QString &deviceId, const QString &pack
|
||||
|
||||
// idx - временный лог
|
||||
// adb -s 6edc4a47 shell 'uiautomator dump /sdcard/uidump.xml' && adb -s 6edc4a47 pull /sdcard/uidump.xml step_1.xml && adb -s 6edc4a47 shell 'rm /sdcard/uidump.xml'
|
||||
QString AdbUtils::getScreenDumpAsXml(const QString &deviceId, const int idx, const bool screenshot) {
|
||||
// TODO убрать логирование в xml файл
|
||||
// "adb -s %1 pull /sdcard/uidump.xml step_%2.xml && "
|
||||
QProcess process;
|
||||
QString xml;
|
||||
if (screenshot) {
|
||||
xml = QString(
|
||||
"adb -s %1 shell 'uiautomator dump /sdcard/uidump.xml' && "
|
||||
"adb -s %1 pull /sdcard/uidump.xml step_%2.xml && "
|
||||
"adb -s %1 shell 'cat /sdcard/uidump.xml' && "
|
||||
"adb -s %1 shell 'rm /sdcard/uidump.xml'"
|
||||
).arg(deviceId, QString::number(idx));
|
||||
} else {
|
||||
xml = QString(
|
||||
"adb -s %1 shell 'uiautomator dump /sdcard/uidump.xml' && "
|
||||
"adb -s %1 shell 'cat /sdcard/uidump.xml' && "
|
||||
"adb -s %1 shell 'rm /sdcard/uidump.xml'"
|
||||
).arg(deviceId);
|
||||
QString AdbUtils::getScreenDumpAsXml(const QString &deviceId, int idx, bool screenshot) {
|
||||
const QString adb = adbPath();
|
||||
QString output;
|
||||
|
||||
// 1. Dump UI hierarchy
|
||||
QString dumpCmd = QString("%1 -s %2 shell uiautomator dump /sdcard/uidump.xml").arg(adb, deviceId);
|
||||
if (!startProcess(dumpCmd)) {
|
||||
qWarning() << "Failed to dump UI hierarchy.";
|
||||
return {};
|
||||
}
|
||||
|
||||
process.start("sh", {"-c", xml});
|
||||
process.waitForFinished();
|
||||
|
||||
// 2. Optionally pull and save the XML file
|
||||
if (screenshot) {
|
||||
// TODO делаем скрин, убрать потом
|
||||
// adb -s 6edc4a47 shell 'screencap -p /sdcard/screen.png' && adb -s 6edc4a47 pull /sdcard/screen.png screen_step_1.png && adb -s 6edc4a47 shell 'rm /sdcard/screen.png'
|
||||
QProcess processScreenshot;
|
||||
QString screenshot = QString(
|
||||
"adb -s %1 shell 'screencap -p /sdcard/screen.png' && "
|
||||
"adb -s %1 pull /sdcard/screen.png screen_step_%2.png && "
|
||||
"adb -s %1 shell 'rm /sdcard/screen.png'"
|
||||
).arg(deviceId, QString::number(idx));
|
||||
processScreenshot.start("sh", {"-c", screenshot});
|
||||
processScreenshot.waitForFinished();
|
||||
QString pullCmd = QString("%1 -s %2 pull /sdcard/uidump.xml step_%3.xml").arg(adb, deviceId).arg(idx);
|
||||
if (!startProcess(pullCmd)) {
|
||||
qWarning() << "Failed to pull UIDump XML.";
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
// чтобы убедиться, что мы прочитали без ошибок
|
||||
if (process.exitStatus() != QProcess::NormalExit || process.exitCode() != 0) {
|
||||
// 3. Read the XML content
|
||||
QString catCmd = QString("%1 -s %2 shell cat /sdcard/uidump.xml").arg(adb, deviceId);
|
||||
QString xmlOut;
|
||||
if (!startProcess(catCmd, &xmlOut)) {
|
||||
qWarning() << "Failed to read UIDump XML.";
|
||||
return {};
|
||||
}
|
||||
|
||||
QByteArray xmlBytes = process.readAllStandardOutput();
|
||||
// UI hierchary dumped to: /sdcard/uidump.xml\n
|
||||
if (const int startIndex = xmlBytes.indexOf("<?xml"); startIndex != -1) {
|
||||
xmlBytes = xmlBytes.mid(startIndex); // Обрезаем всё до "<?xml"
|
||||
// 4. Remove temp XML file
|
||||
QString rmCmd = QString("%1 -s %2 shell rm /sdcard/uidump.xml").arg(adb, deviceId);
|
||||
startProcess(rmCmd); // неважно, успешна ли команда
|
||||
|
||||
// 5. Screenshot (if needed)
|
||||
if (screenshot) {
|
||||
QString shotCmds[] = {
|
||||
QString("%1 -s %2 shell screencap -p /sdcard/screen.png").arg(adb, deviceId),
|
||||
QString("%1 -s %2 pull /sdcard/screen.png screen_step_%3.png").arg(adb, deviceId).arg(idx),
|
||||
QString("%1 -s %2 shell rm /sdcard/screen.png").arg(adb, deviceId)
|
||||
};
|
||||
for (const QString &cmd : shotCmds) {
|
||||
startProcess(cmd); // ошибки игнорируем для скриншота
|
||||
}
|
||||
}
|
||||
|
||||
// 6. Обрезка к началу XML
|
||||
QByteArray xmlBytes = xmlOut.toUtf8();
|
||||
if (const int start = xmlBytes.indexOf("<?xml"); start != -1) {
|
||||
xmlBytes = xmlBytes.mid(start);
|
||||
}
|
||||
return QString::fromUtf8(xmlBytes);
|
||||
}
|
||||
|
||||
bool AdbUtils::takeScreenshot(const QString &deviceId, const QString &name) {
|
||||
QProcess process;
|
||||
QString screenshot = QString(
|
||||
"adb -s %1 shell 'screencap -p /sdcard/screen.png' && "
|
||||
"adb -s %1 pull /sdcard/screen.png %2.png && "
|
||||
"adb -s %1 shell 'rm /sdcard/screen.png'"
|
||||
).arg(deviceId, name);
|
||||
process.start("sh", {"-c", screenshot});
|
||||
process.waitForFinished();
|
||||
return process.exitStatus() == QProcess::NormalExit && process.exitCode() == 0;
|
||||
const QString adb = adbPath();
|
||||
QStringList commands = {
|
||||
QString("%1 -s %2 shell screencap -p /sdcard/screen.png").arg(adb, deviceId),
|
||||
QString("%1 -s %2 pull /sdcard/screen.png %3.png").arg(adb, deviceId, name),
|
||||
QString("%1 -s %2 shell rm /sdcard/screen.png").arg(adb, deviceId)
|
||||
};
|
||||
|
||||
for (const QString &cmd: commands) {
|
||||
QString stderr;
|
||||
if (!startProcess(cmd, nullptr, &stderr)) {
|
||||
qWarning() << "ADB command failed:" << cmd;
|
||||
qWarning() << "Error:" << stderr;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AdbUtils::takeXmlDump(const QString &deviceId, const QString &name) {
|
||||
@ -172,26 +204,19 @@ bool AdbUtils::takeXmlDump(const QString &deviceId, const QString &name) {
|
||||
};
|
||||
|
||||
for (const QString &cmd: commands) {
|
||||
QProcess process;
|
||||
#ifdef Q_OS_WIN
|
||||
process.start("cmd.exe", {"/C", cmd});
|
||||
#else
|
||||
process.start("sh", {"-c", cmd});
|
||||
#endif
|
||||
if (!process.waitForFinished() ||
|
||||
process.exitStatus() != QProcess::NormalExit ||
|
||||
process.exitCode() != 0) {
|
||||
QString stderr;
|
||||
if (!startProcess(cmd, nullptr, &stderr)) {
|
||||
qWarning() << "ADB command failed:" << cmd;
|
||||
qWarning() << "Error:" << stderr;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AdbUtils::makeTap(const QString &deviceId, const int x, const int y) {
|
||||
QProcess process;
|
||||
process.start("adb", {
|
||||
process.start(adbPath(), {
|
||||
"-s", deviceId,
|
||||
"shell", "input",
|
||||
"tap", QString::number(x), QString::number(y)
|
||||
@ -201,21 +226,28 @@ bool AdbUtils::makeTap(const QString &deviceId, const int x, const int y) {
|
||||
}
|
||||
|
||||
bool AdbUtils::enableAdbIMEKeyboard(const QString &deviceId) {
|
||||
QProcess process;
|
||||
QString command = QString(
|
||||
"adb -s %1 shell ime enable com.android.adbkeyboard/.AdbIME "
|
||||
"&& adb -s %1 shell ime set com.android.adbkeyboard/.AdbIME"
|
||||
).arg(deviceId);
|
||||
process.start(command);
|
||||
process.waitForFinished();
|
||||
return process.exitStatus() == QProcess::NormalExit && process.exitCode() == 0;
|
||||
const QString adb = adbPath();
|
||||
QStringList commands = {
|
||||
QString("%1 -s %2 shell ime enable com.android.adbkeyboard/.AdbIME").arg(adb, deviceId),
|
||||
QString("%1 -s %2 shell ime set com.android.adbkeyboard/.AdbIME").arg(adb, deviceId)
|
||||
};
|
||||
|
||||
for (const QString &cmd: commands) {
|
||||
QString stderr;
|
||||
if (!startProcess(cmd, nullptr, &stderr)) {
|
||||
qWarning() << "ADB command failed:" << cmd;
|
||||
qWarning() << "Error:" << stderr;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AdbUtils::inputAdbIMEText(const QString &deviceId, const QString &text) {
|
||||
QProcess process;
|
||||
QString command = QString(
|
||||
"adb -s %1 shell am broadcast -a ADB_INPUT_TEXT --es msg '%2'"
|
||||
).arg(deviceId, text);
|
||||
"%1 -s %2 shell am broadcast -a ADB_INPUT_TEXT --es msg '%3'"
|
||||
).arg(adbPath(), deviceId, text);
|
||||
process.start(command);
|
||||
process.waitForFinished();
|
||||
return process.exitStatus() == QProcess::NormalExit && process.exitCode() == 0;
|
||||
@ -224,8 +256,8 @@ bool AdbUtils::inputAdbIMEText(const QString &deviceId, const QString &text) {
|
||||
bool AdbUtils::disableAdbIMEKeyboard(const QString &deviceId) {
|
||||
QProcess process;
|
||||
QString command = QString(
|
||||
"adb -s %1 shell ime disable com.android.adbkeyboard/.AdbIME"
|
||||
).arg(deviceId);
|
||||
"%1 -s %2 shell ime disable com.android.adbkeyboard/.AdbIME"
|
||||
).arg(adbPath(), deviceId);
|
||||
process.start(command);
|
||||
process.waitForFinished();
|
||||
return process.exitStatus() == QProcess::NormalExit && process.exitCode() == 0;
|
||||
@ -234,7 +266,7 @@ bool AdbUtils::disableAdbIMEKeyboard(const QString &deviceId) {
|
||||
bool AdbUtils::makeSwipe(const QString &deviceId, const int x1, const int y1, const int x2, const int y2) {
|
||||
QProcess process;
|
||||
process.start(
|
||||
"adb",
|
||||
adbPath(),
|
||||
{
|
||||
"-s", deviceId,
|
||||
"shell", "input",
|
||||
@ -247,7 +279,7 @@ bool AdbUtils::makeSwipe(const QString &deviceId, const int x1, const int y1, co
|
||||
|
||||
bool AdbUtils::inputText(const QString &deviceId, const QString &text) {
|
||||
QProcess process;
|
||||
process.start("adb", {
|
||||
process.start(adbPath(), {
|
||||
"-s", deviceId,
|
||||
"shell", "input",
|
||||
"text", text
|
||||
@ -258,7 +290,7 @@ bool AdbUtils::inputText(const QString &deviceId, const QString &text) {
|
||||
|
||||
bool AdbUtils::goBack(const QString &deviceId) {
|
||||
QProcess process;
|
||||
process.start("adb", {
|
||||
process.start(adbPath(), {
|
||||
"-s", deviceId,
|
||||
"shell", "input",
|
||||
"keyevent", "4"
|
||||
@ -269,7 +301,7 @@ bool AdbUtils::goBack(const QString &deviceId) {
|
||||
|
||||
QSet<QString> AdbUtils::getListApps(const QString &deviceId) {
|
||||
QProcess process;
|
||||
process.start("adb", {
|
||||
process.start(adbPath(), {
|
||||
"-s", deviceId,
|
||||
"shell", "pm list",
|
||||
"packages", "-3"
|
||||
|
||||
@ -40,4 +40,7 @@ public:
|
||||
static bool goBack(const QString &deviceId);
|
||||
|
||||
static QSet<QString> getListApps(const QString &deviceId);
|
||||
|
||||
private:
|
||||
static bool startProcess(const QString &cmd, QString *stdOut, QString *stdErr);
|
||||
};
|
||||
|
||||
Binary file not shown.
8
main.cpp
8
main.cpp
@ -145,11 +145,9 @@ int main(int argc, char *argv[]) {
|
||||
// 79641815146 - Мама Альфа
|
||||
// 79199196105 - Папа рсхб
|
||||
|
||||
// startNetworkService(app);
|
||||
// startDeviceScreener(app);
|
||||
// startEventHandler(app);
|
||||
|
||||
AdbUtils::takeXmlDump("29301FDH20036X", "test");
|
||||
startNetworkService(app);
|
||||
startDeviceScreener(app);
|
||||
startEventHandler(app);
|
||||
|
||||
MainWindow window;
|
||||
window.show();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user