From 644e7642eeb6c91656ffe1e648baf1acff609760 Mon Sep 17 00:00:00 2001 From: QiuSW <105186638@qq.com> Date: Fri, 11 Sep 2026 11:44:40 +0800 Subject: [PATCH] fix(android): settle before spec gesture retry (#268) --- .../automation/PurchaseRehearsalExecutor.kt | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/android/app/src/main/java/cn/ilapage/goauto/agent/automation/PurchaseRehearsalExecutor.kt b/android/app/src/main/java/cn/ilapage/goauto/agent/automation/PurchaseRehearsalExecutor.kt index 96518fc..5715381 100644 --- a/android/app/src/main/java/cn/ilapage/goauto/agent/automation/PurchaseRehearsalExecutor.kt +++ b/android/app/src/main/java/cn/ilapage/goauto/agent/automation/PurchaseRehearsalExecutor.kt @@ -459,6 +459,31 @@ class PurchaseRehearsalExecutor( gestureBaseline = retryScreen } + // Give PDD's bottom-sheet re-render a short settle window after an + // accessibility click that produced no observable transition, then + // reacquire the target before the single controlled gesture retry. + if (!wait.changed) { + pause(SPEC_ENTRY_GESTURE_RETRY_SETTLE_MILLIS) + val refreshed = currentScreen(input) + if (!refreshed.isPddPackage || !refreshed.pageEvidenceMatched || refreshed.specPanelOpen) { + return failure(SPEC_PANEL_EVIDENCE_NOT_MATCHED, "规格入口点击后页面已变化,但规格面板强证据不足 [${panelEvidence(refreshed)}]") + } + val refreshedCandidates = listOfNotNull( + refreshed.specEntry?.let { anchor -> anchor to (refreshed.specEntryClickTarget ?: anchor) }, + refreshed.quickConfirmationEntry?.let { it to it }, + ).distinctBy { it.second.path } + .let { candidatesToFilter -> + action.textAliases?.let { aliases -> + candidatesToFilter.filter { (anchor, _) -> specEntryMatchesAliases(refreshed, anchor, aliases) } + } ?: candidatesToFilter + } + if (refreshedCandidates.size != 1) { + return failure(SPEC_ENTRY_CLICK_FAILED, "gesture_failed_after_action_click_no_effect") + } + target = refreshedCandidates.single().second + gestureBaseline = refreshed + } + when (driver.tapSpecFresh(requireNotNull(target))) { FreshActionResult.AMBIGUOUS -> return failure( SPEC_ENTRY_TARGET_AMBIGUOUS, @@ -1234,6 +1259,7 @@ class PurchaseRehearsalExecutor( private const val OPEN_PRODUCT_POLL_MILLIS = 100L private const val SPEC_ENTRY_READY_WAIT_POLLS = 20 private const val SPEC_ENTRY_STABLE_READS = 2 + private const val SPEC_ENTRY_GESTURE_RETRY_SETTLE_MILLIS = 500L private const val SPEC_ENTRY_READY_POLL_MILLIS = 100L private const val SPEC_POST_CLICK_VERIFY_POLLS = 50 private const val SPEC_SELECTION_SUCCESS_VERIFY_POLLS = 20