# Android capabilities

The Android agent should expose **the same gateway capability names** as Linux wherever the gateway semantics are already good enough. The implementation behind those names is Android-native.

## Capability mapping

### `computer_control`

Meaning on Android: phone/device control.

Current implemented actions:

- `launch_app`: implemented; starts app by package name.
- `open_url`: implemented; opens URL via Android intent.
- `open_intent`: implemented for implicit Android intent bridge.
- `key_press`: implemented for Android global actions via AccessibilityService (`back`, `home`, `recents`, `notifications`, `quick_settings`, `power_dialog`).
- `tap`, `swipe`, `long_press`: implemented via AccessibilityService gesture dispatch.
- `type_text`: implemented via Accessibility node focused-text injection.
- `mouse_move`: implemented as Android no-op compatibility response; Android has no persistent cursor.
- `get_active_window`: still routed through `desktop_observe`.

Explicit limitations that remain honest:

- Arbitrary raw key injection like desktop Enter/volume semantics is not available through normal unprivileged Android app APIs.
- Anything requiring shell-level input injection or hidden APIs is intentionally not faked.

Keep the gateway name `computer_control` unless gateway-side UX later needs a friendly alias. Compatibility beats naming purity here.

### `desktop_observe`

Meaning on Android: screen/device observation.

Current implemented actions:

- `screen_info`: implemented; display metrics, density, orientation, interactive state.
- `active_window` / `get_active_window`: implemented via AccessibilityService when enabled.
- `clipboard_get`: implemented.
- `cursor_position` / `mouse_position`: implemented as compatibility shim; Android has touch focus, not a persistent cursor.
- `list_windows`: implemented as Android foreground-window model compatibility.
- `window_geometry`: implemented as screen geometry fallback.
- `screenshot` / `region_screenshot`: consent flow is wired, but bitmap capture/export is still incomplete until the MediaProjection virtual-display pipeline is finished.

### `audio_control`

Current implemented actions:

- `get_audio_status`: implemented; stream volume, ringer mode, speakerphone flag, mic mute flag.
- `list_audio_devices`: implemented via `AudioDeviceInfo`.
- `capture_input`: implemented via `AudioRecord`, returning WAV payload as base64 when microphone permission is granted.
- `play_audio`: still incomplete until download/cache + MediaPlayer/ExoPlayer backend exists.
- `capture_output`: explicitly unsupported; normal Android apps generally cannot capture arbitrary output audio.

### `camera_control`

Current implemented actions:

- `list_cameras`: implemented with Camera2 camera inventory and JPEG size hints.
- `get_camera_status`: implemented with backend/status metadata.
- `capture_frame`: implemented with Camera2 + `ImageReader`, returning base64 JPEG when camera permission is granted.
- `capture_video`: now has a defined honest stock-Android architecture: the gateway command must hand off to a visible foreground `VideoCaptureActivity` that shows preview/recording UI, records for a bounded duration, and hands the resulting file back to the foreground service for upload/response. This is intentionally *not* a hidden background recorder.
- `inject_video`: explicitly unsupported on normal Android; no fake parity.

### `browser_control`

Not first milestone. Basic browser launching/open URL belongs in `computer_control.open_url`. Full browser automation can be added later if there is a clean Android backend.

### `notification_access`

Android does not map notification reading cleanly onto an existing Linux desktop capability, so this should be treated as an Android-specific extension surfaced through capability metadata and/or a dedicated gateway action family if the gateway grows one.

Planned honest actions:

- `get_notification_status`: report whether `NotificationListenerService` is enabled.
- `list_notifications`: return active notifications with package name, app label, post time, title, text preview, conversation/channel hints, and whether a `PendingIntent` launch target exists.
- `open_notification`: where possible, trigger the associated `PendingIntent` or launch the source app/package.
- `dismiss_notification`: only where Android permits cancellation by a listener service.

Boundaries:

- Notification *contents* are permission-gated and user-visible in Android settings.
- Historic notifications are not guaranteed unless the app stores its own recent cache.
- Replying inline should be considered a later feature, because `RemoteInput` handling is app-specific and easy to fake badly.

### `file_transfer`

Android filesystem access also deserves explicit treatment instead of pretending parity with Linux `exec` or desktop shell semantics.

Planned honest actions:

- `list_roots`: describe app-private storage, cache, and any user-granted SAF tree roots.
- `list_directory`: enumerate files/directories within app-private paths or Storage Access Framework roots the user has explicitly granted.
- `stat_path`: metadata for a visible path handle.
- `download_file`: return file bytes/base64 for files inside allowed roots and within size limits.
- `upload_file`: write a provided base64 payload into an app-private directory or a previously user-authorized SAF tree.
- `delete_path`: optional, but only inside allowed roots and with extremely conservative semantics.

Boundaries:

- No pretending the app can browse arbitrary `/sdcard` or other packages’ sandboxes without SAF/user grant.
- Paths should likely be abstract handles (`app://cache/...`, `saf://tree/...`) rather than raw Unix paths, to keep protocol semantics honest.
- Large file transfer should support chunking or temporary-file staging instead of trying to inline everything forever.

### `exec`

Disabled by default. Android shell execution is SELinux/app-sandbox constrained and not Linux-equivalent. If enabled later, it must implement the same allow/deny/ask model as Linux and clearly report limitations.

## Permission model

Android requires explicit grants for the interesting bits:

- AccessibilityService for gestures, key actions, UI inspection.
- UsageStats or Accessibility for foreground app/activity.
- MediaProjection for screenshots/screen recording.
- Camera permission for capture.
- Microphone permission for input capture.
- Notification listener permission for notification bridge if enabled.
- Storage Access Framework tree permission for directory traversal outside app-private storage.

The app must surface these as setup/status checks, not pretend they are available.
