docs(openspec): cancel alarm FGS slice, the alarm service type never existed
Apply-stage SDK verification (javap on android-34/35/36 platform jars plus api-versions.xml) proved FOREGROUND_SERVICE_TYPE_ALARM and the FOREGROUND_SERVICE_ALARM permission are fictional constants. The existing mediaPlayback|systemExempted declaration is the documented correct pattern for an alarm app holding exact-alarm permissions, so slice 1 ships no code and root cause B is withdrawn. Spec, design, and tasks amended with the evidence; volume-override and fade-dedup slices proceed unaffected.
This commit is contained in:
@@ -1,5 +1,19 @@
|
|||||||
# Design: Alarm Volume Ramp & Device-Volume Immunity
|
# Design: Alarm Volume Ramp & Device-Volume Immunity
|
||||||
|
|
||||||
|
> **SLICE 1 CANCELLED — CORRECTION (2026-07-11, apply-stage SDK verification).**
|
||||||
|
> The first two Architecture Decisions below are built on constants that DO NOT EXIST in the
|
||||||
|
> Android SDK: `FOREGROUND_SERVICE_TYPE_ALARM` and `android.permission.FOREGROUND_SERVICE_ALARM`
|
||||||
|
> are fictional (verified via `javap -constants` on the local android-34/35/36 platform jars and a
|
||||||
|
> full `api-versions.xml` sweep — 13 real FGS types, no alarm variant; constants are additive, so
|
||||||
|
> absence in 36 rules out 34/35). The existing `mediaPlayback|systemExempted` declaration is the
|
||||||
|
> documented correct pattern for an alarm-clock app holding exact-alarm permissions starting an FGS
|
||||||
|
> from an AlarmManager broadcast, and the prior `app-quality-and-native-alarms` deviation
|
||||||
|
> (T-S1-03/04) that kept it was right. Slice 1 ships NO code change. Root Cause B from the
|
||||||
|
> exploration is withdrawn; the user-visible bug is fully attributed to Root Cause A (media-stream
|
||||||
|
> steady state), addressed by Slices 2 and 3, which are independent and unaffected.
|
||||||
|
> Evidence trail: engram `sdd/alarm-volume-ramp-restore/apply-progress` (#2332) and project
|
||||||
|
> discovery `android/fgs-alarm-type-nonexistent` (#2333).
|
||||||
|
|
||||||
## Technical Approach
|
## Technical Approach
|
||||||
|
|
||||||
Three independent, rollback-isolated slices realizing proposal #2302. Kotlin owns the manifest fix and a new ring-scoped `STREAM_MUSIC` override (no Flutter volume plugin exists; `MainActivity` already owns the audio channels). Dart drives lifecycle: it invokes override at ring start and restore from the already-centralized exit points. The existing 5%->`alarma.volumen` Dart player ramp is kept; only the audible fade-in *driver* is deduped at handoff. Normal radio playback and `ServicioAudioSession` ducking (S3-R1) are never touched — the override fires only while a ring is active. Kotlin is code-inspection + mandatory on-device QA (flutter build forbidden); Dart follows strict TDD.
|
Three independent, rollback-isolated slices realizing proposal #2302. Kotlin owns the manifest fix and a new ring-scoped `STREAM_MUSIC` override (no Flutter volume plugin exists; `MainActivity` already owns the audio channels). Dart drives lifecycle: it invokes override at ring start and restore from the already-centralized exit points. The existing 5%->`alarma.volumen` Dart player ramp is kept; only the audible fade-in *driver* is deduped at handoff. Normal radio playback and `ServicioAudioSession` ducking (S3-R1) are never touched — the override fires only while a ring is active. Kotlin is code-inspection + mandatory on-device QA (flutter build forbidden); Dart follows strict TDD.
|
||||||
|
|||||||
@@ -4,15 +4,15 @@
|
|||||||
|
|
||||||
### Requirement: Manifest declares alarm-eligible foreground service
|
### Requirement: Manifest declares alarm-eligible foreground service
|
||||||
|
|
||||||
`PluriWaveAlarmService` in `AndroidManifest.xml` MUST use `foregroundServiceType="mediaPlayback|alarm"` and the app MUST declare `FOREGROUND_SERVICE_ALARM`, so the service is eligible to start on Android 14+ (API 34+) from a broadcast receiver.
|
**CORRECTED (2026-07-11, apply-stage SDK verification)**: the originally specified `foregroundServiceType="mediaPlayback|alarm"` + `FOREGROUND_SERVICE_ALARM` permission are FICTIONAL — neither constant exists anywhere in the Android SDK (verified via `javap -constants` on android-34/35/36 platform jars and `api-versions.xml`; 13 real FGS types, no alarm variant). The existing declaration `foregroundServiceType="mediaPlayback|systemExempted"` is the documented correct pattern for an alarm-clock app holding exact-alarm permissions that starts a foreground service from an AlarmManager broadcast on API 34+. The prior `app-quality-and-native-alarms` deviation (T-S1-03/04) that kept `systemExempted` was right. No manifest or runtime change ships in this change; the requirement is re-scoped to the service-start behavior below.
|
||||||
|
|
||||||
#### Scenario: Manifest declares required FGS type and permission
|
#### Scenario: Manifest keeps the verified-correct FGS declaration
|
||||||
**Testability**: static/grep-verifiable
|
**Testability**: static/grep-verifiable
|
||||||
|
|
||||||
- GIVEN the built `AndroidManifest.xml`
|
- GIVEN the built `AndroidManifest.xml`
|
||||||
- WHEN the `PluriWaveAlarmService` `<service>` element is inspected
|
- WHEN the `PluriWaveAlarmService` `<service>` element is inspected
|
||||||
- THEN `android:foregroundServiceType` MUST contain `alarm`
|
- THEN `android:foregroundServiceType` MUST be `mediaPlayback|systemExempted`
|
||||||
- AND a `<uses-permission android:name="android.permission.FOREGROUND_SERVICE_ALARM"/>` MUST exist
|
- AND the runtime `startForeground` type constants in `PluriWaveAlarmService.kt` MUST match the manifest declaration
|
||||||
|
|
||||||
#### Scenario: Native service starts from broadcast context on Android 14+
|
#### Scenario: Native service starts from broadcast context on Android 14+
|
||||||
**Testability**: manual on-device QA (Android 14+; agent cannot install/verify)
|
**Testability**: manual on-device QA (Android 14+; agent cannot install/verify)
|
||||||
|
|||||||
@@ -28,9 +28,18 @@ Chain strategy: pending
|
|||||||
|
|
||||||
## Phase 1: FGS Manifest + Runtime Type Fix (Slice 1 — code-inspection + manual QA)
|
## Phase 1: FGS Manifest + Runtime Type Fix (Slice 1 — code-inspection + manual QA)
|
||||||
|
|
||||||
|
> **PHASE CANCELLED (orchestrator, 2026-07-11)** — resolution of the BLOCKED note below: the
|
||||||
|
> target constants are fictional (verified against the local SDK), the existing
|
||||||
|
> `mediaPlayback|systemExempted` declaration is confirmed correct, and Root Cause B is withdrawn.
|
||||||
|
> Tasks 1.1-1.7 ship no code. See the correction banner in design.md and the amended Requirement
|
||||||
|
> in specs/native-alarms/spec.md. Slices 2 and 3 proceed unaffected.
|
||||||
|
|
||||||
- [ ] 1.1 Edit `android/app/src/main/AndroidManifest.xml:57` — change `PluriWaveAlarmService` `android:foregroundServiceType` from `"mediaPlayback|systemExempted"` to `"mediaPlayback|alarm"`.
|
- [ ] 1.1 Edit `android/app/src/main/AndroidManifest.xml:57` — change `PluriWaveAlarmService` `android:foregroundServiceType` from `"mediaPlayback|systemExempted"` to `"mediaPlayback|alarm"`.
|
||||||
- [ ] 1.2 Edit `android/app/src/main/AndroidManifest.xml:6` — replace `<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SYSTEM_EXEMPTED"/>` with `<uses-permission android:name="android.permission.FOREGROUND_SERVICE_ALARM"/>`.
|
- [ ] 1.2 Edit `android/app/src/main/AndroidManifest.xml:6` — replace `<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SYSTEM_EXEMPTED"/>` with `<uses-permission android:name="android.permission.FOREGROUND_SERVICE_ALARM"/>`.
|
||||||
- [ ] 1.3 Edit `PluriWaveAlarmService.kt:118-119` — change `startForeground` type constants from `FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK or FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED` to `FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK or FOREGROUND_SERVICE_TYPE_ALARM`. 1.1-1.3 are ONE atomic unit — a manifest-only or runtime-only edit leaves the API 34+ exception alive; do not split across commits.
|
- [ ] 1.3 Edit `PluriWaveAlarmService.kt:118-119` — change `startForeground` type constants from `FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK or FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED` to `FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK or FOREGROUND_SERVICE_TYPE_ALARM`. 1.1-1.3 are ONE atomic unit — a manifest-only or runtime-only edit leaves the API 34+ exception alive; do not split across commits.
|
||||||
|
|
||||||
|
> **BLOCKED (sdd-apply, 2026-07-11):** `FOREGROUND_SERVICE_TYPE_ALARM` / `android.permission.FOREGROUND_SERVICE_ALARM` do NOT exist in the Android SDK. Verified via `javap -constants` against `android.content.pm.ServiceInfo` and `android.Manifest$permission` in the local `android-34`/`android-35`/`android-36` platform `android.jar`s, plus a full `FOREGROUND_SERVICE_TYPE_*` field sweep of `api-versions.xml`. The only FGS types that exist through API 36 are: camera, connectedDevice, dataSync, health, location, manifest, mediaPlayback, mediaProcessing, mediaProjection, microphone, phoneCall, remoteMessaging, shortService, specialUse, systemExempted — no `alarm` variant. Edits 1.1-1.3 were applied then reverted (`git checkout --`) to avoid landing an unresolved-Kotlin-reference / invalid-manifest-enum compile break that `flutter analyze` cannot catch (Dart-only) and that this task explicitly forbids validating via `flutter build`/gradle. This reconfirms the identical finding already recorded in `app-quality-and-native-alarms` (T-S1-03/T-S1-04), which used `systemExempted`/`FOREGROUND_SERVICE_SYSTEM_EXEMPTED` for the same reason — see design #2310's own "Open Questions" section, which flagged but did not resolve this before approval. Design #2310 / tasks #2316 need correction before Slice 1 can proceed: either identify a real SDK-backed fix for the API 34+ `ForegroundServiceTypeException`, or confirm `systemExempted` was already correct and the actual Slice 1 defect (if any) lies elsewhere. Working tree is clean — no diff left on either file.
|
||||||
|
|
||||||
- [ ] 1.4 Static check: `rg 'foregroundServiceType' android/app/src/main/AndroidManifest.xml` shows `alarm`, not `systemExempted`, on the `PluriWaveAlarmService` line.
|
- [ ] 1.4 Static check: `rg 'foregroundServiceType' android/app/src/main/AndroidManifest.xml` shows `alarm`, not `systemExempted`, on the `PluriWaveAlarmService` line.
|
||||||
- [ ] 1.5 Static check: `rg 'FOREGROUND_SERVICE_ALARM|FOREGROUND_SERVICE_SYSTEM_EXEMPTED' android/app/src/main/AndroidManifest.xml` shows `FOREGROUND_SERVICE_ALARM` present and `FOREGROUND_SERVICE_SYSTEM_EXEMPTED` absent.
|
- [ ] 1.5 Static check: `rg 'FOREGROUND_SERVICE_ALARM|FOREGROUND_SERVICE_SYSTEM_EXEMPTED' android/app/src/main/AndroidManifest.xml` shows `FOREGROUND_SERVICE_ALARM` present and `FOREGROUND_SERVICE_SYSTEM_EXEMPTED` absent.
|
||||||
- [ ] 1.6 Static check: `rg 'FOREGROUND_SERVICE_TYPE_ALARM|FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED' android/.../PluriWaveAlarmService.kt` shows `TYPE_ALARM` present and `TYPE_SYSTEM_EXEMPTED` absent — confirms manifest/runtime match (Requirement: Manifest declares alarm-eligible FGS, Scenario "Manifest declares required FGS type and permission").
|
- [ ] 1.6 Static check: `rg 'FOREGROUND_SERVICE_TYPE_ALARM|FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED' android/.../PluriWaveAlarmService.kt` shows `TYPE_ALARM` present and `TYPE_SYSTEM_EXEMPTED` absent — confirms manifest/runtime match (Requirement: Manifest declares alarm-eligible FGS, Scenario "Manifest declares required FGS type and permission").
|
||||||
|
|||||||
Reference in New Issue
Block a user