docs(p0): SysRS/SysDes/SRS/SAD/SDD/Verification + traceability for Android P0 reconciliation
Full P0 Android documentation chain: - SysRS: API 24 → API 28 reconciliation per DEC-004 (SysRS-288); add SysRS-305 (Android in-call audio mode), SysRS-306 (RECORD_AUDIO runtime timing). - SysDes: SysDes-152 (in-call audio mode subsystem), SysDes-153 (RECORD_AUDIO permission flow), SysDes-154 (Android voice audio backend), SysDes-155 (macOS runtime baseline). - SRS: SRS-187 → API 28; add SRS-208 (in-call audio mode), SRS-209 (RECORD_AUDIO + listen-only fallback), SRS-210..215 (Android voice audio backend latency/preset/AEC/usage/sharing/foreground service); retarget SysDes anchors from generic SysDes-135 to SysDes-152/153/154. - SAD: SAD-063 refreshed (API 28); add SAD-084 (audio mode controller), SAD-085 (permission adapter with listen-only), SAD-086 (foreground service), SAD-087 (macOS runtime baseline); formalize cross-cutting + platform-specific allocation pattern in §24.1. - SDD: expand SDD-028 (BackIntentService); refresh SDD-073 (build config); add SDD-105 (JNI bootstrap), SDD-106 (permission requester), SDD-107 (foreground service), SDD-108 (audio mode controller), SDD-109 (AAB pipeline), SDD-110 (PTT capability), SDD-111..116 (Android voice audio backend), SDD-118 (Android bridge build automation), SDD-119 (iOS/macOS bridge build automation back-fill). - Verification: create android-p0-acceptance.md TC-1..TC-18; add SWE4-UV-040..052, SWE5-IV-016..026, SWE6-SV-018..030, SYS4-SIV-015 strengthened + SYS4-SIV-017/018. - Governance: traceability matrix v0.9.9 with end-to-end chain closure; DEC-032 documents the temporary abiFilters reduction to arm64-v8a only and its restore-by gate. Trace: full chain SysRS → SysDes → SRS → SAD → SDD → Code → Verification.
This commit is contained in:
@@ -245,3 +245,133 @@ Software integration verification results shall be summarized in an integration
|
||||
| Version | Date | Description |
|
||||
|---|---|---|
|
||||
| 0.9.3 | 2026-05-15 | Added desktop PTT software-integration verification item SWE5-IV-015 covering the integrated audio engine + Rust core PTT controller + bridge + Flutter UI + diagnostics path on Windows, macOS, and GNOME-on-Wayland Linux reference hosts. |
|
||||
|
||||
|
||||
## 9. Android P0 Software Integration Verification Addendum
|
||||
|
||||
**SWE5-IV-016**: Verify Android JNI bootstrap → foreground service lifecycle integration.
|
||||
|
||||
- Source SAD: SAD-077, SAD-081
|
||||
- Source SDD: SDD-105, SDD-107
|
||||
- Verification method: Instrumented integration test on a physical API 28 device
|
||||
- Pass criteria: `Application.onCreate` loads `libchanora_bridge.so`, `JNI_OnLoad` captures the `JavaVM`, the bridge is initialized, and `AndroidVoiceForegroundService` can be started by the Rust core (via JNI callback) without re-loading the library or racing init. Service start completes before the first audio frame is produced.
|
||||
- Evidence: Integration test result + logcat trace
|
||||
|
||||
**SWE5-IV-017**: Verify permission denial → foreground service not started → listen-only stream open integration.
|
||||
|
||||
- Source SAD: SAD-077
|
||||
- Source SDD: SDD-106, SDD-107
|
||||
- Source SRS: SRS-209
|
||||
- Verification method: Integration test using permission-state test double + real audio stack
|
||||
- Pass criteria: When `RECORD_AUDIO` is denied (or revoked mid-session) the FGS is NOT started for capture; the playback stream remains open so the user hears other participants (listen-only fallback per SRS-209); UI surfaces the degraded state; re-granting permission re-enables capture without process restart.
|
||||
- Evidence: Integration test result
|
||||
|
||||
**SWE5-IV-018**: Verify foreground service start triggers audio mode acquisition; service stop triggers mode restore.
|
||||
|
||||
- Source SAD: SAD-081, SAD-085
|
||||
- Source SDD: SDD-107, SDD-108
|
||||
- Source SRS: SRS-208
|
||||
- Source SysRS: SysRS-305
|
||||
- Verification method: Integration test on a physical device with `dumpsys audio` snapshots before / during / after
|
||||
- Pass criteria: Before voice channel join, `AudioManager.mode` is the device baseline. After FGS start and join, mode is `MODE_IN_COMMUNICATION`. After leave/disconnect, FGS stops and the controller restores the snapshotted prior mode. Refcount holds across rapid join/leave/join cycles.
|
||||
- Evidence: Integration test result + `dumpsys audio` traces
|
||||
|
||||
**SWE5-IV-019**: Verify `BackIntentService` integration with the Flutter Navigator route stack.
|
||||
|
||||
- Source SAD: SAD-018
|
||||
- Source SDD: SDD-028 (expanded)
|
||||
- Source SRS: SRS-163
|
||||
- Verification method: Flutter integration test on Android with a non-trivial route stack (home → channel → settings → modal)
|
||||
- Pass criteria: System back closes modal first (does not pop the route); subsequent back pops one route per press; at the home route system back backgrounds the activity. PTT-active-ignore: while the test driver asserts `transmit_active`, back is consumed. API 33+ and pre-33 code paths both produce identical end states (verified on at least one device per branch).
|
||||
- Evidence: Integration test result
|
||||
|
||||
**SWE5-IV-020**: Verify AAB build pipeline integration (`SDD-109`).
|
||||
|
||||
- Source SAD: SAD-063
|
||||
- Source SDD: SDD-073, SDD-109
|
||||
- Source SRS: SRS-119, SRS-188
|
||||
- Verification method: CI build job + `bundletool` validation
|
||||
- Pass criteria: `flutter build appbundle --release` produces an AAB; `bundletool validate` reports no errors; `bundletool build-apks --connected-device` produces per-ABI splits for `{arm64-v8a, armeabi-v7a, x86_64}`; signing key fingerprint matches the CI release-key reference; `targetSdkVersion` matches the SRS-188 declared target; `minSdkVersion` == 28 (DEC-004); manifest contains `FOREGROUND_SERVICE` + `FOREGROUND_SERVICE_MICROPHONE` (API 34+) + `RECORD_AUDIO` permissions and no others outside the allow-list.
|
||||
- Evidence: CI artifact + bundletool report
|
||||
|
||||
| Architecture / Design Area | SWE.5 Coverage |
|
||||
|---|---|
|
||||
| SAD-018, SAD-063, SAD-077, SAD-081, SAD-084, SAD-085, SAD-086 | SWE5-IV-016 through SWE5-IV-020 |
|
||||
| SDD-028 (expanded), SDD-073 (refreshed), SDD-105, SDD-106, SDD-107, SDD-108, SDD-109, SDD-110 | SWE5-IV-016 through SWE5-IV-020 |
|
||||
|
||||
|
||||
### Android voice audio backend integration items (SDD-111..SDD-116 wave)
|
||||
|
||||
**SWE5-IV-021**: Verify `MobileVoiceAudioBackend` trait + audio engine integration on voice_join / voice_leave.
|
||||
|
||||
- Source SAD: SAD-077, SAD-081
|
||||
- Source SDD: SDD-111 (trait surface), SDD-112 (config), SDD-115 (lifecycle)
|
||||
- Source SRS: SRS-210, SRS-211, SRS-213, SRS-214
|
||||
- Verification method: Rust integration test on a physical Android device (API 31 mid-tier minimum) driving the engine through `voice_join` / `voice_leave` against the real `AndroidVoiceUnit`
|
||||
- Pass criteria: `voice_join` constructs `AndroidVoiceStreamConfig` from engine state, calls `AndroidVoiceUnit::open(...)`, opens BOTH input and output streams (verified by `session_id()` being `Some(_)` and the output-stream handle being non-null), then calls `start()`. Engine state transitions are observed in order: `Idle → Opening → Running`. `voice_leave` calls `stop()` then `close()` in that order; engine state returns to `Idle`. No stream is left open after `voice_leave` (verified by a follow-up `voice_join` succeeding with a fresh session id).
|
||||
- Evidence: Integration test result + logcat with engine state transition lines
|
||||
- SDD-116 matrix rows satisfied: all (open/close path exercised on every matrix device)
|
||||
|
||||
**SWE5-IV-022**: Verify SDD-108 audio-mode engagement precedes SDD-113 effect binding (forward) and effects release precedes mode restore (reverse).
|
||||
|
||||
- Source SAD: SAD-077, SAD-081, SAD-085
|
||||
- Source SDD: SDD-108, SDD-113, SDD-115 (sequencing)
|
||||
- Source SRS: SRS-208, SRS-212
|
||||
- Verification method: Integration test instrumented with ordered event sink (timestamped events for `mode_engage`, `stream_open`, `effect_attach`, `start`, `stop`, `effect_release`, `stream_close`, `mode_restore`)
|
||||
- Pass criteria: On `voice_join`, the recorded order is exactly `FGS_start → stream_open → mode_engage → effect_attach → start`. On `voice_leave`, the recorded order is exactly `stop → effect_release → mode_restore → stream_close → FGS_stop` per SDD-115 item 3 (reverse-order teardown). Any deviation fails the case. Test repeats 3 rapid join/leave cycles to surface refcount or sequencing races.
|
||||
- Evidence: Integration test result + event-sink dump
|
||||
- SDD-116 matrix rows satisfied: all
|
||||
|
||||
**SWE5-IV-023**: Verify SDD-115 full lifecycle sequencing forward and reverse.
|
||||
|
||||
- Source SAD: SAD-077, SAD-081
|
||||
- Source SDD: SDD-107, SDD-108, SDD-111, SDD-113, SDD-115
|
||||
- Source SRS: SRS-208, SRS-210, SRS-212, SRS-215
|
||||
- Verification method: Instrumented integration test on physical device
|
||||
- Pass criteria: Forward sequence: `FGS_start → streams_open → mode_engage → effects_bind → start_capture+playback`. Reverse sequence: `stop → effects_release → mode_restore → streams_close → FGS_stop`. Test asserts strict ordering AND that no event from one step occurs before the previous step completes (no overlap). Test re-runs across at least one API 28 device and one API 34 device to cover the FGS-type tightening branch.
|
||||
- Evidence: Integration test result + ordered event log
|
||||
- SDD-116 matrix rows satisfied: API 28 row, API 31 row, API 34 row
|
||||
|
||||
**SWE5-IV-024**: Verify audio-focus loss handling.
|
||||
|
||||
- Source SAD: SAD-077, SAD-081, SAD-085
|
||||
- Source SDD: SDD-115 (audio focus event response)
|
||||
- Source SRS: SRS-208, SRS-215
|
||||
- Verification method: Integration test using a controllable secondary audio source (test app that requests focus with the three loss kinds)
|
||||
- Pass criteria: `AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK` → capture and playback continue at unchanged level (Chanora does not duck itself; voice content is exempt per SDD-115). `AUDIOFOCUS_LOSS_TRANSIENT` → capture is paused (no frames produced upstream) and playback is paused; on focus regain, both resume without `voice_leave`/`voice_join`. `AUDIOFOCUS_LOSS` (permanent) → the session is left cleanly (effects released, mode restored, streams closed) and the user is surfaced an "audio focus lost" state; no auto-rejoin.
|
||||
- Evidence: Integration test result + logcat
|
||||
- SDD-116 matrix rows satisfied: at least API 31 + API 34 rows
|
||||
|
||||
**SWE5-IV-025**: Verify `ErrorDisconnected` callback marshals to tokio task and triggers reopen without blocking the callback thread.
|
||||
|
||||
- Source SAD: SAD-077, SAD-081
|
||||
- Source SDD: SDD-111 (error/disconnect callback via bounded channel/watch), SDD-115 (recovery on disconnect)
|
||||
- Source SRS: SRS-210, SRS-215
|
||||
- Verification method: Integration test injecting a forced disconnect (e.g. unplug Bluetooth headset mid-session, or invoke an Oboe error-callback fault injection point)
|
||||
- Pass criteria: The Oboe `onErrorBeforeClose` / `onErrorAfterClose` callback path enqueues a message onto the bounded channel and returns within the callback's documented latency budget (assert: callback returns in < 5 ms). Reopen is performed on a tokio task on the engine runtime, not on the callback thread (verified by thread-id capture in test). Reopen completes (`voice_join` round-trip on the new device route) within 2 s. The callback never holds a lock during reopen.
|
||||
- Evidence: Integration test result + thread-id capture log
|
||||
- SDD-116 matrix rows satisfied: all (regression surface)
|
||||
|
||||
**SWE5-IV-026**: Verify permission-denied `voice_join` reports listen-only and does NOT start the foreground service for capture.
|
||||
|
||||
- Source SAD: SAD-077
|
||||
- Source SDD: SDD-106, SDD-107, SDD-111, SDD-115
|
||||
- Source SRS: SRS-209, SRS-215
|
||||
- Verification method: Integration test with `RECORD_AUDIO` denied via permission test double
|
||||
- Pass criteria: `voice_join` opens the output (playback) stream and engine state becomes `RunningListenOnly`. `AndroidVoiceForegroundService` is NOT started with `foregroundServiceType="microphone"` for capture (the service may still run as a non-mic FGS for playback longevity per SDD-107 policy — if SDD-107 declines this, the FGS is not started at all). Backend reports `capture_state = ListenOnly`. No `AndroidVoiceUnit` input stream is opened. UI badge reflects listen-only. On runtime permission grant, the engine performs an internal upgrade to full duplex without process restart and without losing the playback stream. Cross-link: builds on SWE5-IV-017.
|
||||
- Evidence: Integration test result + logcat + UI screenshot
|
||||
- SDD-116 matrix rows satisfied: API 28 row, API 34 row (FGS-type tightening branch)
|
||||
|
||||
| Architecture / Design Area | SWE.5 Coverage |
|
||||
|---|---|
|
||||
| SAD-077, SAD-081 (mobile voice audio backend allocation) | SWE5-IV-021 through SWE5-IV-026 |
|
||||
| SDD-111, SDD-112, SDD-113, SDD-115 | SWE5-IV-021 through SWE5-IV-026 |
|
||||
| SDD-116 (device matrix coverage entry points) | SWE5-IV-021, SWE5-IV-023 |
|
||||
|
||||
|
||||
## Baseline Candidate 0.9.4 Update
|
||||
|
||||
| Version | Date | Description |
|
||||
|---|---|---|
|
||||
| 0.9.4 | 2026-05-18 | Added Android P0 software-integration items SWE5-IV-016..SWE5-IV-020 covering JNI+FGS, permission+FGS+listen-only fallback, FGS+audio-mode round-trip, BackIntentService + Flutter route stack, and AAB build pipeline (bundletool + ABI splits). |
|
||||
| 0.9.5 | 2026-05-18 | Added Android voice audio backend integration items SWE5-IV-021..SWE5-IV-026 covering MobileVoiceAudioBackend trait + engine wiring (SDD-111), SDD-108↔SDD-113 ordering and reverse-order teardown (SDD-115), full lifecycle sequencing across SDD-107/108/111/113, audio-focus loss handling, ErrorDisconnected callback marshaling, and permission-denied listen-only fallback. Cross-links: SWE5-IV-017 extended by SWE5-IV-026 (listen-only fallback). |
|
||||
|
||||
Reference in New Issue
Block a user