1
0
forked from BRT/arc

Add closeGooglePlayBannerIfVisible to handle Google Play update banners across scripts:

- Integrate banner dismissal in retry loops for XML parsing in payment and profile scripts.
- Add detection logic for permission deny buttons and update banner handling in `ScreenXmlParser`.
- Ensure reliable operation during input field detection, transactions fetching, and confirmation screens.
This commit is contained in:
slava 2026-04-24 16:39:38 +07:00
parent d480cc51b0
commit f200eae2bd
15 changed files with 134 additions and 0 deletions

View File

@ -295,4 +295,26 @@ void CommonScript::stop() {
m_running = false;
}
bool CommonScript::closeGooglePlayBannerIfVisible(
const QString &deviceId, const int width, const int height
) {
// 1. Системный диалог запроса разрешения Android (permissioncontroller) — тапаем "ЗАПРЕТИТЬ"
if (Node denyBtn = xmlScreenParser.tryToFindSystemPermissionDenyButton(); !denyBtn.isEmpty()) {
qDebug() << "[Dushanbe] System permission dialog detected mid-task, tapping 'ЗАПРЕТИТЬ'...";
AdbUtils::makeTap(deviceId, denyBtn.x(), denyBtn.y());
QThread::msleep(1500);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
return true;
}
// 2. Google Play in-app update bottom sheet
Node gpNode = xmlScreenParser.tryToFindGooglePlayBanner(width, height);
if (gpNode.isEmpty()) return false;
qDebug() << "[Dushanbe] Google Play update banner detected mid-task, closing...";
AdbUtils::makeTap(deviceId, gpNode.x(), gpNode.y());
QThread::msleep(1500);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
return true;
}
} // namespace Dushanbe

View File

@ -47,6 +47,12 @@ protected:
void createBankProfileIfNeeded(const QString &deviceId, const QString &appCode, double parsedBalance = -1.0);
// Если виден баннер Google Play "Доступно обновление" — закрывает его и перепарсивает XML.
// Безопасно вызывать на любом экране; возвращает true если баннер был закрыт.
bool closeGooglePlayBannerIfVisible(
const QString &deviceId, int width, int height
);
bool m_running = true;
ScreenXmlParser xmlScreenParser;
int m_counter = 0;

View File

@ -288,6 +288,7 @@ void GetLastTransactionsScript::doStart() {
bool historyLoaded = false;
for (int attempt = 0; attempt < 10; ++attempt) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(m_deviceId, device.screenWidth, device.screenHeight);
// Проверяем диалог "Ошибка" — нажимаем "ОК" и обновляем свайпом вниз
if (!xmlScreenParser.findNodeByContentDesc(QString::fromUtf8("Ошибка")).isEmpty()) {
@ -390,6 +391,7 @@ void GetLastTransactionsScript::doStart() {
return;
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(m_deviceId, device.screenWidth, device.screenHeight);
// Верх нижнего меню: минимальный y1() среди табов и FAB "Сканировать".
// Тап по строке с y >= navTopY - navMargin промахивается и попадает в FAB/таб.
@ -632,6 +634,7 @@ void GetLastTransactionsScript::doStart() {
for (int attempt = 0; attempt < 10; ++attempt) {
if (interrupted()) { m_error = "Interrupted"; emit finishedWithResult(m_error); return; }
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(m_deviceId, device.screenWidth, device.screenHeight);
for (const Node &n : xmlScreenParser.findAllNodes()) {
if (!n.contentDesc.contains(QString::fromUtf8("Успешный платеж"))) continue;
if (!n.contentDesc.contains(QString::fromUtf8("Дата:"))) continue;

View File

@ -82,6 +82,7 @@ void GetProfileInfoScript::doStart() {
bool sideMenuFound = false;
for (int attempt = 0; attempt < 5; ++attempt) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(m_deviceId, device.screenWidth, device.screenHeight);
if (xmlScreenParser.isSideMenu()) {
sideMenuFound = true;
break;

View File

@ -166,6 +166,7 @@ void PayByCardScript::makePayment(
Node cardTransferBtn;
for (int attempt = 0; attempt < 10; ++attempt) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(deviceId, width, height);
cardTransferBtn = xmlScreenParser.findNodeByContentDesc(
QString::fromUtf8("DC (по номеру карты)"), true);
if (!cardTransferBtn.isEmpty()) {
@ -193,6 +194,7 @@ void PayByCardScript::makePayment(
bool inputScreenLoaded = false;
for (int attempt = 0; attempt < 10; ++attempt) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(deviceId, width, height);
Node editText = xmlScreenParser.findEditTextByHint(
QString::fromUtf8("Номер карты получателя"));
if (editText.isEmpty()) {
@ -233,6 +235,7 @@ void PayByCardScript::makePayment(
Node sumEditText;
for (int attempt = 0; attempt < 10; ++attempt) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(deviceId, width, height);
sumEditText = xmlScreenParser.findEditTextByHint(QString::fromUtf8("Сумма"));
if (!sumEditText.isEmpty()) break;
qDebug() << "[Dushanbe::PayByCard] Waiting for sum input, attempt" << attempt + 1 << "/ 10";
@ -301,6 +304,7 @@ void PayByCardScript::makePayment(
bool oplatitFound = false;
for (int attempt = 0; attempt < 10; ++attempt) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(deviceId, width, height);
Node oplatitBtn = xmlScreenParser.findNodeByContentDesc(QString::fromUtf8("Оплатить"));
if (oplatitBtn.isEmpty()) {
oplatitBtn = xmlScreenParser.findButtonNode(QString::fromUtf8("Оплатить"), false);
@ -330,6 +334,7 @@ void PayByCardScript::makePayment(
bool confirmed = false;
for (int attempt = 0; attempt < 10; ++attempt) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(deviceId, width, height);
// Пин-код может появиться
if (xmlScreenParser.isPinCodeScreen()) {
@ -370,6 +375,7 @@ void PayByCardScript::makePayment(
bool success = false;
for (int attempt = 0; attempt < 15; ++attempt) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(deviceId, width, height);
// Пин-код
if (xmlScreenParser.isPinCodeScreen()) {

View File

@ -163,6 +163,7 @@ void PayByPhoneScript::makePayment(
Node phoneTransferBtn;
for (int attempt = 0; attempt < 10; ++attempt) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(deviceId, width, height);
phoneTransferBtn = xmlScreenParser.findNodeByContentDesc(
QString::fromUtf8("DC (по номеру телефона)"), true);
if (!phoneTransferBtn.isEmpty()) {
@ -190,6 +191,7 @@ void PayByPhoneScript::makePayment(
bool inputScreenLoaded = false;
for (int attempt = 0; attempt < 10; ++attempt) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(deviceId, width, height);
Node editText = xmlScreenParser.findEditTextByHint(
QString::fromUtf8("Номер телефона получателя"));
if (editText.isEmpty()) {
@ -234,6 +236,7 @@ void PayByPhoneScript::makePayment(
Node sumEditText;
for (int attempt = 0; attempt < 10; ++attempt) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(deviceId, width, height);
sumEditText = xmlScreenParser.findEditTextByHint(QString::fromUtf8("Сумма"));
if (!sumEditText.isEmpty()) break;
qDebug() << "[Dushanbe::PayByPhone] Waiting for sum input, attempt" << attempt + 1 << "/ 10";
@ -301,6 +304,7 @@ void PayByPhoneScript::makePayment(
bool oplatitFound = false;
for (int attempt = 0; attempt < 10; ++attempt) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(deviceId, width, height);
Node oplatitBtn = xmlScreenParser.findNodeByContentDesc(QString::fromUtf8("Оплатить"));
if (oplatitBtn.isEmpty()) {
oplatitBtn = xmlScreenParser.findButtonNode(QString::fromUtf8("Оплатить"), false);
@ -328,6 +332,7 @@ void PayByPhoneScript::makePayment(
bool confirmed = false;
for (int attempt = 0; attempt < 10; ++attempt) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(deviceId, width, height);
if (xmlScreenParser.isPinCodeScreen()) {
qDebug() << "[Dushanbe::PayByPhone] PIN code screen, entering PIN...";
@ -365,6 +370,7 @@ void PayByPhoneScript::makePayment(
bool success = false;
for (int attempt = 0; attempt < 15; ++attempt) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(deviceId, width, height);
if (xmlScreenParser.isPinCodeScreen()) {
qDebug() << "[Dushanbe::PayByPhone] PIN code screen (retry), entering PIN...";

View File

@ -497,4 +497,37 @@ Node ScreenXmlParser::findEditTextByHint(const QString &hint) {
return {};
}
Node ScreenXmlParser::tryToFindSystemPermissionDenyButton() {
for (const Node &node : m_nodes) {
if (node.resourceId == "com.android.permissioncontroller:id/permission_deny_button"
&& node.clickable) {
return node;
}
}
for (const Node &node : m_nodes) {
if (node.clickable && node.text.trimmed() == QString::fromUtf8("ЗАПРЕТИТЬ")) {
return node;
}
}
return {};
}
Node ScreenXmlParser::tryToFindGooglePlayBanner(const int screenWidth, const int screenHeight) {
for (const Node &node : m_nodes) {
if (node.contentDesc.contains("Закрыть диалоговое окно") && node.clickable) {
return node;
}
}
for (const Node &node : m_nodes) {
if (node.contentDesc.contains("Доступно обновление")) {
Node tapNode;
const int cx = screenWidth / 2;
const int cy = screenHeight / 20;
tapNode.setBounds(cx, cy, cx + 1, cy + 1);
return tapNode;
}
}
return {};
}
} // namespace Dushanbe

View File

@ -115,6 +115,14 @@ public:
// Находит EditText по hint
Node findEditTextByHint(const QString &hint);
// Находит кнопку закрытия Google Play in-app update bottom sheet
// ("com.android.vending" оверлей "Доступно обновление"), если он показан
Node tryToFindGooglePlayBanner(int screenWidth, int screenHeight);
// Находит кнопку "ЗАПРЕТИТЬ" в системном диалоге запроса разрешения Android
// (com.google.android.permissioncontroller). Возвращает пустой Node если диалог не виден.
Node tryToFindSystemPermissionDenyButton();
private:
QList<Node> m_nodes;
QDomElement m_xml;

View File

@ -227,6 +227,16 @@ bool CommonScript::tryToCloseAllBannersOnHomePage(const QString &deviceId, const
bool CommonScript::closeGooglePlayBannerIfVisible(
const QString &deviceId, const int width, const int height
) {
// 1. Системный диалог запроса разрешения Android (permissioncontroller) — тапаем "ЗАПРЕТИТЬ"
if (Node denyBtn = xmlScreenParser.tryToFindSystemPermissionDenyButton(); !denyBtn.isEmpty()) {
qDebug() << "[Ozon] System permission dialog detected mid-task, tapping 'ЗАПРЕТИТЬ'...";
AdbUtils::makeTap(deviceId, denyBtn.x(), denyBtn.y());
QThread::msleep(1500);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
return true;
}
// 2. Google Play in-app update bottom sheet
Node gpNode = xmlScreenParser.tryToFindGooglePlayBanner(width, height);
if (gpNode.isEmpty()) return false;
qDebug() << "[Ozon] Google Play update banner detected mid-task, closing...";

View File

@ -206,6 +206,7 @@ bool GetLastTransactionsScript::navigateToTransactionList(const DeviceInfo &devi
AdbUtils::makeSwipe(m_deviceId, x, device.screenHeight - 200, x, 200, 100);
QThread::msleep(1500);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(m_deviceId, device.screenWidth, device.screenHeight);
allBtn = xmlScreenParser.findButtonNode("Все", false);
if (!allBtn.isEmpty() && allBtn.y() > 0 && allBtn.y() < navBarTop) break;
@ -569,6 +570,7 @@ void GetLastTransactionsScript::searchTransaction(const DeviceInfo &device, int
for (int da = 0; da < 5; ++da) {
if (QThread::currentThread()->isInterruptionRequested()) break;
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(m_deviceId, device.screenWidth, device.screenHeight);
if (!xmlScreenParser.findNodeByContentDesc("Поделиться").isEmpty()) {
docLoaded = true;
break;
@ -750,6 +752,7 @@ void GetLastTransactionsScript::scanRecentTransactions(const DeviceInfo &device,
AdbUtils::makeSwipe(m_deviceId, x, device.screenHeight - offset, x, offset);
QThread::msleep(1000);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(m_deviceId, device.screenWidth, device.screenHeight);
txButtons = xmlScreenParser.findTransactionButtons(8);
if (i < txButtons.size() && txButtons[i].y() > 0 && txButtons[i].y() < navBarTop) break;
}
@ -788,6 +791,7 @@ void GetLastTransactionsScript::scanRecentTransactions(const DeviceInfo &device,
bool docLoaded = false;
for (int da = 0; da < 15; ++da) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(m_deviceId, device.screenWidth, device.screenHeight);
if (!xmlScreenParser.findNodeByContentDesc("Поделиться").isEmpty()) {
docLoaded = true;
break;
@ -860,6 +864,7 @@ void GetLastTransactionsScript::scanRecentTransactions(const DeviceInfo &device,
bool docLoaded = false;
for (int da = 0; da < 20; ++da) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(m_deviceId, device.screenWidth, device.screenHeight);
if (!xmlScreenParser.findNodeByContentDesc("Поделиться").isEmpty()) {
docLoaded = true; break;
}

View File

@ -108,6 +108,7 @@ void GetProfileInfoScript::doStart() {
// Читаем XML профиля и проверяем что мы действительно там
for (int attempt = 0; attempt < 5; ++attempt) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(m_deviceId, device.screenWidth, device.screenHeight);
if (xmlScreenParser.isProfileScreen()) {
break;
}

View File

@ -176,6 +176,7 @@ void PayByCardScript::makePayment(
for (int attempt = 0; attempt < 10; ++attempt) {
if (!checkApp()) return;
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(deviceId, width, height);
Node title = xmlScreenParser.findTextNode("Платежи и переводы");
if (!title.isEmpty()) titleSeen = true;
cardBtn = xmlScreenParser.findButtonNode("По номеру карты", false);
@ -205,6 +206,7 @@ void PayByCardScript::makePayment(
for (int attempt = 0; attempt < 10; ++attempt) {
if (!checkApp()) return;
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(deviceId, width, height);
Node title = xmlScreenParser.findTextNode("Перевод по номеру карты");
if (!title.isEmpty()) {
cardScreenLoaded = true;
@ -231,6 +233,7 @@ void PayByCardScript::makePayment(
qDebug() << "[PayByCard] Waiting for 'Номер карты получателя' input, attempt" << attempt + 1 << "/ 10";
QThread::msleep(1500);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(deviceId, width, height);
}
if (cardInput.isEmpty()) {
@ -249,6 +252,7 @@ void PayByCardScript::makePayment(
for (int attempt = 0; attempt < 10; ++attempt) {
if (!checkApp()) return;
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(deviceId, width, height);
sumInput = xmlScreenParser.findEditTextByHint("Сумма от");
if (!sumInput.isEmpty()) break;
qDebug() << "[PayByCard] Waiting for 'Сумма от' input, attempt" << attempt + 1 << "/ 10";
@ -274,6 +278,7 @@ void PayByCardScript::makePayment(
for (int attempt = 0; attempt < 15; ++attempt) {
if (!checkApp()) return;
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(deviceId, width, height);
bool foundKomissiya = false;
for (const Node &node : xmlScreenParser.findAllNodes()) {
@ -332,6 +337,7 @@ void PayByCardScript::makePayment(
for (int attempt = 0; attempt < 15; ++attempt) {
if (!checkApp()) return;
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(deviceId, width, height);
// Если PIN-код появился позже — вводим
if (const QList<Node> pinNodes = xmlScreenParser.tryToFindPinCode(pinCode, "Введите ПИН");

View File

@ -176,6 +176,7 @@ void PayByPhoneScript::makePayment(
for (int attempt = 0; attempt < 10; ++attempt) {
if (!checkApp()) return;
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(deviceId, width, height);
Node phoneField = xmlScreenParser.findFirstEditText();
if (!phoneField.isEmpty()) {
paymentsPageLoaded = true;
@ -202,6 +203,7 @@ void PayByPhoneScript::makePayment(
for (int attempt = 0; attempt < 10; ++attempt) {
if (!checkApp()) return;
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(deviceId, width, height);
// Закрываем диалог "Разрешить доступ к контактам"
Node notNowBtn = xmlScreenParser.findButtonNode("Не сейчас", false);
@ -232,6 +234,7 @@ void PayByPhoneScript::makePayment(
for (int attempt = 0; attempt < 10; ++attempt) {
if (!checkApp()) return;
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(deviceId, width, height);
phoneInput = xmlScreenParser.findFirstEditText();
if (!phoneInput.isEmpty()) break;
qDebug() << "[PayByPhone] Waiting for phone input field, attempt" << attempt + 1 << "/ 10";
@ -255,6 +258,7 @@ void PayByPhoneScript::makePayment(
for (int attempt = 0; attempt < 20; ++attempt) {
if (!checkApp()) return;
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(deviceId, width, height);
// Проверяем: уже на экране суммы?
Node sumTitle = xmlScreenParser.findTextNode("По номеру телефона");
@ -375,6 +379,7 @@ void PayByPhoneScript::makePayment(
qDebug() << "[PayByPhone] Waiting for sum input field, attempt" << attempt + 1 << "/ 10";
QThread::msleep(1500);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(deviceId, width, height);
}
if (sumInput.isEmpty()) {
m_error = "Поле ввода суммы не найдено";
@ -404,6 +409,7 @@ void PayByPhoneScript::makePayment(
for (int attempt = 0; attempt < 10; ++attempt) {
if (!checkApp()) return;
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(deviceId, width, height);
Node confirmTitle = xmlScreenParser.findTextNode("Подтвердите перевод");
if (!confirmTitle.isEmpty()) {
confirmScreenLoaded = true;
@ -428,6 +434,7 @@ void PayByPhoneScript::makePayment(
qDebug() << "[PayByPhone] Waiting for 'Перевести ...' button, attempt" << attempt + 1 << "/ 10";
QThread::msleep(1500);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(deviceId, width, height);
}
if (transferConfirmBtn.isEmpty()) {
m_error = "Кнопка 'Перевести ...' не найдена на экране подтверждения";
@ -452,6 +459,7 @@ void PayByPhoneScript::makePayment(
for (int attempt = 0; attempt < 15; ++attempt) {
if (!checkApp()) return;
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
closeGooglePlayBannerIfVisible(deviceId, width, height);
// Если PIN-код появился позже — вводим
if (const QList<Node> pinNodes = xmlScreenParser.tryToFindPinCode(pinCode, "Введите ПИН");

View File

@ -222,6 +222,21 @@ Node ScreenXmlParser::tryToFindAdBanner() {
return {};
}
Node ScreenXmlParser::tryToFindSystemPermissionDenyButton() {
for (const Node &node : m_nodes) {
if (node.resourceId == "com.android.permissioncontroller:id/permission_deny_button"
&& node.clickable) {
return node;
}
}
for (const Node &node : m_nodes) {
if (node.clickable && node.text.trimmed() == QString::fromUtf8("ЗАПРЕТИТЬ")) {
return node;
}
}
return {};
}
Node ScreenXmlParser::tryToFindGooglePlayBanner(const int screenWidth, const int screenHeight) {
// Баннер Google Play "Доступно обновление" — ищем кнопку закрытия по content-desc
for (const Node &node : m_nodes) {

View File

@ -44,6 +44,10 @@ public:
Node tryToFindGooglePlayBanner(int screenWidth, int screenHeight);
// Находит кнопку "ЗАПРЕТИТЬ" в системном диалоге запроса разрешения Android
// (com.google.android.permissioncontroller). Возвращает пустой Node если диалог не виден.
Node tryToFindSystemPermissionDenyButton();
// Returns a Button node whose text is exactly 4 digits (card last numbers)
Node findCardButtonOnHomeScreen();