mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-13 11:00:50 +00:00
229 lines
7.1 KiB
Markdown
229 lines
7.1 KiB
Markdown
## OpenClaw Android App
|
|
|
|
Status: **extremely alpha**. The app is actively being rebuilt from the ground up.
|
|
|
|
### Rebuild Checklist
|
|
|
|
- [x] New 4-step onboarding flow
|
|
- [x] Connect tab with `Setup Code` + `Manual` modes
|
|
- [x] Encrypted persistence for gateway setup/auth state
|
|
- [x] Chat UI restyled
|
|
- [x] Settings UI restyled and de-duplicated (gateway controls moved to Connect)
|
|
- [x] QR code scanning in onboarding
|
|
- [x] Performance improvements
|
|
- [x] Streaming support in chat UI
|
|
- [x] Request camera/location and other permissions in onboarding/settings flow
|
|
- [x] Push notifications for gateway/chat status updates
|
|
- [x] Security hardening (biometric lock, token handling, safer defaults)
|
|
- [x] Voice tab full functionality
|
|
- [x] Screen tab full functionality
|
|
- [ ] Full end-to-end QA and release hardening
|
|
|
|
## Open in Android Studio
|
|
|
|
- Open the folder `apps/android`.
|
|
|
|
## Build / Run
|
|
|
|
```bash
|
|
cd apps/android
|
|
./gradlew :app:assembleDebug
|
|
./gradlew :app:installDebug
|
|
./gradlew :app:testDebugUnitTest
|
|
```
|
|
|
|
## Kotlin Lint + Format
|
|
|
|
```bash
|
|
pnpm android:lint
|
|
pnpm android:format
|
|
```
|
|
|
|
Android framework/resource lint (separate pass):
|
|
|
|
```bash
|
|
pnpm android:lint:android
|
|
```
|
|
|
|
Direct Gradle tasks:
|
|
|
|
```bash
|
|
cd apps/android
|
|
./gradlew :app:ktlintCheck :benchmark:ktlintCheck
|
|
./gradlew :app:ktlintFormat :benchmark:ktlintFormat
|
|
./gradlew :app:lintDebug
|
|
```
|
|
|
|
`gradlew` auto-detects the Android SDK at `~/Library/Android/sdk` (macOS default) if `ANDROID_SDK_ROOT` / `ANDROID_HOME` are unset.
|
|
|
|
## Macrobenchmark (Startup + Frame Timing)
|
|
|
|
```bash
|
|
cd apps/android
|
|
./gradlew :benchmark:connectedDebugAndroidTest
|
|
```
|
|
|
|
Reports are written under:
|
|
|
|
- `apps/android/benchmark/build/reports/androidTests/connected/`
|
|
|
|
## Perf CLI (low-noise)
|
|
|
|
Deterministic startup measurement + hotspot extraction with compact CLI output:
|
|
|
|
```bash
|
|
cd apps/android
|
|
./scripts/perf-startup-benchmark.sh
|
|
./scripts/perf-startup-hotspots.sh
|
|
```
|
|
|
|
Benchmark script behavior:
|
|
|
|
- Runs only `StartupMacrobenchmark#coldStartup` (10 iterations).
|
|
- Prints median/min/max/COV in one line.
|
|
- Writes timestamped snapshot JSON to `apps/android/benchmark/results/`.
|
|
- Auto-compares with previous local snapshot (or pass explicit baseline: `--baseline <old-benchmarkData.json>`).
|
|
|
|
Hotspot script behavior:
|
|
|
|
- Ensures debug app installed, captures startup `simpleperf` data for `.MainActivity`.
|
|
- Prints top DSOs, top symbols, and key app-path clues (Compose/MainActivity/WebView).
|
|
- Writes raw `perf.data` path for deeper follow-up if needed.
|
|
|
|
## Run on a Real Android Phone (USB)
|
|
|
|
1) On phone, enable **Developer options** + **USB debugging**.
|
|
2) Connect by USB and accept the debugging trust prompt on phone.
|
|
3) Verify ADB can see the device:
|
|
|
|
```bash
|
|
adb devices -l
|
|
```
|
|
|
|
4) Install + launch debug build:
|
|
|
|
```bash
|
|
pnpm android:install
|
|
pnpm android:run
|
|
```
|
|
|
|
If `adb devices -l` shows `unauthorized`, re-plug and accept the trust prompt again.
|
|
|
|
### USB-only gateway testing (no LAN dependency)
|
|
|
|
Use `adb reverse` so Android `localhost:18789` tunnels to your laptop `localhost:18789`.
|
|
|
|
Terminal A (gateway):
|
|
|
|
```bash
|
|
pnpm openclaw gateway --port 18789 --verbose
|
|
```
|
|
|
|
Terminal B (USB tunnel):
|
|
|
|
```bash
|
|
adb reverse tcp:18789 tcp:18789
|
|
```
|
|
|
|
Then in app **Connect → Manual**:
|
|
|
|
- Host: `127.0.0.1`
|
|
- Port: `18789`
|
|
- TLS: off
|
|
|
|
## Hot Reload / Fast Iteration
|
|
|
|
This app is native Kotlin + Jetpack Compose.
|
|
|
|
- For Compose UI edits: use Android Studio **Live Edit** on a debug build (works on physical devices; project `minSdk=31` already meets API requirement).
|
|
- For many non-structural code/resource changes: use Android Studio **Apply Changes**.
|
|
- For structural/native/manifest/Gradle changes: do full reinstall (`pnpm android:run`).
|
|
- Canvas web content already supports live reload when loaded from Gateway `__openclaw__/canvas/` (see `docs/platforms/android.md`).
|
|
|
|
## Connect / Pair
|
|
|
|
1) Start the gateway (on your main machine):
|
|
|
|
```bash
|
|
pnpm openclaw gateway --port 18789 --verbose
|
|
```
|
|
|
|
2) In the Android app:
|
|
|
|
- Open the **Connect** tab.
|
|
- Use **Setup Code** or **Manual** mode to connect.
|
|
|
|
3) Approve pairing (on the gateway machine):
|
|
|
|
```bash
|
|
openclaw devices list
|
|
openclaw devices approve <requestId>
|
|
```
|
|
|
|
More details: `docs/platforms/android.md`.
|
|
|
|
## Permissions
|
|
|
|
- Discovery:
|
|
- Android 13+ (`API 33+`): `NEARBY_WIFI_DEVICES`
|
|
- Android 12 and below: `ACCESS_FINE_LOCATION` (required for NSD scanning)
|
|
- Foreground service notification (Android 13+): `POST_NOTIFICATIONS`
|
|
- Camera:
|
|
- `CAMERA` for `camera.snap` and `camera.clip`
|
|
- `RECORD_AUDIO` for `camera.clip` when `includeAudio=true`
|
|
|
|
## Integration Capability Test (Preconditioned)
|
|
|
|
This suite assumes setup is already done manually. It does **not** install/run/pair automatically.
|
|
|
|
Pre-req checklist:
|
|
|
|
1) Gateway is running and reachable from the Android app.
|
|
2) Android app is connected to that gateway and `openclaw nodes status` shows it as paired + connected.
|
|
3) App stays unlocked and in foreground for the whole run.
|
|
4) Open the app **Screen** tab and keep it active during the run (canvas/A2UI commands require the canvas WebView attached there).
|
|
5) Grant runtime permissions for capabilities you expect to pass (camera/mic/location/notification listener/location, etc.).
|
|
6) No interactive system dialogs should be pending before test start.
|
|
7) Canvas host is enabled and reachable from the device (do not run gateway with `OPENCLAW_SKIP_CANVAS_HOST=1`; startup logs should include `canvas host mounted at .../__openclaw__/`).
|
|
8) Local operator test client pairing is approved. If first run fails with `pairing required`, approve latest pending device pairing request, then rerun:
|
|
9) For A2UI checks, keep the app on **Screen** tab; the node now auto-refreshes canvas capability once on first A2UI reachability failure (TTL-safe retry).
|
|
|
|
```bash
|
|
openclaw devices list
|
|
openclaw devices approve --latest
|
|
```
|
|
|
|
Run:
|
|
|
|
```bash
|
|
pnpm android:test:integration
|
|
```
|
|
|
|
Optional overrides:
|
|
|
|
- `OPENCLAW_ANDROID_GATEWAY_URL=ws://...` (default: from your local OpenClaw config)
|
|
- `OPENCLAW_ANDROID_GATEWAY_TOKEN=...`
|
|
- `OPENCLAW_ANDROID_GATEWAY_PASSWORD=...`
|
|
- `OPENCLAW_ANDROID_NODE_ID=...` or `OPENCLAW_ANDROID_NODE_NAME=...`
|
|
|
|
What it does:
|
|
|
|
- Reads `node.describe` command list from the selected Android node.
|
|
- Invokes advertised non-interactive commands.
|
|
- Skips `screen.record` in this suite (Android requires interactive per-invocation screen-capture consent).
|
|
- Asserts command contracts (success or expected deterministic error for safe-invalid calls like `sms.send` and `notifications.actions`).
|
|
|
|
Common failure quick-fixes:
|
|
|
|
- `pairing required` before tests start:
|
|
- approve pending device pairing (`openclaw devices approve --latest`) and rerun.
|
|
- `A2UI host not reachable` / `A2UI_HOST_NOT_CONFIGURED`:
|
|
- ensure gateway canvas host is running and reachable, keep the app on the **Screen** tab. The app will auto-refresh canvas capability once; if it still fails, reconnect app and rerun.
|
|
- `NODE_BACKGROUND_UNAVAILABLE: canvas unavailable`:
|
|
- app is not effectively ready for canvas commands; keep app foregrounded and **Screen** tab active.
|
|
|
|
## Contributions
|
|
|
|
This Android app is currently being rebuilt.
|
|
Maintainer: @obviyus. For issues/questions/contributions, please open an issue or reach out on Discord.
|