From 37dea33b063a913b270f2ea9a5daa8afd5279764 Mon Sep 17 00:00:00 2001 From: QiuSW <105186638@qq.com> Date: Tue, 1 Sep 2026 16:49:35 +0800 Subject: [PATCH] fix(android): lock horizontal spec swipes (#189) --- android/app/build.gradle.kts | 4 +-- .../automation/GoAutoAccessibilityService.kt | 26 +++++++++++++++++-- .../GoAutoAccessibilityServicePolicyTest.kt | 21 +++++++++++++++ 3 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 android/app/src/test/java/cn/ilapage/goauto/agent/automation/GoAutoAccessibilityServicePolicyTest.kt diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 4223099..3936af5 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 = 50 - versionName = "0.9.37" + versionCode = 51 + versionName = "0.9.38" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" diff --git a/android/app/src/main/java/cn/ilapage/goauto/agent/automation/GoAutoAccessibilityService.kt b/android/app/src/main/java/cn/ilapage/goauto/agent/automation/GoAutoAccessibilityService.kt index 2ab8cbf..714c328 100644 --- a/android/app/src/main/java/cn/ilapage/goauto/agent/automation/GoAutoAccessibilityService.kt +++ b/android/app/src/main/java/cn/ilapage/goauto/agent/automation/GoAutoAccessibilityService.kt @@ -438,8 +438,14 @@ class GoAutoAccessibilityService : AccessibilityService(), UiDriver, PddCollecto kotlin.math.abs(bounds.centerY() - anchor.bounds.centerY) <= 32 ) matches += node } - if (matches.size != 1) return swipe(SemanticTarget.SPEC_PANEL, direction) val horizontal = direction == SwipeDirection.LEFT || direction == SwipeDirection.RIGHT + if (matches.size != 1) { + if (!SpecSwipeSafety.allowGlobalFallback(direction)) { + Log.i("GoAutoCollector", "swipe direction=$direction result=blocked reason=anchor-not-unique matches=${matches.size}") + return false + } + return swipe(SemanticTarget.SPEC_PANEL, direction) + } val scrollableAncestors = mutableListOf() var current: AccessibilityNodeInfo? = matches.single() while (current != null) { @@ -458,7 +464,15 @@ class GoAutoAccessibilityService : AccessibilityService(), UiDriver, PddCollecto if (anchoredTarget != null) { val bounds = Rect().also(anchoredTarget::getBoundsInScreen) Log.i("GoAutoCollector", "swipe direction=$direction anchored=true bounds=$bounds class=${anchoredTarget.className}") - return swipeNode(anchoredTarget, direction) + return swipeNode( + anchoredTarget, + direction, + preferScrollAction = SpecSwipeSafety.preferAccessibilityScrollAction(direction), + ) + } + if (!SpecSwipeSafety.allowGlobalFallback(direction)) { + Log.i("GoAutoCollector", "swipe direction=$direction result=blocked reason=no-anchored-horizontal-container") + return false } return swipe(SemanticTarget.SPEC_PANEL, direction) } @@ -643,3 +657,11 @@ class GoAutoAccessibilityService : AccessibilityService(), UiDriver, PddCollecto private set } } + +internal object SpecSwipeSafety { + fun allowGlobalFallback(direction: SwipeDirection): Boolean = + direction == SwipeDirection.UP || direction == SwipeDirection.DOWN + + fun preferAccessibilityScrollAction(direction: SwipeDirection): Boolean = + direction == SwipeDirection.UP || direction == SwipeDirection.DOWN +} diff --git a/android/app/src/test/java/cn/ilapage/goauto/agent/automation/GoAutoAccessibilityServicePolicyTest.kt b/android/app/src/test/java/cn/ilapage/goauto/agent/automation/GoAutoAccessibilityServicePolicyTest.kt new file mode 100644 index 0000000..4cd5610 --- /dev/null +++ b/android/app/src/test/java/cn/ilapage/goauto/agent/automation/GoAutoAccessibilityServicePolicyTest.kt @@ -0,0 +1,21 @@ +package cn.ilapage.goauto.agent.automation + +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Test + +class GoAutoAccessibilityServicePolicyTest { + @Test + fun horizontalSpecSwipeNeverFallsBackToAnotherPageContainer() { + assertFalse(SpecSwipeSafety.allowGlobalFallback(SwipeDirection.LEFT)) + assertFalse(SpecSwipeSafety.allowGlobalFallback(SwipeDirection.RIGHT)) + } + + @Test + fun horizontalSpecSwipeUsesGestureInsteadOfAccessibilityScrollAction() { + assertFalse(SpecSwipeSafety.preferAccessibilityScrollAction(SwipeDirection.LEFT)) + assertFalse(SpecSwipeSafety.preferAccessibilityScrollAction(SwipeDirection.RIGHT)) + assertTrue(SpecSwipeSafety.preferAccessibilityScrollAction(SwipeDirection.UP)) + assertTrue(SpecSwipeSafety.preferAccessibilityScrollAction(SwipeDirection.DOWN)) + } +}