Files
openclaw/apps/android/app/src/thirdParty/AndroidManifest.xml
Peter Steinberger 12df806e90 feat(android): AccessibilityService UI executor (thirdParty, PR 1/3) (#112232)
* feat(android): AccessibilityService UI executor (thirdParty, PR 1/3)

Add a thirdParty-flavor-only AccessibilityService that observes the active
app's UI as a bounded semantic snapshot and performs typed actions, exercised
via a local developer screen. No gateway/agent wiring yet (PR 2 adds
node.invoke commands, PR 3 the agent tool + policy gates).

- Play APK stays accessibility-free: service, config, executor, and UI live
  entirely under src/thirdParty; SensitiveFeatureConfig.accessibilityControlEnabled
  gates it. Verified: 0 accessibility refs in every merged Play manifest and
  0 accessibility classes in the Play dex.
- Semantic-first executor: observe() returns a bounded snapshot (node/depth/text
  caps, deterministic order, password + sensitive-field redaction, stable action
  vocabulary, generation-scoped refs); act() performs one typed action with a
  closed ActionOutcomeCode result set.
- Safety model: coordinate gestures gated by package-match (fail-closed) + a UI
  epoch advanced on window/content/scroll/text mutation events; node actions
  gated by package-match + per-node refresh(); global actions ungated. Capture
  runs off the main thread. Dev UI honestly disables cross-app node controls
  (only reachable while the target is foreground; validated via the remote path).

Built and emulator-tested on API 36: live connection status, immediate observe,
a 103-node cross-app Settings capture, and global Home. Both flavors assemble;
thirdParty unit tests, ktlint, and android lint pass.

* feat(android): gate accessibility control behind an off-by-default opt-in

Make landing the accessibility feature a no-op for existing thirdParty users:
the service is invisible and inert until the user explicitly opts in.

- The AccessibilityService and its dev activity are declared
  android:enabled="false", so a fresh install exposes NO new accessibility
  service in system settings and nothing can bind it (verified on device:
  absent from the installed-services list and unbindable; shell cannot enable
  it either — only the app can).
- New thirdParty-only "Control other apps" toggle (persisted in the existing
  openclaw.node prefs, default OFF). Turning it on enables both components via
  PackageManager.setComponentEnabledSetting and deep-links to Accessibility
  settings so the user can grant it; turning it off disables them again
  (DONT_KILL_APP). A disclosure describes what enabling does.
- Play flavor is a no-op (FlavorPhoneCapabilitiesSettings = Unit); no
  accessibility component/controller/toggle references reach the Play APK.
- No new permissions or dependencies. The compile-time flavor gate and the
  gateway dangerous-command arming remain as additional layers.

* chore(android): update native i18n baseline for accessibility control strings
2026-07-22 00:36:13 -07:00

42 lines
1.9 KiB
XML

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" />
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-feature
android:name="android.hardware.telephony"
android:required="false" />
<application>
<service
android:name=".accessibility.OpenClawAccessibilityService"
android:enabled="false"
android:exported="true"
android:label="@string/accessibility_service_label"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
tools:ignore="ExportedService">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/accessibility_service_config" />
</service>
<activity
android:name=".accessibility.AccessibilityDevActivity"
android:enabled="false"
android:excludeFromRecents="true"
android:exported="true"
android:label="@string/accessibility_dev_activity_label"
tools:ignore="ExportedActivity" />
</application>
</manifest>