docs: update android smoke test runbook

This commit is contained in:
funman300
2026-06-08 19:11:02 -07:00
parent 159774f811
commit df4887fb36
3 changed files with 53 additions and 28 deletions
+2
View File
@@ -10,6 +10,8 @@ project follows [Semantic Versioning](https://semver.org/).
- **Analytics validation runbook.** Documented native Matomo live validation, - **Analytics validation runbook.** Documented native Matomo live validation,
expected event payloads, and the current web/WASM analytics split. expected event payloads, and the current web/WASM analytics split.
- **Android smoke-test runbook.** Updated the Android doc with the current
platform status and a physical-device launch/touch/safe-area checklist.
- **Browser Bevy canvas route and automation support.** Added the `solitaire_web` - **Browser Bevy canvas route and automation support.** Added the `solitaire_web`
Bevy WASM build, wired `/play` to the Bevy canvas, added a Bevy WASM build, wired `/play` to the Bevy canvas, added a
`window.__FERROUS_DEBUG__` bridge, and introduced Playwright coverage for the `window.__FERROUS_DEBUG__` bridge, and introduced Playwright coverage for the
+3 -10
View File
@@ -104,16 +104,9 @@ Three bugs fixed:
### 1. Android APK launch verification (Option A) ### 1. Android APK launch verification (Option A)
Physical device test: install the latest APK on a real Android device (not AVD), Physical device test: install the latest APK on a real Android device (not AVD),
confirm: and run the checklist in `docs/ANDROID.md`. This has never been gated in CI.
- App launches without crash AVD `adb shell input tap` doesn't deliver real touch events, so physical-device
- Safe area insets arrive and shift HUD correctly after ~3 frames smoke testing is the only gate.
- All modal Done buttons are above the gesture bar
- Drag-and-drop works on all pile types
- Leaderboard panel opens and the "Public name" label updates correctly after
using "Set Name"
This has never been gated in CI. AVD `adb shell input tap` doesn't deliver real
touch events, so physical-device smoke testing is the only gate.
### 2. Matomo analytics live validation ### 2. Matomo analytics live validation
+48 -18
View File
@@ -5,10 +5,10 @@ Android target. Steps are runnable on a fresh Debian 13 (trixie) box;
later sections document what's known to compile, what's stubbed, and later sections document what's known to compile, what's stubbed, and
the next milestones. the next milestones.
> **Status (2026-05-07):** First working APK at `fb8b2ac`. 54 MB > **Status (2026-06-09):** Android build plumbing, app-directory storage,
> debug-signed `ferrous-solitaire.apk` for `x86_64-linux-android`. Has > JNI keystore wiring, and safe-area layout fixes have landed. The remaining
> NOT yet been verified to launch on a device or emulator — that's > release gate is a physical-device smoke test; AVD tap injection does not
> the next milestone. > exercise the real touch path reliably enough for launch verification.
--- ---
@@ -163,8 +163,8 @@ accepted workaround.
Physical device: Physical device:
```bash ```bash
adb devices # confirm connection adb devices # confirm connection
adb install target/debug/apk/ferrous-solitaire.apk adb install -r target/debug/apk/ferrous-solitaire.apk
adb shell am start -n com.ferrousapp.solitaire/android.app.NativeActivity adb shell am start -n com.ferrousapp.solitaire/android.app.NativeActivity
adb logcat | grep -iE "RustStdoutStderr|solitaire|panic" adb logcat | grep -iE "RustStdoutStderr|solitaire|panic"
``` ```
@@ -185,35 +185,65 @@ AVD.
--- ---
## 4. What's wired vs. what's stubbed ## 4. Physical-device smoke test
The first build pass (commit `fb8b2ac`) gates four desktop-only Run this on a real phone, preferably a modern 64-bit ARM device with gesture
crates / call sites so the workspace cross-compiles. Each gate is navigation enabled.
documented at its call site.
Build and install:
```bash
cargo apk build -p solitaire_app --target aarch64-linux-android --lib
adb install -r target/debug/apk/ferrous-solitaire.apk
adb logcat -c
adb shell am start -n com.ferrousapp.solitaire/android.app.NativeActivity
adb logcat | grep -iE "RustStdoutStderr|solitaire|panic|WindowInsets"
```
Pass criteria:
- App launches without panic or ANR.
- Safe-area insets arrive after the first few frames and shift HUD/modal
content away from the status and gesture bars.
- Every modal's Done button remains above the gesture bar:
Settings, Help, Pause, Win Summary, and Leaderboard-related dialogs.
- Drag-and-drop works on tableau, waste, foundation, and stock/recycle paths.
- Tap-to-select and one-tap modes both respond correctly on card stacks.
- Leaderboard panel opens, "Set Name" saves, and the "Public name" label updates
while the panel remains open.
- Rotate the device once, then repeat one modal and one drag operation.
- Close and relaunch the app; settings/progress still load.
Record the device model, Android version, APK commit, and pass/fail notes in the
release notes or session handoff. If a failure occurs, keep the filtered logcat
and note the exact screen/control path that reproduced it.
---
## 5. What's wired vs. what's stubbed
Desktop-only crates and call sites are gated so the workspace cross-compiles.
Each gate is documented at its call site.
| Surface | Desktop | Android | | Surface | Desktop | Android |
|---------|---------|---------| |---------|---------|---------|
| Bevy windowing | x11 + wayland | `android-native-activity` (NativeActivity glue) | | Bevy windowing | x11 + wayland | `android-native-activity` (NativeActivity glue) |
| Clipboard ("Copy share link") | `arboard` writes URL | Toast surfaces the URL inline | | Clipboard ("Copy share link") | `arboard` writes URL | Toast surfaces the URL inline |
| OS keychain (JWT tokens) | `keyring` v4 → Secret Service / Keychain / Credential Store | Stub returning `KeychainUnavailable`; sync requires fresh login each launch | | OS keychain (JWT tokens) | `keyring` v4 → Secret Service / Keychain / Credential Store | Android Keystore via JNI |
| Data directory | Platform data dir | Android app files dir |
| App entry point | `bin` target → `solitaire_app::run()` | `cdylib` target loaded by NativeActivity | | App entry point | `bin` target → `solitaire_app::run()` | `cdylib` target loaded by NativeActivity |
What's NOT yet ported / not yet measured: What's not yet ported / not yet measured:
- `dirs::data_dir()` returns `None` on Android. Callers in
`solitaire_data/src/storage.rs`, `progress.rs`, `replay.rs`,
`achievements.rs`, `settings.rs` all need an Android-aware
helper (likely `/data/data/com.ferrousapp.solitaire/files`).
- Touch UX pass — hit-target sizes, modal scaling on small screens, - Touch UX pass — hit-target sizes, modal scaling on small screens,
app lifecycle (suspend / resume), font scaling. app lifecycle (suspend / resume), font scaling.
- Android Keystore via JNI for `auth_tokens`.
- JNI ClipboardManager for share links. - JNI ClipboardManager for share links.
- Google Play Games sign-in (the `solitaire_gpgs` crate referenced - Google Play Games sign-in (the `solitaire_gpgs` crate referenced
in older docs doesn't yet exist). in older docs doesn't yet exist).
--- ---
## 5. Iteration loop ## 6. Iteration loop
```bash ```bash
# Edit code… # Edit code…