- Add platform capability reference (Android & iOS OS-level facts) - Add plugin behavior exploration template (executable test matrices) - Add plugin requirements & implementation directive - Add Android-specific implementation directive with detailed test procedures - Add exploration findings from code inspection - Add improvement directive for refining documentation structure - Add Android alarm persistence directive (OS capabilities) All documents include: - File locations, function references, and line numbers - Detailed test procedures with ADB commands - Cross-platform comparisons - Implementation checklists and code examples
16 KiB
Plugin Behavior Exploration Template
Author: Matthew Raymer
Date: November 2025
Status: Active Exploration Template
Purpose
This document provides an executable template for exploring and documenting the current plugin's alarm/schedule/notification behavior on Android and iOS.
Use this template to:
- Test plugin behavior across different scenarios
- Document expected vs actual results
- Identify gaps between current behavior and platform capabilities
- Generate findings for the Plugin Requirements document
Reference: See Platform Capability Reference for OS-level facts.
0. Quick Reference: Platform Capabilities
Android: See Platform Capability Reference - Android Section
iOS: See Platform Capability Reference - iOS Section
Key Differences:
- Android: Alarms wiped on reboot; must reschedule
- iOS: Notifications persist across reboot automatically
- Android: App code runs when alarm fires
- iOS: App code does NOT run when notification fires (unless user interacts)
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 | Expected (OS) | Expected (Plugin) | Actual Result | Notes |
|---|---|---|---|---|---|
| 1 | Schedule alarm 2 minutes in future | - | Alarm scheduled | ☐ | |
| 2 | Leave app in foreground/background | - | - | ☐ | |
| 3 | Wait for trigger time | Alarm fires | Notification displayed | ☐ | |
| 4 | Check logs | - | No errors | ☐ |
Code Reference: NotifyReceiver.scheduleExactNotification() line 92
Test 2: Swipe from Recents
| Step | Action | Expected (OS) | Expected (Plugin) | Actual Result | Notes |
|---|---|---|---|---|---|
| 1 | Schedule alarm 2-5 minutes in future | - | Alarm scheduled | ☐ | |
| 2 | Swipe app away from recents | - | - | ☐ | |
| 3 | Wait for trigger time | ✅ Alarm fires (OS resurrects process) | ✅ Notification displayed | ☐ | |
| 4 | Check app state on wake | Cold start | App process recreated | ☐ | |
| 5 | Check logs | - | No errors | ☐ |
Code Reference: NotifyReceiver.scheduleExactNotification() uses setAlarmClock() line 219
Platform Behavior: OS-guaranteed (Android AlarmManager)
Test 3: OS Kill (Memory Pressure)
| Step | Action | Expected (OS) | Expected (Plugin) | Actual Result | Notes |
|---|---|---|---|---|---|
| 1 | Schedule alarm 2-5 minutes in future | - | Alarm scheduled | ☐ | |
| 2 | Force kill via adb shell am kill <package> |
- | - | ☐ | |
| 3 | Wait for trigger time | ✅ Alarm fires | ✅ Notification displayed | ☐ | |
| 4 | Check logs | - | No errors | ☐ |
Platform Behavior: OS-guaranteed (Android AlarmManager)
Test 4: Device Reboot
| Step | Action | Expected (OS) | Expected (Plugin) | Actual Result | Notes |
|---|---|---|---|---|---|
| 1 | Schedule alarm 10 minutes in future | - | Alarm scheduled | ☐ | |
| 2 | Reboot device | - | - | ☐ | |
| 3 | Do NOT open app | ❌ Alarm does NOT fire | ❌ No notification | ☐ | |
| 4 | Wait past scheduled time | ❌ No automatic firing | ❌ No notification | ☐ | |
| 5 | Open app manually | - | Plugin detects missed alarm | ☐ | |
| 6 | Check missed alarm handling | - | ✅ Missed alarm detected | ☐ | |
| 7 | Check rescheduling | - | ✅ Future alarms rescheduled | ☐ |
Code Reference:
- Boot receiver:
BootReceiver.ktline 24 - Rescheduling:
BootReceiver.ktline 38+
Platform Behavior: Plugin-guaranteed (must implement boot receiver)
Expected Plugin Behavior: Plugin must reschedule from database on boot
Test 5: Android Force Stop
| Step | Action | Expected (OS) | Expected (Plugin) | Actual Result | Notes |
|---|---|---|---|---|---|
| 1 | Schedule alarm | - | Alarm scheduled | ☐ | |
| 2 | Go to Settings → Apps → [App] → Force Stop | ❌ All alarms removed | ❌ All alarms removed | ☐ | |
| 3 | Wait for trigger time | ❌ Alarm does NOT fire | ❌ No notification | ☐ | |
| 4 | Open app again | - | Plugin detects missed alarm | ☐ | |
| 5 | Check recovery | - | ✅ Missed alarm detected | ☐ | |
| 6 | Check rescheduling | - | ✅ Future alarms rescheduled | ☐ |
Platform Behavior: Not allowed (Android hard kill)
Expected Plugin Behavior: Plugin must detect and recover on app restart
Test 6: Exact Alarm Permission (Android 12+)
| Step | Action | Expected (OS) | Expected (Plugin) | Actual Result | Notes |
|---|---|---|---|---|---|
| 1 | Revoke exact alarm permission | - | - | ☐ | |
| 2 | Attempt to schedule alarm | - | Plugin requests permission | ☐ | |
| 3 | Check settings opened | - | ✅ Settings opened | ☐ | |
| 4 | Grant permission | - | - | ☐ | |
| 5 | Schedule alarm | - | ✅ Alarm scheduled | ☐ | |
| 6 | Verify alarm fires | ✅ Alarm fires | ✅ Notification displayed | ☐ |
Code Reference: DailyNotificationPlugin.kt line 1309, 1314-1324
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. iOS Exploration
2.1 Code-Level Inspection Checklist
Source Locations:
- Plugin:
ios/Plugin/ - Test App:
test-apps/ios-test-app/ - Alternative: Check
ios-2branch
| 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 |
2.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
Test 2: Swipe App Away
| Step | Action | Expected (OS) | Expected (Plugin) | Actual Result | Notes |
|---|---|---|---|---|---|
| 1 | Schedule notification 2-5 minutes in future | - | Notification scheduled | ☐ | |
| 2 | Swipe app away from app switcher | - | - | ☐ | |
| 3 | Wait for trigger time | ✅ Notification fires (OS handles) | ✅ Notification displayed | ☐ | |
| 4 | Check app state | App terminated | App not running | ☐ |
Platform Behavior: OS-guaranteed (iOS UNUserNotificationCenter)
Test 3: Device Reboot
| Step | Action | Expected (OS) | Expected (Plugin) | Actual Result | Notes |
|---|---|---|---|---|---|
| 1 | Schedule notification for future time | - | Notification scheduled | ☐ | |
| 2 | Reboot device | - | - | ☐ | |
| 3 | Do NOT open app | ✅ Notification fires (OS persists) | ✅ Notification displayed | ☐ | |
| 4 | Check notification timing | ✅ On time (±180s tolerance) | ✅ On time | ☐ |
Platform Behavior: OS-guaranteed (iOS persists calendar/time triggers)
Note: Only calendar and time-based triggers persist. Location triggers do not.
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: System-controlled (not guaranteed)
2.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)
2.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 |
3. 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 |
4. Findings & Gaps
4.1 Android Gaps
| Gap | Severity | Description | Recommendation |
|---|---|---|---|
| Boot recovery | ☐ High/Medium/Low | Does plugin reschedule on boot? | Implement if missing |
| Missed alarm detection | ☐ High/Medium/Low | Does plugin detect missed alarms? | Implement if missing |
| Force stop recovery | ☐ High/Medium/Low | Does plugin recover after force stop? | Implement if missing |
| Persistence completeness | ☐ High/Medium/Low | Are all required fields persisted? | Verify and add if missing |
4.2 iOS Gaps
| Gap | Severity | Description | Recommendation |
|---|---|---|---|
| Missed notification detection | ☐ High/Medium/Low | Does plugin detect missed notifications? | Implement if missing |
| Plugin-side persistence | ☐ High/Medium/Low | Does plugin persist state separately? | Consider if needed |
| Background task reliability | ☐ High/Medium/Low | Can plugin rely on BGTaskScheduler? | Document limitations |
5. Deliverables from This Exploration
After completing this exploration, generate:
- ALARMS_BEHAVIOR_MATRIX.md - Completed test results
- PLUGIN_ALARM_LIMITATIONS.md - Documented limitations and gaps
- Annotated code pointers - Code locations with findings
- Open Questions / TODOs - Unresolved issues
Related Documentation
- Platform Capability Reference - OS-level facts
- Plugin Requirements & Implementation - Requirements based on findings
- Improve Alarm Directives - Improvement directive
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