Add retry limits for "Подтверждаю" and "Оплатить" taps in PayByPhoneScript and PayByCardScript to prevent infinite loops and improve error handling with detailed logs.
This commit is contained in:
parent
feb839daf2
commit
14e46cac84
@ -413,7 +413,16 @@ void PayByCardScript::makePayment(
|
||||
// 10. Ждём результат — "Платеж выполнен" или ошибку.
|
||||
// Промежуточный статус "Выполняется" может висеть до ~1.5 мин, пока банк
|
||||
// подтверждает перевод, поэтому общий таймаут — 60 итераций × 2 сек = 2 мин.
|
||||
// Лимиты повторных тапов: если первый тап "Подтверждаю" не сработал,
|
||||
// bottom sheet дисмиссится, виден "Оплатить" → перетапываем; следующий
|
||||
// sheet → пробуем другую Y. Без лимита получали бесконечный
|
||||
// "Оплатить ↔ Подтверждаю" со случайными попаданиями в системные экраны
|
||||
// (security/launcher).
|
||||
bool success = earlySuccess;
|
||||
int confirmRetries = 0;
|
||||
int oplatitRetries = 0;
|
||||
const int maxConfirmRetries = 2;
|
||||
const int maxOplatitRetries = 2;
|
||||
for (int attempt = 0; !earlySuccess && attempt < 60; ++attempt) {
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||
closeGooglePlayBannerIfVisible(deviceId, width, height);
|
||||
@ -458,14 +467,29 @@ void PayByCardScript::makePayment(
|
||||
QString::fromUtf8("Подтверждение платежа"), true);
|
||||
if (!retryConfirm.isEmpty() &&
|
||||
retryConfirm.contentDesc.contains(QString::fromUtf8("Подтверждаю"))) {
|
||||
qDebug() << "[Dushanbe::PayByCard] Confirm sheet still visible, re-tapping 'Подтверждаю'";
|
||||
if (confirmRetries >= maxConfirmRetries) {
|
||||
m_error = "Confirm tap missed " + QString::number(confirmRetries)
|
||||
+ " times (sheet still visible)";
|
||||
qWarning() << "[Dushanbe::PayByCard]" << m_error;
|
||||
AppLogger::log("dushanbe/PayByCard", deviceId, m_error,
|
||||
AdbUtils::captureScreenshotBytes(deviceId), "CREATE_TRANSACTION");
|
||||
return;
|
||||
}
|
||||
++confirmRetries;
|
||||
qDebug() << "[Dushanbe::PayByCard] Confirm sheet still visible, re-tap"
|
||||
<< confirmRetries << "/" << maxConfirmRetries;
|
||||
const QByteArray screen = AdbUtils::captureScreenshotBytes(deviceId);
|
||||
QPoint tap = OcrUtils::findTextCenter(screen,
|
||||
QString::fromUtf8("Подтверждаю"),
|
||||
retryConfirm.y1(), retryConfirm.y2());
|
||||
if (tap.x() < 0) {
|
||||
const int tapY = retryConfirm.y2() - qMax(150, height / 14);
|
||||
// Варьируем Y: первый retry — выше fallback на 100px,
|
||||
// второй — ещё на 100px выше. Compose-кнопка действия
|
||||
// обычно на y2 - 150..350; перебираем диапазон.
|
||||
const int extra = 100 * confirmRetries;
|
||||
const int tapY = retryConfirm.y2() - qMax(150 + extra, height / 14 + extra);
|
||||
tap = QPoint(retryConfirm.x(), tapY);
|
||||
qDebug() << "[Dushanbe::PayByCard] OCR miss, fallback tap at" << tap;
|
||||
}
|
||||
AdbUtils::makeTap(deviceId, tap.x(), tap.y());
|
||||
QThread::msleep(4000);
|
||||
@ -482,7 +506,17 @@ void PayByCardScript::makePayment(
|
||||
retryOplatit = xmlScreenParser.findButtonNode(QString::fromUtf8("Оплатить"), false);
|
||||
}
|
||||
if (!retryOplatit.isEmpty() && retryOplatit.clickable) {
|
||||
qDebug() << "[Dushanbe::PayByCard] Sheet dismissed, re-tapping 'Оплатить' to restart confirm flow";
|
||||
if (oplatitRetries >= maxOplatitRetries) {
|
||||
m_error = "Sheet dismissed and re-tap exhausted ("
|
||||
+ QString::number(oplatitRetries) + " retries)";
|
||||
qWarning() << "[Dushanbe::PayByCard]" << m_error;
|
||||
AppLogger::log("dushanbe/PayByCard", deviceId, m_error,
|
||||
AdbUtils::captureScreenshotBytes(deviceId), "CREATE_TRANSACTION");
|
||||
return;
|
||||
}
|
||||
++oplatitRetries;
|
||||
qDebug() << "[Dushanbe::PayByCard] Sheet dismissed, re-tap 'Оплатить'"
|
||||
<< oplatitRetries << "/" << maxOplatitRetries;
|
||||
AdbUtils::makeTap(deviceId, retryOplatit.x(), retryOplatit.y());
|
||||
QThread::msleep(3000);
|
||||
continue;
|
||||
|
||||
@ -409,7 +409,16 @@ void PayByPhoneScript::makePayment(
|
||||
// 10. Ждём результат — "Платеж выполнен" или ошибку.
|
||||
// Промежуточный статус "Выполняется" может висеть до ~1.5 мин, пока банк
|
||||
// подтверждает перевод, поэтому общий таймаут — 60 итераций × 2 сек = 2 мин.
|
||||
// Лимиты повторных тапов: если первый тап "Подтверждаю" не сработал,
|
||||
// bottom sheet дисмиссится, виден "Оплатить" → перетапываем; следующий
|
||||
// sheet → пробуем другую Y. Без лимита получали бесконечный
|
||||
// "Оплатить ↔ Подтверждаю" со случайными попаданиями в системные экраны
|
||||
// (security/launcher).
|
||||
bool success = earlySuccess;
|
||||
int confirmRetries = 0;
|
||||
int oplatitRetries = 0;
|
||||
const int maxConfirmRetries = 2;
|
||||
const int maxOplatitRetries = 2;
|
||||
for (int attempt = 0; !earlySuccess && attempt < 60; ++attempt) {
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||
closeGooglePlayBannerIfVisible(deviceId, width, height);
|
||||
@ -450,14 +459,29 @@ void PayByPhoneScript::makePayment(
|
||||
QString::fromUtf8("Подтверждение платежа"), true);
|
||||
if (!retryConfirm.isEmpty() &&
|
||||
retryConfirm.contentDesc.contains(QString::fromUtf8("Подтверждаю"))) {
|
||||
qDebug() << "[Dushanbe::PayByPhone] Confirm sheet still visible, re-tapping 'Подтверждаю'";
|
||||
if (confirmRetries >= maxConfirmRetries) {
|
||||
m_error = "Confirm tap missed " + QString::number(confirmRetries)
|
||||
+ " times (sheet still visible)";
|
||||
qWarning() << "[Dushanbe::PayByPhone]" << m_error;
|
||||
AppLogger::log("dushanbe/PayByPhone", deviceId, m_error,
|
||||
AdbUtils::captureScreenshotBytes(deviceId), "CREATE_TRANSACTION");
|
||||
return;
|
||||
}
|
||||
++confirmRetries;
|
||||
qDebug() << "[Dushanbe::PayByPhone] Confirm sheet still visible, re-tap"
|
||||
<< confirmRetries << "/" << maxConfirmRetries;
|
||||
const QByteArray screen = AdbUtils::captureScreenshotBytes(deviceId);
|
||||
QPoint tap = OcrUtils::findTextCenter(screen,
|
||||
QString::fromUtf8("Подтверждаю"),
|
||||
retryConfirm.y1(), retryConfirm.y2());
|
||||
if (tap.x() < 0) {
|
||||
const int tapY = retryConfirm.y2() - qMax(150, height / 14);
|
||||
// Варьируем Y: первый retry — выше fallback на 100px,
|
||||
// второй — ещё на 100px выше. Compose-кнопка действия
|
||||
// обычно на y2 - 150..350; перебираем диапазон.
|
||||
const int extra = 100 * confirmRetries;
|
||||
const int tapY = retryConfirm.y2() - qMax(150 + extra, height / 14 + extra);
|
||||
tap = QPoint(retryConfirm.x(), tapY);
|
||||
qDebug() << "[Dushanbe::PayByPhone] OCR miss, fallback tap at" << tap;
|
||||
}
|
||||
AdbUtils::makeTap(deviceId, tap.x(), tap.y());
|
||||
QThread::msleep(4000);
|
||||
@ -474,7 +498,17 @@ void PayByPhoneScript::makePayment(
|
||||
retryOplatit = xmlScreenParser.findButtonNode(QString::fromUtf8("Оплатить"), false);
|
||||
}
|
||||
if (!retryOplatit.isEmpty() && retryOplatit.clickable) {
|
||||
qDebug() << "[Dushanbe::PayByPhone] Sheet dismissed, re-tapping 'Оплатить' to restart confirm flow";
|
||||
if (oplatitRetries >= maxOplatitRetries) {
|
||||
m_error = "Sheet dismissed and re-tap exhausted ("
|
||||
+ QString::number(oplatitRetries) + " retries)";
|
||||
qWarning() << "[Dushanbe::PayByPhone]" << m_error;
|
||||
AppLogger::log("dushanbe/PayByPhone", deviceId, m_error,
|
||||
AdbUtils::captureScreenshotBytes(deviceId), "CREATE_TRANSACTION");
|
||||
return;
|
||||
}
|
||||
++oplatitRetries;
|
||||
qDebug() << "[Dushanbe::PayByPhone] Sheet dismissed, re-tap 'Оплатить'"
|
||||
<< oplatitRetries << "/" << maxOplatitRetries;
|
||||
AdbUtils::makeTap(deviceId, retryOplatit.x(), retryOplatit.y());
|
||||
QThread::msleep(3000);
|
||||
continue;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user