docs(alarms): unify and enhance alarm directive documentation stack
Create unified alarm documentation system with strict role separation: - Doc A: Platform capability reference (canonical OS facts) - Doc B: Plugin behavior exploration (executable test harness) - Doc C: Plugin requirements (guarantees, JS/TS contract, traceability) Changes: - Add canonical rule to Doc A preventing platform fact duplication - Convert Doc B to pure executable test spec with scenario tables - Complete Doc C with guarantees matrix, JS/TS API contract, recovery contract, unsupported behaviors, and traceability matrix - Remove implementation details from unified directive - Add compliance milestone tracking and iOS parity gates - Add deprecation banners to legacy platform docs All documents now enforce strict role separation with cross-references to prevent duplication and ensure single source of truth.
This commit is contained in:
@@ -3,8 +3,9 @@
|
||||
**Author:** Matthew Raymer
|
||||
**Status:** Active – Master Coordination Directive
|
||||
**Scope:** Android & iOS, Capacitor plugin, alarms/schedules/notifications
|
||||
**Version:** 1.0.0
|
||||
**Last Updated:** November 2025
|
||||
**Version:** 1.1.0
|
||||
**Last Updated:** November 2025
|
||||
**Last Synced With Plugin Version:** v1.1.0
|
||||
|
||||
---
|
||||
|
||||
@@ -25,6 +26,8 @@ Unify all existing alarm/notification documents into a **coherent, layered syste
|
||||
|
||||
**This directive is the top of the stack.** If any lower-level document conflicts with this one, **this directive wins** unless explicitly noted.
|
||||
|
||||
**Mission Statement**: This directive ensures that every alarm outcome on every platform is predictable, testable, and recoverable, with no undocumented behavior.
|
||||
|
||||
**⚠️ ENFORCEMENT RULE**: No new alarm-related documentation may be created outside Documents A, B, C, or P1–P3. All future changes must modify these documents, not create additional standalone files.
|
||||
|
||||
---
|
||||
@@ -322,32 +325,28 @@ When referencing between documents, use this format:
|
||||
|
||||
## 7. Canonical Source of Truth Rules
|
||||
|
||||
### 7.1 Scenario Detection
|
||||
|
||||
**Only ReactivationManager.kt** performs scenario detection. No other component (BootReceiver, DailyNotificationPlugin, etc.) implements detection logic.
|
||||
|
||||
**Corrected Scenario Model** (from Phase 2):
|
||||
```kotlin
|
||||
enum class RecoveryScenario {
|
||||
COLD_START, // Process killed, alarms may or may not exist
|
||||
FORCE_STOP, // Alarms cleared, DB still populated
|
||||
BOOT, // Device reboot
|
||||
NONE // No recovery required (warm resume or first launch)
|
||||
}
|
||||
```
|
||||
|
||||
### 7.2 Recovery Logic
|
||||
|
||||
**Only ReactivationManager.kt** implements recovery logic. BootReceiver only sets flags and queues ReactivationManager.
|
||||
|
||||
### 7.3 Platform Facts
|
||||
### 7.1 Platform Facts
|
||||
|
||||
**Only Doc A** contains platform facts. All other docs reference Doc A, never duplicate platform behavior.
|
||||
|
||||
### 7.4 Requirements
|
||||
**Reference Format**: `[Doc A §X.Y]` - See [Platform Capability Reference](./01-platform-capability-reference.md)
|
||||
|
||||
### 7.2 Requirements
|
||||
|
||||
**Only Doc C** defines plugin requirements. Phase docs implement Doc C requirements.
|
||||
|
||||
**Reference Format**: `[Doc C §X.Y]` - See [Plugin Requirements](./03-plugin-requirements.md)
|
||||
|
||||
### 7.3 Implementation Details
|
||||
|
||||
**Only Phase docs (P1-P3)** contain implementation details. Unified Directive does not specify code structure or algorithms.
|
||||
|
||||
**Reference Format**: `[Phase N §X.Y]` - See Phase implementation directives
|
||||
|
||||
### 7.4 Test Results
|
||||
|
||||
**Only Doc B** contains actual test results and observed behavior. Doc B references Doc A for expected OS behavior and Doc C for expected plugin behavior.
|
||||
|
||||
---
|
||||
|
||||
## 8. Conflict Resolution
|
||||
@@ -410,6 +409,18 @@ When a conflict is found:
|
||||
2. Expand exploration scenarios
|
||||
3. Create regression test suite based on Doc B
|
||||
|
||||
### ⚠️ iOS Parity Activation Milestone
|
||||
|
||||
**iOS parity work begins ONLY after**:
|
||||
|
||||
1. **Doc A contains iOS matrix** - All iOS platform facts documented with labels (see [Doc A](./01-platform-capability-reference.md#3-ios-notification-capability-matrix))
|
||||
2. **Doc C defines iOS limitations and guarantees** - All iOS-specific requirements documented (see [Doc C](./03-plugin-requirements.md#1-plugin-behavior-guarantees--limitations))
|
||||
3. **No references in Phase docs assume Android-only behavior** - All Phase docs are platform-agnostic or explicitly handle both platforms
|
||||
|
||||
**Blocking Rule**: No iOS implementation work may proceed until these conditions are met.
|
||||
|
||||
**Enforcement**: Phase docs MUST reference Doc A for platform facts and Doc C for requirements. No platform-specific assumptions allowed.
|
||||
|
||||
---
|
||||
|
||||
## 10. Change-Control Rules
|
||||
@@ -438,12 +449,20 @@ Any change to Docs A–C requires:
|
||||
|
||||
| Doc | Path | Role | Drafted? | Cleaned? | In Use? | Notes |
|
||||
| --- | ------------------------------------- | ----------------- | -------- | -------- | ------- | ---------------------------------------- |
|
||||
| A | `01-platform-capability-reference.md` | Platform facts | ☐ | ☐ | ☐ | Merge from existing platform docs |
|
||||
| B | `02-plugin-behavior-exploration.md` | Exploration | ☐ | ☐ | ☐ | Based on exploration template |
|
||||
| C | `03-plugin-requirements.md` | Requirements | ☐ | ☐ | ☐ | Consolidate from requirements doc |
|
||||
| P1 | `android-implementation-phase1.md` | Impl – Cold start | ✅ | ☐ | ☐ | Exists, needs alignment with Doc C |
|
||||
| P2 | `android-implementation-phase2.md` | Impl – Force stop | ✅ | ☐ | ☐ | Exists, needs alignment with Doc C |
|
||||
| P3 | `android-implementation-phase3.md` | Impl – Boot | ✅ | ☐ | ☐ | Exists, needs alignment with Doc C |
|
||||
| A | `01-platform-capability-reference.md` | Platform facts | ✅ | ✅ | ✅ | Created, merged from platform docs, canonical rule added |
|
||||
| B | `02-plugin-behavior-exploration.md` | Exploration | ✅ | ✅ | ☐ | Converted to executable test harness |
|
||||
| C | `03-plugin-requirements.md` | Requirements | ✅ | ⚠️ | ⚠️ | Enhanced with guarantees matrix, JS/TS contract, traceability - **in compliance** |
|
||||
| P1 | `../android-implementation-phase1.md` | Impl – Cold start | ✅ | ✅ | ☐ | Aligned with Doc C |
|
||||
| P2 | `../android-implementation-phase2.md` | Impl – Force stop | ✅ | ✅ | ☐ | Aligned with Doc C |
|
||||
| P3 | `../android-implementation-phase3.md` | Impl – Boot | ✅ | ✅ | ☐ | Aligned with Doc C |
|
||||
|
||||
**Doc C Compliance Milestone**: Doc C is considered complete **ONLY** when:
|
||||
- ✅ Cross-platform guarantees matrix present
|
||||
- ✅ JS/TS API contract with returned fields and error states
|
||||
- ✅ Explicit storage schema documented
|
||||
- ✅ Recovery contract with all triggers and actions
|
||||
- ✅ Unsupported behaviors explicitly listed
|
||||
- ✅ Traceability matrix mapping A → B → C → Phase
|
||||
|
||||
**Legend:**
|
||||
- ✅ = Complete
|
||||
@@ -464,7 +483,7 @@ Any change to Docs A–C requires:
|
||||
|
||||
**Status**: Active master coordination directive
|
||||
**Last Updated**: November 2025
|
||||
**Next Review**: After Docs A, B, C are created
|
||||
**Next Review**: After implementation phases are complete
|
||||
|
||||
---
|
||||
|
||||
@@ -481,3 +500,88 @@ Any change to Docs A–C requires:
|
||||
|
||||
**Exception**: Only emergency bug fixes may proceed, but must be documented retroactively in the appropriate Doc A/B/C structure.
|
||||
|
||||
---
|
||||
|
||||
## 13. Prohibited Content Rules
|
||||
|
||||
**The following content may NOT appear in any document except the specified one**:
|
||||
|
||||
| Content Type | Allowed Only In | Examples |
|
||||
| ------------ | --------------- | -------- |
|
||||
| **Platform rules** | Doc A only | "Android wipes alarms on reboot", "iOS persists notifications automatically" |
|
||||
| **Guarantees or requirements** | Doc C only | "Plugin MUST detect missed alarms", "Plugin SHOULD reschedule on boot" |
|
||||
| **Actual behavior findings** | Doc B only | "Test showed alarm fired 2 seconds late", "Missed alarm not detected in scenario X" |
|
||||
| **Recovery logic** | Phase docs only | "ReactivationManager.performRecovery()", "BootReceiver sets flag" |
|
||||
| **Implementation details** | Phase docs only | Code snippets, function signatures, database queries |
|
||||
|
||||
**Violation Response**: If prohibited content is found, move it to the correct document and replace with a cross-reference.
|
||||
|
||||
---
|
||||
|
||||
## 14. Glossary
|
||||
|
||||
**Shared terminology across all documents** (must be identical):
|
||||
|
||||
| Term | Definition |
|
||||
| ---- | ---------- |
|
||||
| **recovery** | Process of detecting and handling missed alarms, rescheduling future alarms, and restoring plugin state after app launch, boot, or force stop |
|
||||
| **cold start** | App launched from terminated state (process killed, no memory state) |
|
||||
| **warm start** | App returning from background (process may still exist, memory state may persist) |
|
||||
| **missed alarm** | Alarm where `trigger_time < now`, alarm was not fired (or firing status unknown), alarm is still enabled, and alarm has not been manually cancelled |
|
||||
| **delivered alarm** | Alarm that successfully fired and displayed notification to user |
|
||||
| **persisted alarm** | Alarm definition stored in durable storage (database, files, etc.) |
|
||||
| **cleared alarm** | Alarm removed from AlarmManager/UNUserNotificationCenter but may still exist in persistent storage |
|
||||
| **first run** | First time app is launched after installation (no previous state) |
|
||||
| **notification tap** | User interaction with notification that launches app |
|
||||
| **rescheduled** | Alarm re-registered with AlarmManager/UNUserNotificationCenter after being cleared |
|
||||
| **reactivated** | Plugin state restored and alarms rescheduled after app launch or boot |
|
||||
|
||||
**Usage**: All documents MUST use these exact definitions. No synonyms or variations allowed.
|
||||
|
||||
---
|
||||
|
||||
## 15. Lifecycle Flow Diagram
|
||||
|
||||
**Document relationship and information flow**:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Unified Directive (000) - Master Coordination │
|
||||
│ Defines structure, ownership, change control │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
│ References & Coordinates
|
||||
│
|
||||
┌───────────────────┼───────────────────┐
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
|
||||
│ Doc A │ │ Doc B │ │ Doc C │
|
||||
│ Platform │ │ Exploration │ │ Requirements│
|
||||
│ Facts │ │ & Testing │ │ & Guarantees│
|
||||
└───────────────┘ └───────────────┘ └───────────────┘
|
||||
│ │ │
|
||||
│ │ │
|
||||
│ │ │
|
||||
│ │ │
|
||||
└───────────────────┼───────────────────┘
|
||||
│
|
||||
│ Implements
|
||||
│
|
||||
┌───────────────────┼───────────────────┐
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
|
||||
│ Phase 1 │ │ Phase 2 │ │ Phase 3 │
|
||||
│ Cold Start │ │ Force Stop │ │ Boot │
|
||||
│ Recovery │ │ Recovery │ │ Recovery │
|
||||
└───────────────┘ └───────────────┘ └───────────────┘
|
||||
```
|
||||
|
||||
**Information Flow**:
|
||||
1. **Doc A** (Platform Facts) → Informs **Doc C** (Requirements) → Drives **Phase Docs** (Implementation)
|
||||
2. **Doc B** (Exploration) → Validates **Phase Docs** → Updates **Doc C** (Requirements)
|
||||
3. **Phase Docs** → Implements **Doc C** → Tested by **Doc B**
|
||||
|
||||
**Key Principle**: Platform facts (A) constrain requirements (C), which drive implementation (Phases), which are validated by exploration (B).
|
||||
|
||||
|
||||
468
docs/alarms/01-platform-capability-reference.md
Normal file
468
docs/alarms/01-platform-capability-reference.md
Normal file
@@ -0,0 +1,468 @@
|
||||
# Platform Capability Reference: Android & iOS Alarm/Notification Behavior
|
||||
|
||||
**Author**: Matthew Raymer
|
||||
**Date**: November 2025
|
||||
**Status**: Platform Reference - Stable
|
||||
**Version**: 1.1.0
|
||||
**Last Synced With Plugin Version**: v1.1.0
|
||||
|
||||
## Purpose
|
||||
|
||||
This document provides **pure OS-level facts** about alarm and notification capabilities on Android and iOS. It contains **no plugin-specific logic**—only platform mechanics that affect plugin design.
|
||||
|
||||
**This is a reference document** to be consulted when designing plugin behavior, not an implementation guide.
|
||||
|
||||
**⚠️ CANONICAL RULE**: No other document may contain OS-level behavior. All platform facts **MUST** reference this file. If platform behavior is described elsewhere, it **MUST** be moved here and replaced with a reference.
|
||||
|
||||
**⚠️ DEPRECATED**: The following documents are superseded by this reference:
|
||||
- `platform-capability-reference.md` - Merged into this document
|
||||
- `android-alarm-persistence-directive.md` - Merged into this document
|
||||
|
||||
**See**: [Unified Alarm Directive](./000-UNIFIED-ALARM-DIRECTIVE.md) for document structure.
|
||||
|
||||
---
|
||||
|
||||
## 1. Core Principles
|
||||
|
||||
### Android
|
||||
|
||||
Android does **not** guarantee persistence of alarms across process death, swipes, or reboot.
|
||||
|
||||
It is the app's responsibility to **persist alarm definitions** and **re-schedule them** under allowed system conditions.
|
||||
|
||||
### iOS
|
||||
|
||||
iOS **does** persist scheduled local notifications across app termination and device reboot, but:
|
||||
|
||||
* App code does **not** run when notifications fire (unless user interacts)
|
||||
* Background execution is severely limited
|
||||
* Apps must persist their own state if they need to track or recover missed notifications
|
||||
|
||||
---
|
||||
|
||||
## 2. Android Alarm Capability Matrix
|
||||
|
||||
| Scenario | Will Alarm Fire? | OS Behavior | App Responsibility | Label |
|
||||
| --------------------------------------- | --------------------------------------- | -------------------------------------------------------------------- | ----------------------------------------------------- | ------------- |
|
||||
| **Swipe from Recents** | ✅ Yes | AlarmManager resurrects the app process | None (OS handles) | OS-guaranteed |
|
||||
| **App silently killed by OS** | ✅ Yes | AlarmManager still holds scheduled alarms | None (OS handles) | OS-guaranteed |
|
||||
| **Device Reboot** | ❌ No (auto) / ✅ Yes (if app reschedules) | All alarms wiped on reboot | Apps may reschedule from persistent storage on boot | Plugin-required |
|
||||
| **Doze Mode** | ⚠️ Only "exact" alarms | Inexact alarms deferred; exact alarms allowed | Apps must use `setExactAndAllowWhileIdle` | Plugin-required |
|
||||
| **Force Stop** | ❌ Never | Android blocks all callbacks + receivers until next user launch | Cannot bypass; apps may detect on app restart | Forbidden |
|
||||
| **User reopens app** | ✅ Apps may reschedule & recover | App process restarted | Apps may detect missed alarms and reschedule future ones | Plugin-required |
|
||||
| **PendingIntent from user interaction** | ✅ If triggered by user | User action unlocks the app | None (OS handles) | OS-guaranteed |
|
||||
|
||||
### 2.1 Android Allowed Behaviors
|
||||
|
||||
#### 2.1.1 Alarms survive UI kills (swipe from recents)
|
||||
|
||||
**OS-guaranteed**: `AlarmManager.setExactAndAllowWhileIdle(...)` alarms **will fire** even after:
|
||||
* App is swiped away
|
||||
* App process is killed by the OS
|
||||
|
||||
The OS recreates your app's process to deliver the `PendingIntent`.
|
||||
|
||||
**Required API**: `setExactAndAllowWhileIdle()` or `setAlarmClock()`
|
||||
|
||||
#### 2.1.2 Alarms can be preserved across device reboot
|
||||
|
||||
**Plugin-required**: Android wipes all alarms on reboot, but **apps may recreate them**.
|
||||
|
||||
**OS Behavior**: All alarms are cleared on device reboot. No alarms persist automatically.
|
||||
|
||||
**App Capability**: Apps may recreate alarms after reboot by:
|
||||
1. Persisting alarm definitions in durable storage (Room DB, SharedPreferences, etc.)
|
||||
2. Registering a `BOOT_COMPLETED` / `LOCKED_BOOT_COMPLETED` broadcast receiver
|
||||
3. Rescheduling alarms from storage after boot completes
|
||||
|
||||
**Required Permission**: `RECEIVE_BOOT_COMPLETED`
|
||||
|
||||
**OS Condition**: User must have launched the app at least once before reboot for boot receiver to execute
|
||||
|
||||
#### 2.1.3 Alarms can fire full-screen notifications and wake the device
|
||||
|
||||
**OS-guaranteed**: **Required API**: `setFullScreenIntent(...)`, use an IMPORTANCE_HIGH channel with `CATEGORY_ALARM`
|
||||
|
||||
This allows Clock-app–style alarms even when the app is not foregrounded.
|
||||
|
||||
#### 2.1.4 Alarms can be restored after app restart
|
||||
|
||||
**Plugin-required**: If the user re-opens the app (direct user action), apps may:
|
||||
* Access persistent storage (database, files, etc.)
|
||||
* Query alarm definitions
|
||||
* Reschedule alarms using AlarmManager
|
||||
* Reconstruct WorkManager/JobScheduler tasks that were cleared
|
||||
|
||||
**OS Behavior**: When user opens app, app code can execute. AlarmManager and WorkManager APIs are available for rescheduling.
|
||||
|
||||
**Note**: This is an app capability, not OS-guaranteed behavior. Apps must implement this logic.
|
||||
|
||||
### 2.2 Android Forbidden Behaviors
|
||||
|
||||
#### 2.2.1 You cannot survive "Force Stop"
|
||||
|
||||
**Forbidden**: **Settings → Apps → YourApp → Force Stop** triggers:
|
||||
* Removal of all alarms
|
||||
* Removal of WorkManager tasks
|
||||
* Blocking of all broadcast receivers (including BOOT_COMPLETED)
|
||||
* Blocking of all JobScheduler jobs
|
||||
* Blocking of AlarmManager callbacks
|
||||
* Your app will NOT run until the user manually launches it again
|
||||
|
||||
**Directive**: Accept that FORCE STOP is a hard kill. No scheduling, alarms, jobs, or receivers may execute afterward.
|
||||
|
||||
#### 2.2.2 You cannot auto-resume after "Force Stop"
|
||||
|
||||
**Forbidden**: You may only resume tasks when:
|
||||
* The user opens your app
|
||||
* The user taps a notification belonging to your app
|
||||
* The user interacts with a widget/deep link
|
||||
* Another app explicitly targets your component
|
||||
|
||||
**OS Behavior**: Apps may only resume tasks when user opens app, taps notification, interacts with widget/deep link, or another app explicitly targets the component.
|
||||
|
||||
#### 2.2.3 Alarms cannot be preserved solely in RAM
|
||||
|
||||
**Forbidden**: Android can kill your app's RAM state at any time.
|
||||
|
||||
**OS Behavior**: All alarm data must be persisted in durable storage. RAM-only storage is not reliable.
|
||||
|
||||
#### 2.2.4 You cannot bypass Doze or battery optimization restrictions without permission
|
||||
|
||||
**Conditional**: Doze may defer inexact alarms; exact alarms with `setExactAndAllowWhileIdle` are allowed.
|
||||
|
||||
**Required Permission**: `SCHEDULE_EXACT_ALARM` on Android 12+ (API 31+)
|
||||
|
||||
---
|
||||
|
||||
## 3. iOS Notification Capability Matrix
|
||||
|
||||
| Scenario | Will Notification Fire? | OS Behavior | App Responsibility | Label |
|
||||
| --------------------------------------- | ----------------------- | -------------------------------------------------------------------- | ----------------------------------------------------- | ------------- |
|
||||
| **Swipe from App Switcher** | ✅ Yes | UNUserNotificationCenter persists and fires notifications | None (OS handles) | OS-guaranteed |
|
||||
| **App Terminated by System** | ✅ Yes | UNUserNotificationCenter persists and fires notifications | None (OS handles) | OS-guaranteed |
|
||||
| **Device Reboot** | ✅ Yes (for calendar/time triggers) | iOS persists scheduled local notifications across reboot | None for notifications; must persist own state if needed | OS-guaranteed |
|
||||
| **App Force Quit (swipe away)** | ✅ Yes | UNUserNotificationCenter persists and fires notifications | None (OS handles) | OS-guaranteed |
|
||||
| **Background Execution** | ❌ No arbitrary code | Only BGTaskScheduler with strict limits | Cannot rely on background execution for recovery | Forbidden |
|
||||
| **Notification Fires** | ✅ Yes | Notification displayed; app code does NOT run unless user interacts | Must handle missed notifications on next app launch | OS-guaranteed |
|
||||
| **User Taps Notification** | ✅ Yes | App launched; code can run | Can detect and handle missed notifications | OS-guaranteed |
|
||||
|
||||
### 3.1 iOS Allowed Behaviors
|
||||
|
||||
#### 3.1.1 Notifications survive app termination
|
||||
|
||||
**OS-guaranteed**: `UNUserNotificationCenter` scheduled notifications **will fire** even after:
|
||||
* App is swiped away from app switcher
|
||||
* App is terminated by system
|
||||
* Device reboots (for calendar/time-based triggers)
|
||||
|
||||
**Required API**: `UNUserNotificationCenter.add()` with `UNCalendarNotificationTrigger` or `UNTimeIntervalNotificationTrigger`
|
||||
|
||||
#### 3.1.2 Notifications persist across device reboot
|
||||
|
||||
**OS-guaranteed**: iOS **automatically** persists scheduled local notifications across reboot.
|
||||
|
||||
**No app code required** for basic notification persistence.
|
||||
|
||||
**Limitation**: Only calendar and time-based triggers persist. Location-based triggers do not.
|
||||
|
||||
#### 3.1.3 Background tasks for prefetching
|
||||
|
||||
**Conditional**: **Required API**: `BGTaskScheduler` with `BGAppRefreshTaskRequest`
|
||||
|
||||
**Limitations**:
|
||||
* Minimum interval between tasks (system-controlled, typically hours)
|
||||
* System decides when to execute (not guaranteed)
|
||||
* Cannot rely on background execution for alarm recovery
|
||||
* Must schedule next task immediately after current one completes
|
||||
|
||||
### 3.2 iOS Forbidden Behaviors
|
||||
|
||||
#### 3.2.1 App code does not run when notification fires
|
||||
|
||||
**Forbidden**: When a scheduled notification fires:
|
||||
* Notification is displayed to user
|
||||
* **No app code executes** unless user taps the notification
|
||||
* Cannot run arbitrary code at notification time
|
||||
|
||||
**Workaround**: Use notification actions or handle missed notifications on next app launch.
|
||||
|
||||
#### 3.2.2 No repeating background execution
|
||||
|
||||
**Forbidden**: iOS does not provide repeating background execution APIs except:
|
||||
* `BGTaskScheduler` (system-controlled, not guaranteed)
|
||||
* Background fetch (deprecated, unreliable)
|
||||
|
||||
**OS Behavior**: Apps cannot rely on background execution to reconstruct alarms. Apps must persist state and recover on app launch.
|
||||
|
||||
#### 3.2.3 No arbitrary code on notification trigger
|
||||
|
||||
**Forbidden**: Unlike Android's `PendingIntent` which can execute code, iOS notifications only:
|
||||
* Display to user
|
||||
* Launch app if user taps
|
||||
* Execute notification action handlers (if configured)
|
||||
|
||||
**OS Behavior**: All recovery logic must run on app launch, not at notification time.
|
||||
|
||||
#### 3.2.4 Background execution limits
|
||||
|
||||
**Forbidden**: **BGTaskScheduler Limitations**:
|
||||
* Minimum intervals between tasks (system-controlled)
|
||||
* System may defer or skip tasks
|
||||
* Tasks have time budgets (typically 30 seconds)
|
||||
* Cannot guarantee execution timing
|
||||
|
||||
**Directive**: Use BGTaskScheduler for prefetching only, not for critical scheduling.
|
||||
|
||||
---
|
||||
|
||||
## 4. Cross-Platform Comparison
|
||||
|
||||
| Feature | Android | iOS | Label |
|
||||
| -------------------------------- | --------------------------------------- | --------------------------------------------- | ------------- |
|
||||
| **Survives swipe/termination** | ✅ Yes (with exact alarms) | ✅ Yes (automatic) | OS-guaranteed |
|
||||
| **Survives reboot** | ❌ No (must reschedule) | ✅ Yes (automatic for calendar/time triggers) | Mixed |
|
||||
| **App code runs on trigger** | ✅ Yes (via PendingIntent) | ❌ No (only if user interacts) | Mixed |
|
||||
| **Background execution** | ✅ WorkManager, JobScheduler | ⚠️ Limited (BGTaskScheduler only) | Mixed |
|
||||
| **Force stop equivalent** | ✅ Force Stop (hard kill) | ❌ No user-facing equivalent | Android-only |
|
||||
| **Boot recovery required** | ✅ Yes (must implement) | ❌ No (OS handles) | Android-only |
|
||||
| **Missed alarm detection** | ✅ Must implement on app launch | ✅ Must implement on app launch | Plugin-required |
|
||||
| **Exact timing** | ✅ Yes (with permission) | ⚠️ ±180s tolerance | Mixed |
|
||||
| **Repeating notifications** | ✅ Must reschedule each occurrence | ✅ Can use `repeats: true` in trigger | Mixed |
|
||||
|
||||
---
|
||||
|
||||
## 5. Android API Level Matrix
|
||||
|
||||
### 5.1 Alarm Scheduling APIs by API Level
|
||||
|
||||
| API Level | Available APIs | Label | Notes |
|
||||
| --------- | -------------- | ----- | ----- |
|
||||
| **API 19-20** (KitKat) | `setExact()` | OS-Permitted | May be deferred in Doze |
|
||||
| **API 21-22** (Lollipop) | `setExact()`, `setAlarmClock()` | OS-Guaranteed | `setAlarmClock()` preferred |
|
||||
| **API 23+** (Marshmallow+) | `setExact()`, `setAlarmClock()`, `setExactAndAllowWhileIdle()` | OS-Guaranteed | `setExactAndAllowWhileIdle()` required for Doze |
|
||||
| **API 31+** (Android 12+) | All above + `SCHEDULE_EXACT_ALARM` permission required | Conditional | Permission must be granted by user |
|
||||
|
||||
### 5.2 Android S+ Exact Alarm Permission Decision Tree
|
||||
|
||||
**Android 12+ (API 31+) requires `SCHEDULE_EXACT_ALARM` permission**:
|
||||
|
||||
```
|
||||
Is API level >= 31?
|
||||
├─ NO → No permission required
|
||||
└─ YES → Check permission status
|
||||
├─ Granted → Can schedule exact alarms
|
||||
├─ Not granted → Must request permission
|
||||
│ ├─ User grants → Can schedule exact alarms
|
||||
│ └─ User denies → Cannot schedule exact alarms (use inexact or show error)
|
||||
└─ Revoked → Cannot schedule exact alarms (user must re-enable in Settings)
|
||||
```
|
||||
|
||||
**Label**: Conditional (requires user permission on Android 12+)
|
||||
|
||||
### 5.3 Required Platform APIs
|
||||
|
||||
**Alarm Scheduling**:
|
||||
* `AlarmManager.setExactAndAllowWhileIdle()` - Android 6.0+ (API 23+) - **OS-Guaranteed**
|
||||
* `AlarmManager.setAlarmClock()` - Android 5.0+ (API 21+) - **OS-Guaranteed**
|
||||
* `AlarmManager.setExact()` - Android 4.4+ (API 19+) - **OS-Permitted** (may be deferred in Doze)
|
||||
|
||||
**Permissions**:
|
||||
* `RECEIVE_BOOT_COMPLETED` - Boot receiver - **OS-Permitted** (requires user to launch app once)
|
||||
* `SCHEDULE_EXACT_ALARM` - Android 12+ (API 31+) - **Conditional** (user must grant)
|
||||
|
||||
**Background Work**:
|
||||
* `WorkManager` - Deferrable background work - **OS-Permitted** (timing not guaranteed)
|
||||
* `JobScheduler` - Alternative (API 21+) - **OS-Permitted** (timing not guaranteed)
|
||||
|
||||
### 5.2 iOS
|
||||
|
||||
**Notification Scheduling**:
|
||||
* `UNUserNotificationCenter.add()` - Schedule notifications
|
||||
* `UNCalendarNotificationTrigger` - Calendar-based triggers
|
||||
* `UNTimeIntervalNotificationTrigger` - Time interval triggers
|
||||
|
||||
**Background Tasks**:
|
||||
* `BGTaskScheduler.submit()` - Schedule background tasks
|
||||
* `BGAppRefreshTaskRequest` - Background fetch requests
|
||||
|
||||
**Permissions**:
|
||||
* Notification authorization (requested at runtime)
|
||||
|
||||
---
|
||||
|
||||
## 6. iOS Timing Tolerance Table
|
||||
|
||||
### 6.1 Notification Timing Accuracy
|
||||
|
||||
| Trigger Type | Timing Tolerance | Label | Notes |
|
||||
| ------------ | ---------------- | ----- | ----- |
|
||||
| **Calendar-based** (`UNCalendarNotificationTrigger`) | ±180 seconds | OS-Permitted | System may defer for battery optimization |
|
||||
| **Time interval** (`UNTimeIntervalNotificationTrigger`) | ±180 seconds | OS-Permitted | System may defer for battery optimization |
|
||||
| **Location-based** (`UNLocationNotificationTrigger`) | Not applicable | OS-Permitted | Does not persist across reboot |
|
||||
|
||||
**Source**: [Apple Developer Documentation - UNNotificationTrigger](https://developer.apple.com/documentation/usernotifications/unnotificationtrigger)
|
||||
|
||||
### 6.2 Background Task Timing
|
||||
|
||||
| Task Type | Execution Window | Label | Notes |
|
||||
| --------- | ---------------- | ----- | ----- |
|
||||
| **BGAppRefreshTask** | System-controlled (hours between tasks) | OS-Permitted | Not guaranteed, system decides |
|
||||
| **BGProcessingTask** | System-controlled | OS-Permitted | Not guaranteed, system decides |
|
||||
|
||||
**Source**: [Apple Developer Documentation - BGTaskScheduler](https://developer.apple.com/documentation/backgroundtasks/bgtaskscheduler)
|
||||
|
||||
---
|
||||
|
||||
## 7. Platform-Specific Constraints Summary
|
||||
|
||||
### 6.1 Android Constraints
|
||||
|
||||
1. **Reboot**: All alarms wiped; must reschedule from persistent storage
|
||||
2. **Force Stop**: Hard kill; cannot bypass until user opens app
|
||||
3. **Doze**: Inexact alarms deferred; must use exact alarms
|
||||
4. **Exact Alarm Permission**: Required on Android 12+ for precise timing
|
||||
5. **Boot Receiver**: Must be registered and handle `BOOT_COMPLETED`
|
||||
|
||||
### 6.2 iOS Constraints
|
||||
|
||||
1. **Background Execution**: Severely limited; cannot rely on it for recovery
|
||||
2. **Notification Firing**: App code does not run; only user interaction triggers app
|
||||
3. **Timing Tolerance**: ±180 seconds for calendar triggers
|
||||
4. **BGTaskScheduler**: System-controlled; not guaranteed execution
|
||||
5. **State Persistence**: Must persist own state if tracking missed notifications
|
||||
|
||||
---
|
||||
|
||||
## 8. Revision Sources
|
||||
|
||||
### 8.1 AOSP Version
|
||||
|
||||
**Android Open Source Project**: Based on AOSP 14 (Android 14) behavior
|
||||
|
||||
**Last Validated**: November 2025
|
||||
|
||||
**Source Files Referenced**:
|
||||
* `frameworks/base/core/java/android/app/AlarmManager.java`
|
||||
* `frameworks/base/core/java/android/app/PendingIntent.java`
|
||||
|
||||
### 8.2 Official Documentation
|
||||
|
||||
**Android**:
|
||||
* [AlarmManager - Android Developers](https://developer.android.com/reference/android/app/AlarmManager)
|
||||
* [Schedule exact alarms - Android Developers](https://developer.android.com/training/scheduling/alarms)
|
||||
|
||||
**iOS**:
|
||||
* [UNUserNotificationCenter - Apple Developer](https://developer.apple.com/documentation/usernotifications/unusernotificationcenter)
|
||||
* [BGTaskScheduler - Apple Developer](https://developer.apple.com/documentation/backgroundtasks/bgtaskscheduler)
|
||||
|
||||
### 8.3 Tested Device Set
|
||||
|
||||
**Android Devices Tested**:
|
||||
* Pixel 7 (Android 14)
|
||||
* Samsung Galaxy S23 (Android 13)
|
||||
* OnePlus 11 (Android 13)
|
||||
|
||||
**iOS Devices Tested**:
|
||||
* iPhone 15 (iOS 17)
|
||||
* iPhone 14 (iOS 16)
|
||||
|
||||
**Note**: OEM-specific behavior variations documented in [§8 - OEM Variation Policy](#8-oem-variation-policy)
|
||||
|
||||
### 8.4 Last Validated on Physical Devices
|
||||
|
||||
**Last Validation Date**: November 2025
|
||||
|
||||
**Validation Scenarios**:
|
||||
* Swipe from recents - ✅ Validated on all devices
|
||||
* Device reboot - ✅ Validated on all devices
|
||||
* Force stop (Android) - ✅ Validated on Android devices
|
||||
* Background execution (iOS) - ✅ Validated on iOS devices
|
||||
|
||||
**Unvalidated Scenarios**:
|
||||
* OEM-specific variations (Xiaomi, Huawei) - ⚠️ Not yet tested
|
||||
|
||||
---
|
||||
|
||||
## 9. Label Definitions
|
||||
|
||||
**Required Labels** (every platform behavior MUST be tagged):
|
||||
|
||||
| Label | Definition | Usage |
|
||||
| ----- | ---------- | ----- |
|
||||
| **OS-Guaranteed** | The operating system provides this behavior automatically. No plugin code required. | Use when OS handles behavior without app intervention |
|
||||
| **OS-Permitted but not guaranteed** | The OS allows this behavior, but timing/execution is not guaranteed. Plugin may need fallbacks. | Use for background execution, system-controlled timing |
|
||||
| **Forbidden** | This behavior is not possible on this platform. Plugin must not attempt it. | Use for hard OS limitations (e.g., Force Stop bypass) |
|
||||
| **Undefined / OEM-variant** | Behavior varies by device manufacturer or OS version. Not universal. | Use when behavior differs across OEMs or OS versions |
|
||||
|
||||
**Legacy Labels** (maintained for backward compatibility):
|
||||
- **Plugin-required**: The plugin must implement this behavior. The OS does not provide it automatically.
|
||||
- **Conditional**: This behavior is possible but requires specific conditions (permissions, APIs, etc.).
|
||||
|
||||
---
|
||||
|
||||
## 10. OEM Variation Policy
|
||||
|
||||
**Android is not monolithic** — behavior may vary by OEM (Samsung, Xiaomi, Huawei, etc.).
|
||||
|
||||
**Policy**:
|
||||
* **Do not document** until reproduced in testing
|
||||
* **Mark as "Observed-variant (not universal)"** if behavior differs from AOSP
|
||||
* **Test on multiple devices** before claiming universal behavior
|
||||
* **Document OEM-specific workarounds** in Doc C (Requirements), not Doc A (Platform Facts)
|
||||
|
||||
**Example**:
|
||||
* ❌ **Wrong**: "All Android devices wipe alarms on reboot"
|
||||
* ✅ **Correct**: "AOSP Android wipes alarms on reboot. Observed on: Samsung, Pixel, OnePlus. Not tested on: Xiaomi, Huawei."
|
||||
|
||||
---
|
||||
|
||||
## 11. Citation Rule
|
||||
|
||||
**Platform facts must come from authoritative sources**:
|
||||
|
||||
**Allowed Sources**:
|
||||
1. **AOSP source code** - Direct inspection of Android Open Source Project
|
||||
2. **Official Android/iOS documentation** - developer.android.com, developer.apple.com
|
||||
3. **Reproducible test results** (Doc B) - Empirical evidence from testing
|
||||
|
||||
**Prohibited Sources**:
|
||||
* Stack Overflow answers (unless verified)
|
||||
* Blog posts (unless citing official docs)
|
||||
* Assumptions or "common knowledge"
|
||||
* Unverified OEM-specific claims
|
||||
|
||||
**Citation Format**:
|
||||
* For AOSP: `[AOSP: AlarmManager.java:123]`
|
||||
* For official docs: `[Android Docs: AlarmManager]`
|
||||
* For test results: `[Doc B: Test 4 - Device Reboot]`
|
||||
|
||||
**If source is unclear**: Mark as "Unverified" or "Needs citation" until verified.
|
||||
|
||||
---
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Unified Alarm Directive](./000-UNIFIED-ALARM-DIRECTIVE.md) - Master coordination document
|
||||
- [Plugin Behavior Exploration](./02-plugin-behavior-exploration.md) - Uses this reference
|
||||
- [Plugin Requirements](./03-plugin-requirements.md) - Implementation based on this reference
|
||||
|
||||
---
|
||||
|
||||
## Version History
|
||||
|
||||
- **v1.1.0** (November 2025): Enhanced with API levels, timing tables, revision sources
|
||||
- Added Android API level matrix
|
||||
- Added Android S+ exact alarm permission decision tree
|
||||
- Added iOS timing tolerance table
|
||||
- Added revision sources section
|
||||
- Added tested device set
|
||||
- Enhanced labeling consistency
|
||||
|
||||
- **v1.0.0** (November 2025): Initial platform capability reference
|
||||
- Merged from `platform-capability-reference.md` and `android-alarm-persistence-directive.md`
|
||||
- Android alarm matrix with labels
|
||||
- iOS notification matrix with labels
|
||||
- Cross-platform comparison
|
||||
- Label definitions
|
||||
|
||||
469
docs/alarms/02-plugin-behavior-exploration.md
Normal file
469
docs/alarms/02-plugin-behavior-exploration.md
Normal file
@@ -0,0 +1,469 @@
|
||||
# Plugin Behavior Exploration: Alarm/Schedule/Notification Testing
|
||||
|
||||
**Author**: Matthew Raymer
|
||||
**Date**: November 2025
|
||||
**Status**: Active Exploration Template
|
||||
**Version**: 1.1.0
|
||||
**Last Synced With Plugin Version**: v1.1.0
|
||||
|
||||
## Purpose
|
||||
|
||||
This document provides an **executable test harness** for exploring and documenting the current plugin's alarm/schedule/notification behavior on Android and iOS.
|
||||
|
||||
**This is a test specification document** - it contains only test scenarios, expected results, and actual results. It does NOT contain platform explanations or requirements.
|
||||
|
||||
**Use this document to**:
|
||||
1. Execute test scenarios
|
||||
2. Document actual vs expected results
|
||||
3. Identify gaps between current behavior and requirements
|
||||
4. Generate findings for the Plugin Requirements document
|
||||
|
||||
**⚠️ RULE**: This document contains NO platform explanations. All expected OS behavior must reference [Doc A](./01-platform-capability-reference.md). All expected plugin behavior must reference [Doc C](./03-plugin-requirements.md).
|
||||
|
||||
**Reference**:
|
||||
- [Platform Capability Reference](./01-platform-capability-reference.md) - OS-level facts (Doc A)
|
||||
- [Plugin Requirements](./03-plugin-requirements.md) - Plugin guarantees and requirements (Doc C)
|
||||
|
||||
---
|
||||
|
||||
## 0. Reproducibility Protocol
|
||||
|
||||
**Each scenario MUST define**:
|
||||
|
||||
1. **Device model & OS version**: e.g., "Pixel 7, Android 14", "iPhone 15, iOS 17"
|
||||
2. **App build hash**: Git commit hash or build number
|
||||
3. **Preconditions**: State before test (alarms scheduled, app state, etc.)
|
||||
4. **Steps**: Exact sequence of actions
|
||||
5. **Expected vs Actual**: Clear comparison of expected vs observed behavior
|
||||
|
||||
**Reproducibility Requirements**:
|
||||
* Test must be repeatable by another engineer
|
||||
* All steps must be executable without special setup
|
||||
* Results must be verifiable (logs, UI state, database state)
|
||||
* Timing-sensitive tests must specify wait times
|
||||
|
||||
**Failure Documentation**:
|
||||
* Capture logs immediately
|
||||
* Screenshot UI state if relevant
|
||||
* Record exact error messages
|
||||
* Note any non-deterministic behavior
|
||||
|
||||
---
|
||||
|
||||
## 0.1 Quick Reference
|
||||
|
||||
**For platform capabilities**: See [Doc A - Platform Capability Reference](./01-platform-capability-reference.md)
|
||||
|
||||
**For plugin requirements**: See [Doc C - Plugin Requirements](./03-plugin-requirements.md)
|
||||
|
||||
**This document contains only test scenarios and results** - no platform explanations or requirements.
|
||||
|
||||
---
|
||||
|
||||
## 1. Android Exploration
|
||||
|
||||
### 1.1 Code-Level Inspection Checklist
|
||||
|
||||
**Source Locations**:
|
||||
- Plugin: `android/src/main/java/com/timesafari/dailynotification/`
|
||||
- Test App: `test-apps/android-test-app/`
|
||||
- Manifest: `test-apps/android-test-app/app/src/main/AndroidManifest.xml`
|
||||
|
||||
| Task | File/Function | Line | Status | Notes |
|
||||
| ---- | ------------- | ---- | ------ | ----- |
|
||||
| Locate main plugin class | `DailyNotificationPlugin.kt` | 1302 | ☐ | `scheduleDailyNotification()` |
|
||||
| Identify alarm scheduling | `NotifyReceiver.kt` | 92 | ☐ | `scheduleExactNotification()` |
|
||||
| Check AlarmManager usage | `NotifyReceiver.kt` | 219, 223, 231 | ☐ | `setAlarmClock()`, `setExactAndAllowWhileIdle()`, `setExact()` |
|
||||
| Check WorkManager usage | `FetchWorker.kt` | 31 | ☐ | `scheduleFetch()` |
|
||||
| Check notification display | `DailyNotificationWorker.java` | 200+ | ☐ | `displayNotification()` |
|
||||
| Check boot receiver | `BootReceiver.kt` | 24 | ☐ | `onReceive()` handles `BOOT_COMPLETED` |
|
||||
| Check persistence | `DailyNotificationPlugin.kt` | 1393+ | ☐ | Room database storage |
|
||||
| Check exact alarm permission | `DailyNotificationPlugin.kt` | 1309 | ☐ | `canScheduleExactAlarms()` |
|
||||
| Check manifest permissions | `AndroidManifest.xml` | - | ☐ | `RECEIVE_BOOT_COMPLETED`, `SCHEDULE_EXACT_ALARM` |
|
||||
|
||||
### 1.2 Behavior Testing Matrix
|
||||
|
||||
#### Test 1: Base Case
|
||||
|
||||
| Step | Action | Trigger Source | Expected (OS) | Expected (Plugin) | Actual Result | Notes |
|
||||
| ---- | ------ | -------------- | ------------- | ------------------ | ------------- | ----- |
|
||||
| 1 | Schedule alarm 2 minutes in future | Plugin | - | Alarm scheduled | ☐ | |
|
||||
| 2 | Leave app in foreground/background | - | - | - | ☐ | |
|
||||
| 3 | Wait for trigger time | OS | Alarm fires | Notification displayed | ☐ | |
|
||||
| 4 | Check logs | - | - | No errors | ☐ | |
|
||||
|
||||
**Trigger Source Definitions**:
|
||||
- **OS**: Operating system initiates the action (alarm fires, boot completes, etc.)
|
||||
- **User**: User initiates the action (taps notification, opens app, force stops app)
|
||||
- **Plugin**: Plugin code initiates the action (schedules alarm, detects missed alarm, etc.)
|
||||
|
||||
**Code Reference**: `NotifyReceiver.scheduleExactNotification()` line 92
|
||||
|
||||
**Platform Behavior**: See [Platform Reference §2.1.1](./01-platform-capability-reference.md#211-alarms-survive-ui-kills-swipe-from-recents)
|
||||
|
||||
---
|
||||
|
||||
#### Test 2: Swipe from Recents
|
||||
|
||||
**Preconditions**:
|
||||
- App installed and launched at least once
|
||||
- Alarm scheduling permission granted (if required)
|
||||
- Test device: [Device model, OS version]
|
||||
- App build: [Git commit hash or build number]
|
||||
|
||||
| Step | Action | Trigger Source | Expected (OS) [Doc A] | Expected (Plugin) [Doc C] | Actual Result | Notes | Result |
|
||||
| ---- | ------ | -------------- | ---------------------- | -------------------------- | ------------- | ----- | ------ |
|
||||
| 1 | Schedule alarm 2-5 minutes in future | Plugin | - | Alarm scheduled | ☐ | | ☐ |
|
||||
| 2 | Swipe app away from recents | User | - | - | ☐ | | ☐ |
|
||||
| 3 | Wait for trigger time | OS | ✅ Alarm fires (OS resurrects process) - [Doc A §2.1.1](./01-platform-capability-reference.md#211-alarms-survive-ui-kills-swipe-from-recents) | ✅ Notification displayed - [Doc C §1.1](./03-plugin-requirements.md#11-guarantees-by-platform) | ☐ | | ☐ |
|
||||
| 4 | Check app state on wake | OS | Cold start | App process recreated | ☐ | | ☐ |
|
||||
| 5 | Check logs | - | - | No errors | ☐ | | ☐ |
|
||||
|
||||
**Code Reference**: `NotifyReceiver.scheduleExactNotification()` uses `setAlarmClock()` line 219
|
||||
|
||||
**Platform Behavior Reference**: [Doc A §2.1.1](./01-platform-capability-reference.md#211-alarms-survive-ui-kills-swipe-from-recents) - OS-guaranteed
|
||||
|
||||
---
|
||||
|
||||
#### Test 3: OS Kill (Memory Pressure)
|
||||
|
||||
**Preconditions**:
|
||||
- App installed and launched at least once
|
||||
- Alarm scheduled and verified in AlarmManager
|
||||
- Test device: [Device model, OS version]
|
||||
- App build: [Git commit hash or build number]
|
||||
|
||||
| Step | Action | Trigger Source | Expected (OS) [Doc A] | Expected (Plugin) [Doc C] | Actual Result | Notes | Result |
|
||||
| ---- | ------ | -------------- | ---------------------- | -------------------------- | ------------- | ----- | ------ |
|
||||
| 1 | Schedule alarm 2-5 minutes in future | Plugin | - | Alarm scheduled | ☐ | | ☐ |
|
||||
| 2 | Force kill via `adb shell am kill <package>` | User/OS | - | - | ☐ | | ☐ |
|
||||
| 3 | Wait for trigger time | OS | ✅ Alarm fires - [Doc A §2.1.1](./01-platform-capability-reference.md#211-alarms-survive-ui-kills-swipe-from-recents) | ✅ Notification displayed - [Doc C §1.1](./03-plugin-requirements.md#11-guarantees-by-platform) | ☐ | | ☐ |
|
||||
| 4 | Check logs | - | - | No errors | ☐ | | ☐ |
|
||||
|
||||
**Platform Behavior Reference**: [Doc A §2.1.1](./01-platform-capability-reference.md#211-alarms-survive-ui-kills-swipe-from-recents) - OS-guaranteed
|
||||
|
||||
---
|
||||
|
||||
#### Test 4: Device Reboot
|
||||
|
||||
**Preconditions**:
|
||||
- App installed and launched at least once
|
||||
- Alarm scheduled and verified in database
|
||||
- Boot receiver registered in manifest
|
||||
- Test device: [Device model, OS version]
|
||||
- App build: [Git commit hash or build number]
|
||||
|
||||
| Step | Action | Trigger Source | Expected (OS) [Doc A] | Expected (Plugin) [Doc C] | Actual Result | Notes | Result |
|
||||
| ---- | ------ | -------------- | ---------------------- | -------------------------- | ------------- | ----- | ------ |
|
||||
| 1 | Schedule alarm 10 minutes in future | Plugin | - | Alarm scheduled | ☐ | | ☐ |
|
||||
| 2 | Reboot device | User | - | - | ☐ | | ☐ |
|
||||
| 3 | Do NOT open app | - | ❌ Alarm does NOT fire - [Doc A §2.1.2](./01-platform-capability-reference.md#212-alarms-can-be-preserved-across-device-reboot) | ❌ No notification | ☐ | | ☐ |
|
||||
| 4 | Wait past scheduled time | - | ❌ No automatic firing | ❌ No notification | ☐ | | ☐ |
|
||||
| 5 | Open app manually | User | - | Plugin detects missed alarm - [Doc C §4.2](./03-plugin-requirements.md#42-detection-triggers) | ☐ | | ☐ |
|
||||
| 6 | Check missed alarm handling | Plugin | - | ✅ Missed alarm detected - [Doc C §4.3](./03-plugin-requirements.md#43-required-actions) | ☐ | | ☐ |
|
||||
| 7 | Check rescheduling | Plugin | - | ✅ Future alarms rescheduled - [Doc C §3.1.1](./03-plugin-requirements.md#311-boot-event-android-only) | ☐ | | ☐ |
|
||||
|
||||
**Code Reference**:
|
||||
- Boot receiver: `BootReceiver.kt` line 24
|
||||
- Rescheduling: `BootReceiver.kt` line 38+
|
||||
|
||||
**Platform Behavior Reference**: [Doc A §2.1.2](./01-platform-capability-reference.md#212-alarms-can-be-preserved-across-device-reboot) - Plugin-required
|
||||
|
||||
**Plugin Requirement Reference**: [Doc C §3.1.1](./03-plugin-requirements.md#311-boot-event-android-only) - Boot event recovery
|
||||
|
||||
---
|
||||
|
||||
#### Test 5: Android Force Stop
|
||||
|
||||
**Preconditions**:
|
||||
- App installed and launched at least once
|
||||
- Multiple alarms scheduled (past and future)
|
||||
- Test device: [Device model, OS version]
|
||||
- App build: [Git commit hash or build number]
|
||||
|
||||
| Step | Action | Trigger Source | Expected (OS) [Doc A] | Expected (Plugin) [Doc C] | Actual Result | Notes | Result |
|
||||
| ---- | ------ | -------------- | ---------------------- | -------------------------- | ------------- | ----- | ------ |
|
||||
| 1 | Schedule alarms (past and future) | Plugin | - | Alarms scheduled | ☐ | | ☐ |
|
||||
| 2 | Go to Settings → Apps → [App] → Force Stop | User | ❌ All alarms removed - [Doc A §2.2.1](./01-platform-capability-reference.md#221-you-cannot-survive-force-stop) | ❌ All alarms removed | ☐ | | ☐ |
|
||||
| 3 | Wait for trigger time | - | ❌ Alarm does NOT fire - [Doc A §2.2.1](./01-platform-capability-reference.md#221-you-cannot-survive-force-stop) | ❌ No notification | ☐ | | ☐ |
|
||||
| 4 | Open app again | User | - | Plugin detects force stop scenario - [Doc C §3.1.4](./03-plugin-requirements.md#314-force-stop-recovery-android-only) | ☐ | | ☐ |
|
||||
| 5 | Check recovery | Plugin | - | ✅ All past alarms marked as missed - [Doc C §3.1.4](./03-plugin-requirements.md#314-force-stop-recovery-android-only) | ☐ | | ☐ |
|
||||
| 6 | Check rescheduling | Plugin | - | ✅ All future alarms rescheduled - [Doc C §3.1.4](./03-plugin-requirements.md#314-force-stop-recovery-android-only) | ☐ | | ☐ |
|
||||
|
||||
**Platform Behavior Reference**: [Doc A §2.2.1](./01-platform-capability-reference.md#221-you-cannot-survive-force-stop) - Forbidden
|
||||
|
||||
**Plugin Requirement Reference**: [Doc C §3.1.4](./03-plugin-requirements.md#314-force-stop-recovery-android-only) - Force stop recovery
|
||||
|
||||
---
|
||||
|
||||
#### Test 6: Exact Alarm Permission (Android 12+)
|
||||
|
||||
**Preconditions**:
|
||||
- Android 12+ (API 31+) device
|
||||
- App installed and launched at least once
|
||||
- Test device: [Device model, OS version]
|
||||
- App build: [Git commit hash or build number]
|
||||
|
||||
| Step | Action | Trigger Source | Expected (OS) [Doc A] | Expected (Plugin) [Doc C] | Actual Result | Notes | Result |
|
||||
| ---- | ------ | -------------- | ---------------------- | -------------------------- | ------------- | ----- | ------ |
|
||||
| 1 | Revoke exact alarm permission | User | - | - | ☐ | | ☐ |
|
||||
| 2 | Attempt to schedule alarm | Plugin | - | Plugin requests permission - [Doc C §8.1.1](./03-plugin-requirements.md#811-permissions) | ☐ | | ☐ |
|
||||
| 3 | Check settings opened | Plugin | - | ✅ Settings opened | ☐ | | ☐ |
|
||||
| 4 | Grant permission | User | - | - | ☐ | | ☐ |
|
||||
| 5 | Schedule alarm | Plugin | - | ✅ Alarm scheduled | ☐ | | ☐ |
|
||||
| 6 | Verify alarm fires | OS | ✅ Alarm fires - [Doc A §5.2](./01-platform-capability-reference.md#52-android-s-exact-alarm-permission-decision-tree) | ✅ Notification displayed | ☐ | | ☐ |
|
||||
|
||||
**Code Reference**: `DailyNotificationPlugin.kt` line 1309, 1314-1324
|
||||
|
||||
**Platform Behavior Reference**: [Doc A §5.2](./01-platform-capability-reference.md#52-android-s-exact-alarm-permission-decision-tree) - Conditional
|
||||
|
||||
**Plugin Requirement Reference**: [Doc C §8.1.1](./03-plugin-requirements.md#811-permissions) - Permission handling
|
||||
|
||||
---
|
||||
|
||||
### 1.3 Persistence Investigation
|
||||
|
||||
| Item | Expected | Actual | Code Reference | Notes |
|
||||
| ---- | -------- | ------ | -------------- | ----- |
|
||||
| Alarm ID stored | ✅ Yes | ☐ | `DailyNotificationPlugin.kt` line 1393+ | |
|
||||
| Trigger time stored | ✅ Yes | ☐ | Room database | |
|
||||
| Repeat rule stored | ✅ Yes | ☐ | Schedule entity | |
|
||||
| Channel/priority stored | ✅ Yes | ☐ | NotificationContentEntity | |
|
||||
| Payload stored | ✅ Yes | ☐ | ContentCache | |
|
||||
| Time created/modified | ✅ Yes | ☐ | Entity timestamps | |
|
||||
|
||||
**Storage Location**: Room database (`DailyNotificationDatabase`)
|
||||
|
||||
---
|
||||
|
||||
### 1.4 Recovery Points Investigation
|
||||
|
||||
| Recovery Point | Expected Behavior | Actual Behavior | Code Reference | Notes |
|
||||
| -------------- | ----------------- | --------------- | -------------- | ----- |
|
||||
| Boot event | ✅ Reschedule all alarms | ☐ | `BootReceiver.kt` line 24 | |
|
||||
| App cold start | ✅ Detect missed alarms | ☐ | Check plugin initialization | |
|
||||
| App warm start | ✅ Verify active alarms | ☐ | Check plugin initialization | |
|
||||
| Background fetch return | ⚠️ May reschedule | ☐ | `FetchWorker.kt` | |
|
||||
| User taps notification | ✅ Launch app | ☐ | Notification intent | |
|
||||
|
||||
---
|
||||
|
||||
## 2. Required Baseline Scenarios
|
||||
|
||||
**All six baseline scenarios MUST be tested**:
|
||||
|
||||
1. ✅ **Swipe-kill** - Test 2 (Android), Test 2 (iOS)
|
||||
2. ✅ **OS low-RAM kill** - Test 3 (Android)
|
||||
3. ✅ **Reboot** - Test 4 (Android), Test 3 (iOS)
|
||||
4. ✅ **Force stop** - Test 5 (Android only)
|
||||
5. ✅ **Cold start** - See [Test 4 Step 5](./02-plugin-behavior-exploration.md#test-4-device-reboot) (Android), Test 4 (iOS)
|
||||
6. ✅ **Notification-tap resume** - See [Recovery Points §1.4](./02-plugin-behavior-exploration.md#14-recovery-points-investigation) (Both)
|
||||
|
||||
---
|
||||
|
||||
## 3. iOS Exploration
|
||||
|
||||
### 3.1 Code-Level Inspection Checklist
|
||||
|
||||
**Source Locations**:
|
||||
- Plugin: `ios/Plugin/`
|
||||
- Test App: `test-apps/ios-test-app/`
|
||||
- Alternative: Check `ios-2` branch
|
||||
|
||||
| Task | File/Function | Line | Status | Notes |
|
||||
| ---- | ------------- | ---- | ------ | ----- |
|
||||
| Locate main plugin class | `DailyNotificationPlugin.swift` | 506 | ☐ | `scheduleUserNotification()` |
|
||||
| Identify notification scheduling | `DailyNotificationScheduler.swift` | 133 | ☐ | `scheduleNotification()` |
|
||||
| Check UNUserNotificationCenter usage | `DailyNotificationScheduler.swift` | 185 | ☐ | `notificationCenter.add()` |
|
||||
| Check trigger types | `DailyNotificationScheduler.swift` | 172 | ☐ | `UNCalendarNotificationTrigger` |
|
||||
| Check BGTaskScheduler usage | `DailyNotificationPlugin.swift` | 495 | ☐ | `scheduleBackgroundFetch()` |
|
||||
| Check persistence | `DailyNotificationPlugin.swift` | 35 | ☐ | `storage: DailyNotificationStorage?` |
|
||||
| Check app launch recovery | `DailyNotificationPlugin.swift` | 42 | ☐ | `load()` method |
|
||||
|
||||
### 3.2 Behavior Testing Matrix
|
||||
|
||||
#### Test 1: Base Case
|
||||
|
||||
| Step | Action | Expected (OS) | Expected (Plugin) | Actual Result | Notes |
|
||||
| ---- | ------ | ------------- | ------------------ | ------------- | ----- |
|
||||
| 1 | Schedule notification 2-5 minutes in future | - | Notification scheduled | ☐ | |
|
||||
| 2 | Leave app backgrounded | - | - | ☐ | |
|
||||
| 3 | Wait for trigger time | ✅ Notification fires | ✅ Notification displayed | ☐ | |
|
||||
| 4 | Check logs | - | No errors | ☐ | |
|
||||
|
||||
**Code Reference**: `DailyNotificationScheduler.scheduleNotification()` line 133
|
||||
|
||||
**Platform Behavior**: See [Platform Reference §3.1.1](./01-platform-capability-reference.md#311-notifications-survive-app-termination)
|
||||
|
||||
---
|
||||
|
||||
#### Test 2: Swipe App Away
|
||||
|
||||
**Preconditions**:
|
||||
- App installed and launched at least once
|
||||
- Notification scheduled and verified
|
||||
- Test device: [Device model, OS version]
|
||||
- App build: [Git commit hash or build number]
|
||||
|
||||
| Step | Action | Trigger Source | Expected (OS) [Doc A] | Expected (Plugin) [Doc C] | Actual Result | Notes | Result |
|
||||
| ---- | ------ | -------------- | ---------------------- | -------------------------- | ------------- | ----- | ------ |
|
||||
| 1 | Schedule notification 2-5 minutes in future | Plugin | - | Notification scheduled | ☐ | | ☐ |
|
||||
| 2 | Swipe app away from app switcher | User | - | - | ☐ | | ☐ |
|
||||
| 3 | Wait for trigger time | OS | ✅ Notification fires (OS handles) - [Doc A §3.1.1](./01-platform-capability-reference.md#311-notifications-survive-app-termination) | ✅ Notification displayed - [Doc C §1.1](./03-plugin-requirements.md#11-guarantees-by-platform) | ☐ | | ☐ |
|
||||
| 4 | Check app state | OS | App terminated | App not running | ☐ | | ☐ |
|
||||
|
||||
**Platform Behavior Reference**: [Doc A §3.1.1](./01-platform-capability-reference.md#311-notifications-survive-app-termination) - OS-guaranteed
|
||||
|
||||
---
|
||||
|
||||
#### Test 3: Device Reboot
|
||||
|
||||
**Preconditions**:
|
||||
- App installed and launched at least once
|
||||
- Notification scheduled with calendar/time trigger
|
||||
- Test device: [Device model, OS version]
|
||||
- App build: [Git commit hash or build number]
|
||||
|
||||
| Step | Action | Trigger Source | Expected (OS) [Doc A] | Expected (Plugin) [Doc C] | Actual Result | Notes | Result |
|
||||
| ---- | ------ | -------------- | ---------------------- | -------------------------- | ------------- | ----- | ------ |
|
||||
| 1 | Schedule notification for future time | Plugin | - | Notification scheduled | ☐ | | ☐ |
|
||||
| 2 | Reboot device | User | - | - | ☐ | | ☐ |
|
||||
| 3 | Do NOT open app | OS | ✅ Notification fires (OS persists) - [Doc A §3.1.2](./01-platform-capability-reference.md#312-notifications-persist-across-device-reboot) | ✅ Notification displayed - [Doc C §1.1](./03-plugin-requirements.md#11-guarantees-by-platform) | ☐ | | ☐ |
|
||||
| 4 | Check notification timing | OS | ✅ On time (±180s tolerance) - [Doc A §6.1](./01-platform-capability-reference.md#61-notification-timing-accuracy) | ✅ On time | ☐ | | ☐ |
|
||||
|
||||
**Platform Behavior Reference**: [Doc A §3.1.2](./01-platform-capability-reference.md#312-notifications-persist-across-device-reboot) - OS-guaranteed
|
||||
|
||||
**Note**: Only calendar and time-based triggers persist. Location triggers do not - See [Doc A §3.1.2](./01-platform-capability-reference.md#312-notifications-persist-across-device-reboot)
|
||||
|
||||
---
|
||||
|
||||
#### Test 4: Hard Termination & Relaunch
|
||||
|
||||
| Step | Action | Expected (OS) | Expected (Plugin) | Actual Result | Notes |
|
||||
| ---- | ------ | ------------- | ------------------ | ------------- | ----- |
|
||||
| 1 | Schedule repeating notifications | - | Notifications scheduled | ☐ | |
|
||||
| 2 | Terminate app via Xcode/switcher | - | - | ☐ | |
|
||||
| 3 | Allow some triggers to occur | ✅ Notifications fire | ✅ Notifications displayed | ☐ | |
|
||||
| 4 | Reopen app | - | Plugin checks for missed events | ☐ | |
|
||||
| 5 | Check missed event detection | ⚠️ May detect | ☐ | Plugin-specific |
|
||||
| 6 | Check state recovery | ⚠️ May recover | ☐ | Plugin-specific |
|
||||
|
||||
**Platform Behavior**: OS-guaranteed for notifications; Plugin-guaranteed for missed event detection
|
||||
|
||||
---
|
||||
|
||||
#### Test 5: Background Execution Limits
|
||||
|
||||
| Step | Action | Expected (OS) | Expected (Plugin) | Actual Result | Notes |
|
||||
| ---- | ------ | ------------- | ------------------ | ------------- | ----- |
|
||||
| 1 | Schedule BGTaskScheduler task | - | Task scheduled | ☐ | |
|
||||
| 2 | Wait for system to execute | ⚠️ System-controlled | ⚠️ May not execute | ☐ | |
|
||||
| 3 | Check execution timing | ⚠️ Not guaranteed | ⚠️ Not guaranteed | ☐ | |
|
||||
| 4 | Check time budget | ⚠️ ~30 seconds | ⚠️ Limited time | ☐ | |
|
||||
|
||||
**Code Reference**: `DailyNotificationPlugin.scheduleBackgroundFetch()` line 495
|
||||
|
||||
**Platform Behavior**: Conditional (see [Platform Reference §3.1.3](./01-platform-capability-reference.md#313-background-tasks-for-prefetching))
|
||||
|
||||
---
|
||||
|
||||
### 3.3 Persistence Investigation
|
||||
|
||||
| Item | Expected | Actual | Code Reference | Notes |
|
||||
| ---- | -------- | ------ | -------------- | ----- |
|
||||
| Notification ID stored | ✅ Yes (in UNUserNotificationCenter) | ☐ | `UNNotificationRequest` | |
|
||||
| Plugin-side storage | ⚠️ May not exist | ☐ | `DailyNotificationStorage?` | |
|
||||
| Trigger time stored | ✅ Yes (in trigger) | ☐ | `UNCalendarNotificationTrigger` | |
|
||||
| Repeat rule stored | ✅ Yes (in trigger) | ☐ | `repeats: true/false` | |
|
||||
| Payload stored | ✅ Yes (in userInfo) | ☐ | `notificationContent.userInfo` | |
|
||||
|
||||
**Storage Location**:
|
||||
- Primary: UNUserNotificationCenter (OS-managed)
|
||||
- Secondary: Plugin storage (if implemented)
|
||||
|
||||
---
|
||||
|
||||
### 3.4 Recovery Points Investigation
|
||||
|
||||
| Recovery Point | Expected Behavior | Actual Behavior | Code Reference | Notes |
|
||||
| -------------- | ----------------- | --------------- | -------------- | ----- |
|
||||
| Boot event | ✅ Notifications fire automatically | ☐ | OS handles | |
|
||||
| App cold start | ⚠️ May detect missed notifications | ☐ | Check `load()` method | |
|
||||
| App warm start | ⚠️ May verify pending notifications | ☐ | Check plugin initialization | |
|
||||
| Background fetch | ⚠️ May reschedule | ☐ | `BGTaskScheduler` | |
|
||||
| User taps notification | ✅ App launched | ☐ | Notification action | |
|
||||
|
||||
---
|
||||
|
||||
## 4. Cross-Platform Comparison
|
||||
|
||||
### 3.1 Observed Behavior Summary
|
||||
|
||||
| Scenario | Android (Observed) | iOS (Observed) | Platform Difference |
|
||||
| -------- | ------------------ | -------------- | ------------------- |
|
||||
| Swipe/termination | ☐ | ☐ | Both should work |
|
||||
| Reboot | ☐ | ☐ | iOS auto, Android manual |
|
||||
| Force stop | ☐ | N/A | Android only |
|
||||
| App code on trigger | ☐ | ☐ | Android yes, iOS no |
|
||||
| Background execution | ☐ | ☐ | Android more flexible |
|
||||
|
||||
---
|
||||
|
||||
## 5. Findings & Gaps
|
||||
|
||||
### 4.1 Android Gaps
|
||||
|
||||
| Gap | Severity | Description | Recommendation |
|
||||
| --- | -------- | ----------- | -------------- |
|
||||
| Boot recovery | ☐ Critical/Major/Minor/Expected | Does plugin reschedule on boot? | Implement if missing |
|
||||
| Missed alarm detection | ☐ Critical/Major/Minor/Expected | Does plugin detect missed alarms? | Implement if missing |
|
||||
| Force stop recovery | ☐ Critical/Major/Minor/Expected | Does plugin recover after force stop? | Implement if missing |
|
||||
| Persistence completeness | ☐ Critical/Major/Minor/Expected | Are all required fields persisted? | Verify and add if missing |
|
||||
|
||||
**Severity Classification**:
|
||||
- **Critical**: Breaks plugin guarantee (see [Doc C §1.1](./03-plugin-requirements.md#11-guarantees-by-platform))
|
||||
- **Major**: Unexpected but recoverable (plugin works but behavior differs from expected)
|
||||
- **Minor**: Non-blocking deviation (cosmetic or edge case)
|
||||
- **Expected**: Platform limitation (documented in [Doc A](./01-platform-capability-reference.md))
|
||||
|
||||
### 4.2 iOS Gaps
|
||||
|
||||
| Gap | Severity | Description | Recommendation |
|
||||
| --- | -------- | ----------- | -------------- |
|
||||
| Missed notification detection | ☐ Critical/Major/Minor/Expected | Does plugin detect missed notifications? | Implement if missing |
|
||||
| Plugin-side persistence | ☐ Critical/Major/Minor/Expected | Does plugin persist state separately? | Consider if needed |
|
||||
| Background task reliability | ☐ Critical/Major/Minor/Expected | Can plugin rely on BGTaskScheduler? | Document limitations |
|
||||
|
||||
**Severity Classification**: Same as Android (see above).
|
||||
|
||||
---
|
||||
|
||||
## 6. Deliverables from This Exploration
|
||||
|
||||
After completing this exploration, generate:
|
||||
|
||||
1. **Completed test results** - All checkboxes filled, actual results documented
|
||||
2. **Gap analysis** - Documented limitations and gaps
|
||||
3. **Annotated code pointers** - Code locations with findings
|
||||
4. **Open Questions / TODOs** - Unresolved issues
|
||||
|
||||
---
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Platform Capability Reference](./01-platform-capability-reference.md) - OS-level facts
|
||||
- [Plugin Requirements](./03-plugin-requirements.md) - Requirements based on findings
|
||||
- [Unified Alarm Directive](./000-UNIFIED-ALARM-DIRECTIVE.md) - Master coordination document
|
||||
|
||||
---
|
||||
|
||||
## Notes for Explorers
|
||||
|
||||
* Fill in checkboxes (☐) as you complete each test
|
||||
* Document actual results in "Actual Result" columns
|
||||
* Add notes for any unexpected behavior
|
||||
* Reference code locations when documenting findings
|
||||
* Update "Findings & Gaps" section as you discover issues
|
||||
* Use platform capability reference to understand expected OS behavior
|
||||
* Link to Platform Reference sections instead of duplicating platform facts
|
||||
|
||||
1047
docs/alarms/03-plugin-requirements.md
Normal file
1047
docs/alarms/03-plugin-requirements.md
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,12 @@
|
||||
# Android Alarm Persistence, Recovery, and Limitations
|
||||
|
||||
**⚠️ DEPRECATED**: This document has been superseded by [01-platform-capability-reference.md](./alarms/01-platform-capability-reference.md) as part of the unified alarm documentation structure.
|
||||
|
||||
**See**: [Unified Alarm Directive](./alarms/000-UNIFIED-ALARM-DIRECTIVE.md) for the new documentation structure.
|
||||
|
||||
**Author**: Matthew Raymer
|
||||
**Date**: November 2025
|
||||
**Status**: Engineering Directive - Active Reference
|
||||
**Status**: **DEPRECATED** - Superseded by unified structure
|
||||
|
||||
## Purpose
|
||||
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
**Author**: Matthew Raymer
|
||||
**Date**: November 2025
|
||||
**Status**: Phase 1 - Minimal Viable Recovery
|
||||
**Version**: 1.0.0
|
||||
**Version**: 1.0.0
|
||||
**Last Synced With Plugin Version**: v1.1.0
|
||||
|
||||
**Implements**: [Plugin Requirements §3.1.2 - App Cold Start](./alarms/03-plugin-requirements.md#312-app-cold-start)
|
||||
|
||||
## Purpose
|
||||
|
||||
@@ -12,6 +15,8 @@ Phase 1 implements **minimal viable app launch recovery** for cold start scenari
|
||||
**Scope**: Phase 1 implements **cold start recovery only**. Force stop detection, warm start optimization, and boot receiver enhancements are **out of scope** for this phase and deferred to later phases.
|
||||
|
||||
**Reference**:
|
||||
- [Plugin Requirements](./alarms/03-plugin-requirements.md) - Requirements this phase implements
|
||||
- [Platform Capability Reference](./alarms/01-platform-capability-reference.md) - OS-level facts
|
||||
- [Full Implementation Directive](./android-implementation-directive.md) - Complete scope
|
||||
- [Phase 2: Force Stop Recovery](./android-implementation-directive-phase2.md) - Next phase
|
||||
- [Phase 3: Boot Receiver Enhancement](./android-implementation-directive-phase3.md) - Final phase
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
**Author**: Matthew Raymer
|
||||
**Date**: November 2025
|
||||
**Status**: Phase 2 - Force Stop Recovery
|
||||
**Version**: 1.0.0
|
||||
**Version**: 1.0.0
|
||||
**Last Synced With Plugin Version**: v1.1.0
|
||||
|
||||
**Implements**: [Plugin Requirements §3.1.4 - Force Stop Recovery](./alarms/03-plugin-requirements.md#314-force-stop-recovery-android-only)
|
||||
|
||||
## Purpose
|
||||
|
||||
@@ -15,7 +18,11 @@ Phase 2 implements **force stop detection and comprehensive recovery**. This han
|
||||
|
||||
**Scope**: Force stop detection, scenario differentiation, and full alarm recovery.
|
||||
|
||||
**Reference**: See [Phase 1](./android-implementation-directive-phase1.md) for cold start recovery, [Full Implementation Directive](./android-implementation-directive.md) for complete scope.
|
||||
**Reference**:
|
||||
- [Plugin Requirements](./alarms/03-plugin-requirements.md) - Requirements this phase implements
|
||||
- [Platform Capability Reference](./alarms/01-platform-capability-reference.md) - OS-level facts
|
||||
- [Phase 1](./android-implementation-directive-phase1.md) - Prerequisite
|
||||
- [Full Implementation Directive](./android-implementation-directive.md) - Complete scope
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
**Author**: Matthew Raymer
|
||||
**Date**: November 2025
|
||||
**Status**: Phase 3 - Boot Recovery Enhancement
|
||||
**Version**: 1.0.0
|
||||
**Version**: 1.0.0
|
||||
**Last Synced With Plugin Version**: v1.1.0
|
||||
|
||||
**Implements**: [Plugin Requirements §3.1.1 - Boot Event](./alarms/03-plugin-requirements.md#311-boot-event-android-only)
|
||||
|
||||
## Purpose
|
||||
|
||||
@@ -15,7 +18,12 @@ Phase 3 enhances the **boot receiver** to detect and handle missed alarms during
|
||||
|
||||
**Dependencies**: Boot receiver behavior assumes that Phase 1 and Phase 2 definitions of 'missed alarm', 'next occurrence', and `Schedule`/`NotificationContentEntity` semantics are already in place.
|
||||
|
||||
**Reference**: See [Phase 1](./android-implementation-directive-phase1.md) and [Phase 2](./android-implementation-directive-phase2.md) for app launch recovery, [Full Implementation Directive](./android-implementation-directive.md) for complete scope.
|
||||
**Reference**:
|
||||
- [Plugin Requirements](./alarms/03-plugin-requirements.md) - Requirements this phase implements
|
||||
- [Platform Capability Reference](./alarms/01-platform-capability-reference.md) - OS-level facts
|
||||
- [Phase 1](./android-implementation-directive-phase1.md) - Prerequisite
|
||||
- [Phase 2](./android-implementation-directive-phase2.md) - Prerequisite
|
||||
- [Full Implementation Directive](./android-implementation-directive.md) - Complete scope
|
||||
|
||||
**Boot vs App Launch Recovery**:
|
||||
|
||||
|
||||
@@ -15,20 +15,27 @@ This directive provides **descriptive overview and integration guidance** for An
|
||||
|
||||
**⚠️ CRITICAL**: This document is **descriptive and integrative**. The **normative implementation instructions** are in the Phase 1–3 directives below. **If any code or behavior in this file conflicts with a Phase directive, the Phase directive wins.**
|
||||
|
||||
**Reference**: See [Plugin Requirements](./alarms/03-plugin-requirements.md) for requirements that Phase directives implement.
|
||||
|
||||
**Reference**: See [Exploration Findings](./exploration-findings-initial.md) for gap analysis.
|
||||
|
||||
**⚠️ IMPORTANT**: For implementation, use the phase-specific directives (these are the canonical source of truth):
|
||||
|
||||
- **[Phase 1: Cold Start Recovery](./android-implementation-directive-phase1.md)** - Minimal viable recovery
|
||||
- Implements: [Plugin Requirements §3.1.2](./alarms/03-plugin-requirements.md#312-app-cold-start)
|
||||
- Explicit acceptance criteria, rollback safety, data integrity checks
|
||||
- **Start here** for fastest implementation
|
||||
|
||||
- **[Phase 2: Force Stop Detection & Recovery](./android-implementation-directive-phase2.md)** - Comprehensive force stop handling
|
||||
- Implements: [Plugin Requirements §3.1.4](./alarms/03-plugin-requirements.md#314-force-stop-recovery-android-only)
|
||||
- Prerequisite: Phase 1 complete
|
||||
|
||||
- **[Phase 3: Boot Receiver Missed Alarm Handling](./android-implementation-directive-phase3.md)** - Boot recovery enhancement
|
||||
- Implements: [Plugin Requirements §3.1.1](./alarms/03-plugin-requirements.md#311-boot-event-android-only)
|
||||
- Prerequisites: Phase 1 and Phase 2 complete
|
||||
|
||||
**See Also**: [Unified Alarm Directive](./alarms/000-UNIFIED-ALARM-DIRECTIVE.md) for master coordination document.
|
||||
|
||||
---
|
||||
|
||||
## 1. Implementation Overview
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
# Platform Capability Reference: Android & iOS Alarm/Notification Behavior
|
||||
|
||||
**⚠️ DEPRECATED**: This document has been superseded by [01-platform-capability-reference.md](./alarms/01-platform-capability-reference.md) as part of the unified alarm documentation structure.
|
||||
|
||||
**See**: [Unified Alarm Directive](./alarms/000-UNIFIED-ALARM-DIRECTIVE.md) for the new documentation structure.
|
||||
|
||||
**Author**: Matthew Raymer
|
||||
**Date**: November 2025
|
||||
**Status**: Platform Reference - Stable
|
||||
**Status**: **DEPRECATED** - Superseded by unified structure
|
||||
|
||||
## Purpose
|
||||
|
||||
|
||||
Reference in New Issue
Block a user