Files
daily-notification-plugin/docs/alarms/02-plugin-behavior-exploration.md
Matthew Raymer bd842c6ef8 [ALARM-DOCS] fix(docs): remove duplicate status matrix and fix cross-references
Remove duplicate status matrix from Section 3.3 and consolidate to Section 11
as single source of truth. Fix all section number references throughout
documentation.

Changes:
- Remove duplicate status matrix table from Section 3.3
- Update all references from "Section 3.3" and "Section 10" to "Section 11"
- Fix phase directive paths to use consistent ../ prefix format
- Fix P1 path typo (missing "directive" in filename)
- Update Doc C status in matrix to reflect completion
- Remove duplicate text in Doc B baseline scenarios
- Remove self-referencing links in Doc B

All status matrix references now point to Section 11, eliminating confusion
about which matrix is authoritative.
2025-11-27 07:34:47 +00:00

24 KiB

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. All expected plugin behavior must reference Doc C.

Reference:


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

For plugin requirements: See Doc C - Plugin Requirements

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


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 ✅ Notification displayed - Doc C §1.1 ☐ ☐
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 - 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 ✅ Notification displayed - Doc C §1.1 ☐ ☐
4 Check logs - - No errors ☐ ☐

Platform Behavior Reference: Doc A §2.1.1 - 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 ❌ 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 ☐ ☐
6 Check missed alarm handling Plugin - ✅ Missed alarm detected - Doc C §4.3 ☐ ☐
7 Check rescheduling Plugin - ✅ Future alarms rescheduled - Doc C §3.1.1 ☐ ☐

Code Reference:

  • Boot receiver: BootReceiver.kt line 24
  • Rescheduling: BootReceiver.kt line 38+

Platform Behavior Reference: Doc A §2.1.2 - Plugin-required

Plugin Requirement Reference: Doc C §3.1.1 - 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 ❌ All alarms removed ☐ ☐
3 Wait for trigger time - ❌ Alarm does NOT fire - Doc A §2.2.1 ❌ No notification ☐ ☐
4 Open app again User - Plugin detects force stop scenario - Doc C §3.1.4 ☐ ☐
5 Check recovery Plugin - ✅ All past alarms marked as missed - Doc C §3.1.4 ☐ ☐
6 Check rescheduling Plugin - ✅ All future alarms rescheduled - Doc C §3.1.4 ☐ ☐

Platform Behavior Reference: Doc A §2.2.1 - Forbidden

Plugin Requirement Reference: Doc C §3.1.4 - 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 ☐ ☐
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 ✅ Notification displayed ☐ ☐

Code Reference: DailyNotificationPlugin.kt line 1309, 1314-1324

Platform Behavior Reference: Doc A §5.2 - Conditional

Plugin Requirement Reference: Doc C §8.1.1 - 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 - Test 4 Step 5 (Android), Test 4 (iOS)
  6. ✅ Notification-tap resume - Recovery Points §1.4 (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


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 ✅ Notification displayed - Doc C §1.1 ☐ ☐
4 Check app state OS App terminated App not running ☐ ☐

Platform Behavior Reference: Doc A §3.1.1 - 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 ✅ Notification displayed - Doc C §1.1 ☐ ☐
4 Check notification timing OS ✅ On time (±180s tolerance) - Doc A §6.1 ✅ On time ☐ ☐

Platform Behavior Reference: Doc A §3.1.2 - OS-guaranteed

Note: Only calendar and time-based triggers persist. Location triggers do not - See Doc A §3.1.2


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)


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)
  • 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)

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


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