fix(patrol): make Android UiAutomation accessibility flags configurable - #3216
Draft
Kendru98 wants to merge 1 commit into
Draft
fix(patrol): make Android UiAutomation accessibility flags configurable#3216Kendru98 wants to merge 1 commit into
Kendru98 wants to merge 1 commit into
Conversation
Kendru98
requested review from
PiotrRogulski,
jBorkowska,
pdenert,
piotruela and
zoskar
as code owners
August 5, 2026 10:13
Kendru98
force-pushed
the
claude/patrol-flag-defaults-025ec4
branch
from
August 5, 2026 10:13
abcff08 to
945539c
Compare
Both flags are opt-in and default to today's behavior. #3201: Patrol acquired UiAutomation with flags=0, so the platform suppressed every third-party AccessibilityService for the whole session. Add AndroidAutomatorConfig.dontSuppressAccessibilityServices (dart-define PATROL_ANDROID_DONT_SUPPRESS_ACCESSIBILITY_SERVICES); when set, Patrol acquires it with FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES via Configurator so other services keep running. #3178: uiautomator 2.3.0's UiDevice.getUiAutomation() force-enables FLAG_RETRIEVE_INTERACTIVE_WINDOWS, which stops some WebViews (e.g. Plaid Link) from ever populating their accessibility tree, breaking $.native selectors. Add AndroidAutomatorConfig.retrieveInteractiveWindows (dart-define PATROL_ANDROID_RETRIEVE_INTERACTIVE_WINDOWS); set it to false to clear the flag. uiautomator re-adds it whenever serviceInfo.flags != mCachedServiceFlags or every SERVICE_FLAGS_TIMEOUT (2s), so the private mCachedServiceFlags / mLastServiceFlagsTime cache is pinned via reflection; FLAG_INCLUDE_NOT_IMPORTANT_VIEWS is preserved so normal selectors keep working. Flags flow from AndroidAutomatorConfig through the ConfigureRequest contract to Automator.configure() on Android; iOS ignores them.
Kendru98
force-pushed
the
claude/patrol-flag-defaults-025ec4
branch
from
August 5, 2026 10:15
945539c to
a072a2e
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
Adds configurable Android UiAutomation accessibility flags, addressing third-party accessibility-service suppression and WebView selector failures.
Changes:
- Adds Android configuration fields and Dart defines.
- Threads flags through cross-platform contracts.
- Applies and pins native Android accessibility flags.
Reviewed changes
Copilot reviewed 14 out of 16 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
schema.dart |
Extends the configure contract. |
packages/patrol/test/android_automator_config_test.dart |
Tests defaults and request forwarding. |
packages/patrol/lib/src/platform/platform_automator.dart |
Exposes platform-level options. |
packages/patrol/lib/src/platform/mobile/mobile_automator_native.dart |
Adds extensible configure requests. |
packages/patrol/lib/src/platform/contracts/contracts.g.dart |
Serializes new fields. |
packages/patrol/lib/src/platform/contracts/contracts.dart |
Defines new contract fields. |
packages/patrol/lib/src/platform/android/android_automator_native.dart |
Forwards Android configuration. |
packages/patrol/lib/src/platform/android/android_automator_config.dart |
Defines flags and Dart defaults. |
packages/patrol/darwin/patrol/Sources/PatrolImpl/AutomatorServer/Contracts.swift |
Keeps Darwin contract compatible. |
packages/patrol/CHANGELOG.md |
Documents the options. |
packages/patrol/android/src/main/kotlin/pl/leancode/patrol/contracts/Contracts.kt |
Extends Android contracts. |
packages/patrol/android/src/main/kotlin/pl/leancode/patrol/AutomatorServer.kt |
Passes flags to the automator. |
packages/patrol/android/src/main/kotlin/pl/leancode/patrol/Automator.kt |
Applies Android accessibility flags. |
packages/patrol_devtools_extension/lib/api/contracts.g.dart |
Updates DevTools serialization. |
packages/patrol_devtools_extension/lib/api/contracts.dart |
Updates DevTools contracts. |
Files not reviewed (2)
- packages/patrol/lib/src/platform/contracts/contracts.g.dart: Generated file
- packages/patrol_devtools_extension/lib/api/contracts.g.dart: Generated file
Suppressed comments (1)
packages/patrol/android/src/main/kotlin/pl/leancode/patrol/Automator.kt:128
- This option is also one-way: once a test sets it to
false,clearRetrieveInteractiveWindowsFlag()removes the bit and pinsmLastServiceFlagsTimetoLong.MAX_VALUE; a later test requestingtrueskips this block, so uiautomator never restores its default flag. Handle thetruetransition by restoring the service flag and unpinning/synchronizing the UiDevice cache.
if (!retrieveInteractiveWindows) {
clearRetrieveInteractiveWindowsFlag()
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // UiDevice.getUiAutomation() forwards Configurator.uiAutomationFlags to | ||
| // Instrumentation.getUiAutomation(flags), so setting it here is enough for | ||
| // uiautomator's own queries. | ||
| configurator.uiAutomationFlags = UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES |
Comment on lines
+121
to
+123
| if (dontSuppressAccessibilityServices) { | ||
| configureDontSuppressAccessibilityServices() | ||
| } |
Kendru98
marked this pull request as draft
August 5, 2026 10:58
jBorkowska
reviewed
Aug 5, 2026
| // Instrumentation.getUiAutomation(flags) exists only on API 24+. Below that, | ||
| // the flags-based opt-ins are unavailable and Configurator.uiAutomationFlags | ||
| // stays at its default (0), so the no-arg overload is equivalent. | ||
| private fun uiAutomationForConfiguredFlags(): UiAutomation { |
Collaborator
There was a problem hiding this comment.
Is this method used anywhere else than in the method above? Seems redundant
| keyboardBehavior = keyboardBehavior ?? KeyboardBehavior.showAndDismiss, | ||
| dontSuppressAccessibilityServices = | ||
| dontSuppressAccessibilityServices ?? | ||
| const bool.fromEnvironment( |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Make two Android
UiAutomationaccessibility flags configurable. Both opt-in, default = today's behavior.Problem
UiAutomationwithflags=0, so the platform suppresses every third-partyAccessibilityServicefor the whole session.FLAG_RETRIEVE_INTERACTIVE_WINDOWS, which stops some WebViews (e.g. Plaid Link) from populating their a11y tree, breaking$.nativeselectors.Change
AndroidAutomatorConfig.dontSuppressAccessibilityServices(dart-definePATROL_ANDROID_DONT_SUPPRESS_ACCESSIBILITY_SERVICES) → setsFLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICESviaConfigurator.AndroidAutomatorConfig.retrieveInteractiveWindows(dart-definePATROL_ANDROID_RETRIEVE_INTERACTIVE_WINDOWS) →falseclears the flag.ConfigureRequestcontract →Automator.configure(); iOS ignores them.Watch out
serviceInfo.flags != mCachedServiceFlagsor everySERVICE_FLAGS_TIMEOUT(2s), so a plainsetServiceInfo()won't stick —mCachedServiceFlags/mLastServiceFlagsTimeare pinned via reflection (guarded, degrades to default on failure).FLAG_INCLUDE_NOT_IMPORTANT_VIEWSis preserved so normal selectors keep working.Result
ConfigureRequestthreading).Closes #3201
Closes #3178