diff --git a/docs/android-app-analysis.md b/docs/android-app-analysis.md index ae85cb6..f0d306e 100644 --- a/docs/android-app-analysis.md +++ b/docs/android-app-analysis.md @@ -491,6 +491,8 @@ JavaScript Promise Resolution - **BootReceiver**: Reschedules notifications after reboot - **Doze Mode**: Handles Android's battery optimization +> **Closed vs force-stopped:** Closing/swiping the app does not affect alarms or WorkManager. **Force-stopping** from Settings cancels alarms and suppresses receivers until the next launch, after which Boot/rehydration logic can restore future schedules. + ## Testing Capabilities ### Interactive Testing Features diff --git a/docs/android-app-improvement-plan.md b/docs/android-app-improvement-plan.md index 0039221..641be4b 100644 --- a/docs/android-app-improvement-plan.md +++ b/docs/android-app-improvement-plan.md @@ -940,6 +940,7 @@ interface ScheduleResponse { - [ ] When fallback is active, matrix shows **"Degraded timing (Doze)"** and last event includes `EVT_DOZE_FALLBACK_TAKEN` - [ ] If app is not ignoring battery optimizations, we **do not** prompt `ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS`; we only deep-link documentation (policy choice) - [ ] Visual badge (e.g., "Degraded (Doze)") plus one-tap link to exact-alarm settings when fallback is active +- [ ] When fallback is active, show a **fixed string** badge: "Degraded (Doze)". Ensure last event includes `EVT_DOZE_FALLBACK_TAKEN`. ### Error Handling - [ ] All @PluginMethod calls validate inputs @@ -962,6 +963,7 @@ interface ScheduleResponse { - [ ] Rescheduler uses unique key `(requestCode|channelId|time)` and **UPSERT** semantics; log `EVT_BOOT_REHYDRATE_DONE(count=n)` - [ ] Only `BootReceiver` is exported; all other receivers remain `exported="false"` - [ ] Timezone and manual clock changes trigger rescheduler with idempotent rehydration +- [ ] **Force-stop limitation:** If the user force-stops the app from Settings, the system cancels all alarms and suppresses receivers until the next explicit app launch. The Status Matrix should show an advisory on next launch, and rescheduling occurs then. ### Testing - [ ] Test UI modularized into scenarios @@ -977,6 +979,7 @@ interface ScheduleResponse { - [ ] No hardcoded secrets or API keys - [ ] Secure network communication (HTTPS only) - [ ] Proper permission handling +- [ ] All notification and alarm `PendingIntent`s use **`FLAG_IMMUTABLE`** unless mutation is required; if mutation is required, use `FLAG_UPDATE_CURRENT | FLAG_MUTABLE` with a stable `requestCode` ### Documentation - [ ] "How it Works" page with lifecycle diagrams @@ -1070,6 +1073,7 @@ By following this plan, the test app will become more maintainable, reliable, an | Closed app delivery | scheduleDailyNotification + DailyNotificationReceiver | App closed, screen off | Exact alarm delivers via receiver; log shows `EVT_SCHEDULE_OK` → receiver → notification | | Closed app fallback | scheduleDailyNotification + WorkManager | App closed, device idle, exact alarm denied | WorkManager fires eventually; UI shows "Degraded timing (Doze)" | | Closed app reboot | BootReceiver | App closed, device reboot | Single notification posts at next window; UPSERT prevents duplicates | +| Force-stopped app | scheduleDailyNotification + app launch | Force-stop from Settings, then launch | No delivery until next explicit launch; on launch, rescheduler restores future schedules; matrix shows advisory | ## Error Codes (canonical)