# Android Implementation Directive – Phase 3  
## Boot-Time Recovery (Device Reboot / System Restart)

**Plugin:** Daily Notification Plugin  
**Author:** Matthew Raymer  
**Applies to:** Android Plugin (Kotlin), Capacitor Bridge  
**Related Docs:**  
- `03-plugin-requirements.md`  
- `000-UNIFIED-ALARM-DIRECTIVE.md`  
- `android-implementation-directive-phase1.md`  
- `android-implementation-directive-phase2.md`  
- `ACTIVATION-GUIDE.md`

---

## 1. Purpose

Phase 3 introduces **Boot-Time Recovery**, which restores daily notifications after:

- Device reboot  
- OS restart  
- Update-related restart  
- App not opened after reboot (silent recovery)  

Android clears **all alarms** on reboot.  
Therefore, if our plugin is not actively rescheduling on boot, the user will miss all daily notifications until they manually launch the app.

Phase 3 ensures:

1. Schedules stored in SQLite survive reboot  
2. Alarms are fully reconstructed  
3. No duplication / double-scheduling  
4. Boot behavior avoids unnecessary heavy recovery  
5. Recovery occurs even if the user does **not** manually open the app

---

## 2. Boot-Time Recovery Flow

### Trigger:

`BOOT_COMPLETED` broadcast received  
→ Plugin's Boot Receiver invoked  
→ Recovery logic executed with `scenario=BOOT`

### Recovery Steps

1. **Load all schedules** from SQLite (`NotificationRepository.getAllSchedules()`)

2. **For each schedule:**
   - Calculate next runtime based on cron expression
   - Compare with current time

3. **If the next scheduled time is in the future:**
   - Recreate alarm with `setAlarmClock`
   - Log:  
     `Rescheduled alarm: <id> for <ts>`

4. **If schedule was *in the past* at boot time:**
   - Mark as missed
   - Schedule next run according to cron rules

5. **If no schedules found:**
   - Quiet exit, log only one line:
     `BOOT: No schedules found`

6. **Safeties:**
   - Boot recovery must **not** modify Plugin Settings  
   - Must not regenerate Fetcher configuration  
   - Must not overwrite database records  

---

## 3. Required Android Components

### 3.1 Boot Receiver

```xml
<receiver
    android:name=".BootReceiver"
    android:enabled="true"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>
```

### 3.2 Kotlin Class

```kotlin
class BootReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent?) {
        if (intent?.action != Intent.ACTION_BOOT_COMPLETED) return

        ReactivationManager.runBootRecovery(context)
    }
}
```

---

## 4. ReactivationManager – Boot Logic

### Method Signature

```kotlin
fun runBootRecovery(context: Context)
```

### Required Logging (canonical)

```
DNP-REACTIVATION: Starting boot recovery
DNP-REACTIVATION: Loaded <N> schedules from DB
DNP-REACTIVATION: Rescheduled alarm: <id> for <ts>
DNP-REACTIVATION: Marked missed notification: <id>
DNP-REACTIVATION: Boot recovery complete: missed=X, rescheduled=Y, errors=Z
```

### Required Fields

* `scenario=BOOT`
* `missed`
* `rescheduled`
* `verified` **MUST BE 0** (boot has no verification phase)

---

## 5. Constraints & Guardrails

1. **No plugin initialization**
   Boot must *not* require running the app UI.

2. **No heavy processing**
   * limit to 2 seconds
   * use the same timeout guard as Phase 2

3. **No scheduling duplicates**
   * Must detect existing AlarmManager entries
   * Boot always clears them, so all reschedules should be fresh

4. **App does not need to be opened**
   * Entire recovery must run in background context

5. **Idempotency**
   * Running twice should produce identical logs

---

## 6. Implementation Checklist

### Mandatory

* [ ] BootReceiver included
* [ ] Manifest entry added
* [ ] `runBootRecovery()` implemented
* [ ] Scenario logged as `BOOT`
* [ ] All alarms recreated
* [ ] Timeout protection
* [ ] No modifications to preferences or plugin settings

### Optional

* [ ] Additional telemetry for analytics
* [ ] Optional debug toast for dev builds only

---

## 7. Expected Output Examples

### Example 1 – Normal Boot (future alarms exist)

```
DNP-REACTIVATION: Starting boot recovery
DNP-REACTIVATION: Loaded 2 schedules from DB
DNP-REACTIVATION: Rescheduled alarm: daily_1764233911265 for 1764236120000
DNP-REACTIVATION: Rescheduled alarm: daily_1764233465343 for 1764233700000
DNP-REACTIVATION: Boot recovery complete: missed=0, rescheduled=2, errors=0
```

### Example 2 – Schedules present but some in past

```
Marked missed notification: daily_1764233300000
Rescheduled alarm: daily_1764233300000 for next day
```

### Example 3 – No schedules

```
DNP-REACTIVATION: BOOT: No schedules found
```

---

## 8. Status

| Item                 | Status                           |
| -------------------- | -------------------------------- |
| Directive            | **Complete**                     |
| Implementation       | ☐ Pending / ✅ **Complete** (plugin v1.2+)      |
| Emulator Test Script | Ready (`test-phase3.sh`)         |
| Verification Doc     | Ready (`PHASE3-VERIFICATION.md`) |

---

## 9. Related Documentation

- [Unified Alarm Directive](./alarms/000-UNIFIED-ALARM-DIRECTIVE.md) - Master coordination document
- [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
- [Phase 3 Emulator Testing](./alarms/PHASE3-EMULATOR-TESTING.md) - Test procedures
- [Phase 3 Verification](./alarms/PHASE3-VERIFICATION.md) - Verification report

---

**Status**: Directive complete, ready for implementation  
**Last Updated**: November 2025
