diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 65ce03a..3db25cf 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -11,8 +11,8 @@ android { applicationId = "cn.ilapage.goauto.agent" minSdk = 23 targetSdk = 34 - versionCode = 44 - versionName = "0.9.31" + versionCode = 45 + versionName = "0.9.32" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" diff --git a/android/app/src/main/java/cn/ilapage/goauto/agent/automation/PurchaseLiveAutomation.kt b/android/app/src/main/java/cn/ilapage/goauto/agent/automation/PurchaseLiveAutomation.kt index e457f2a..b09ab3e 100644 --- a/android/app/src/main/java/cn/ilapage/goauto/agent/automation/PurchaseLiveAutomation.kt +++ b/android/app/src/main/java/cn/ilapage/goauto/agent/automation/PurchaseLiveAutomation.kt @@ -112,6 +112,8 @@ class PurchaseLiveAutomation( var backedOutOfPayment = false var backedOutOfChooser = false var restoredFromWechat = false + var pddObservedAfterWechatRestore = false + var wechatRestorePendingSamples = 0 var consecutiveEmptySnapshots = 0 repeat(ORDER_RESULT_MAX_SAMPLES) { index -> val snapshot = driver.capture() @@ -130,12 +132,18 @@ class PurchaseLiveAutomation( return@repeat } if (snapshot.packageName == WECHAT_PACKAGE) { - if (restoredFromWechat || !driver.bringPddToForeground()) return null - restoredFromWechat = true - pause(500) + if (!restoredFromWechat) { + if (!driver.bringPddToForeground()) return null + restoredFromWechat = true + pause(500) + return@repeat + } + if (pddObservedAfterWechatRestore || ++wechatRestorePendingSamples >= ORDER_RESULT_WECHAT_RESTORE_MAX_SAMPLES) return null + pause(ORDER_RESULT_SAMPLE_INTERVAL_MS) return@repeat } if (snapshot.packageName != PDD_PACKAGE) return null + if (restoredFromWechat) pddObservedAfterWechatRestore = true val paymentVisible = isKnownPddPaymentActivity(snapshot) || currentLabels.any { label -> PAYMENT_MARKERS.any(label::contains) } val orderContextVisible = currentLabels.any { label -> ORDER_CONTEXT_MARKERS.any(label::contains) } @@ -383,6 +391,7 @@ class PurchaseLiveAutomation( val PDD_PAYMENT_ACTIVITIES = setOf("com.xunmeng.pinduoduo.app_pay.core.PayActivity") const val ORDER_RESULT_MAX_SAMPLES = 60 const val ORDER_RESULT_MAX_EMPTY_SAMPLES = 15 + const val ORDER_RESULT_WECHAT_RESTORE_MAX_SAMPLES = 15 const val ORDER_RESULT_SAMPLE_INTERVAL_MS = 200L } } diff --git a/android/app/src/test/java/cn/ilapage/goauto/agent/PurchaseLiveAutomationTest.kt b/android/app/src/test/java/cn/ilapage/goauto/agent/PurchaseLiveAutomationTest.kt index 52b6530..22fc3b3 100644 --- a/android/app/src/test/java/cn/ilapage/goauto/agent/PurchaseLiveAutomationTest.kt +++ b/android/app/src/test/java/cn/ilapage/goauto/agent/PurchaseLiveAutomationTest.kt @@ -138,6 +138,25 @@ class PurchaseLiveAutomationTest { assertFalse(driver.clicked.any { it.contains("微信") || it.contains("登录") || it.contains("支付") }) } + @Test + fun `delayed PDD activity after WeChat restore stays within bounded grace period`() { + val driver = LiveDriver( + postSubmitCaptureSequence = List(12) { "wechat-login" } + listOf("order"), + ) + val automation = PurchaseLiveAutomation(driver, pause = {}) + val address = automation.updateShippingAddress("_cg36") + automation.finalConfirmation(input().copy(addressSuffix = "_cg36"), address) + automation.submitOrderOnce() + + val order = automation.readOrderResult() + + assertEquals("PDD-202608210001", order?.orderNo) + assertEquals(1, driver.pddRestoreCount) + assertEquals(13, driver.postSubmitCaptureCount) + assertEquals(0, driver.postSubmitBackCount) + assertFalse(driver.clicked.any { it.contains("微信") || it.contains("登录") || it.contains("支付") }) + } + @Test fun `empty accessibility transitions wait for WeChat and verify delayed PDD foreground`() { val driver = LiveDriver(