docs: add comprehensive testing and recovery documentation
- Add app-startup-recovery-solution.md with technical deep dive - Add boot-receiver-testing-guide.md with Android 10+ fixes - Add notification-testing-procedures.md with manual testing steps - Add reboot-testing-procedure.md with automated testing - Add reboot-testing-steps.md with quick reference guide - Add testing-quick-reference.md with common scenarios Documentation covers: - Boot receiver implementation and Direct Boot handling - App startup recovery as fallback mechanism - Comprehensive testing procedures for all scenarios - Troubleshooting guides for common issues - Performance metrics and success criteria - Production deployment best practices This provides complete documentation for the notification system including both boot receiver and app startup recovery approaches.
This commit is contained in:
463
docs/reboot-testing-procedure.md
Normal file
463
docs/reboot-testing-procedure.md
Normal file
@@ -0,0 +1,463 @@
|
||||
# Reboot Testing Procedure for DailyNotification Plugin
|
||||
|
||||
## Overview
|
||||
|
||||
This document provides a comprehensive procedure for testing notification recovery after device reboots. The DailyNotification plugin implements a robust reboot recovery system that restores scheduled notifications after system events.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Android device or emulator with ADB enabled
|
||||
- DailyNotification app installed
|
||||
- ADB tools installed on development machine
|
||||
- Notification permissions granted
|
||||
- Boot receiver permissions granted
|
||||
|
||||
## Reboot Recovery System
|
||||
|
||||
### How It Works
|
||||
|
||||
1. **Boot Receiver Registration**: The `BootReceiver` is registered in `AndroidManifest.xml` to listen for:
|
||||
- `BOOT_COMPLETED` - Device boot completion
|
||||
- `MY_PACKAGE_REPLACED` - App update
|
||||
- `PACKAGE_REPLACED` - Any package update
|
||||
|
||||
2. **Recovery Process**: When triggered, the boot receiver:
|
||||
- Initializes the `DailyNotificationRebootRecoveryManager`
|
||||
- Loads stored notification data from SharedPreferences
|
||||
- Reschedules all pending notifications
|
||||
- Validates notification integrity
|
||||
|
||||
3. **Data Persistence**: Notification data is stored in:
|
||||
- SharedPreferences for notification content
|
||||
- AlarmManager for scheduling
|
||||
- Internal storage for recovery metadata
|
||||
|
||||
## Manual Reboot Testing Procedure
|
||||
|
||||
### Test 1: Basic Reboot Recovery
|
||||
|
||||
**Objective**: Verify notifications are restored after device reboot
|
||||
|
||||
**Steps**:
|
||||
1. **Schedule Notification**:
|
||||
```bash
|
||||
# Launch app
|
||||
adb shell am start -n com.timesafari.dailynotification/.MainActivity
|
||||
```
|
||||
- Tap "Test Notification" button
|
||||
- Verify notification scheduled for 5 minutes from now
|
||||
- Note the scheduled time
|
||||
|
||||
2. **Verify Alarm is Scheduled**:
|
||||
```bash
|
||||
# Check scheduled alarms
|
||||
adb shell "dumpsys alarm | grep timesafari"
|
||||
```
|
||||
- Should show scheduled alarm with correct timestamp
|
||||
|
||||
3. **Reboot Device**:
|
||||
```bash
|
||||
# Reboot device
|
||||
adb reboot
|
||||
```
|
||||
- Wait for device to fully boot (2-3 minutes)
|
||||
- Wait for boot animation to complete
|
||||
|
||||
4. **Verify Recovery**:
|
||||
```bash
|
||||
# Check if app recovered notifications
|
||||
adb logcat -d | grep -i "bootreceiver\|recovery"
|
||||
```
|
||||
- Look for "Device boot completed - restoring notifications"
|
||||
- Look for "Notification recovery completed successfully"
|
||||
|
||||
5. **Verify Alarm Restored**:
|
||||
```bash
|
||||
# Check if alarm was restored
|
||||
adb shell "dumpsys alarm | grep timesafari"
|
||||
```
|
||||
- Should show the same scheduled alarm
|
||||
|
||||
6. **Wait for Notification**:
|
||||
- Wait for the originally scheduled time
|
||||
- Check notification panel for the test notification
|
||||
|
||||
**Expected Result**: Notification appears at the originally scheduled time
|
||||
|
||||
### Test 2: App Update Recovery
|
||||
|
||||
**Objective**: Verify notifications are restored after app update
|
||||
|
||||
**Steps**:
|
||||
1. **Schedule Notification**:
|
||||
- Schedule a notification for 5 minutes from now
|
||||
- Verify it's scheduled correctly
|
||||
|
||||
2. **Update App**:
|
||||
```bash
|
||||
# Build and install updated app
|
||||
cd android && ./gradlew assembleDebug
|
||||
adb install -r app/build/outputs/apk/debug/app-debug.apk
|
||||
```
|
||||
|
||||
3. **Verify Recovery**:
|
||||
```bash
|
||||
# Check recovery logs
|
||||
adb logcat -d | grep -i "package.*replaced\|recovery"
|
||||
```
|
||||
- Look for "Our app was updated - restoring notifications"
|
||||
|
||||
4. **Verify Alarm Restored**:
|
||||
```bash
|
||||
# Check if alarm was restored
|
||||
adb shell "dumpsys alarm | grep timesafari"
|
||||
```
|
||||
|
||||
5. **Wait for Notification**:
|
||||
- Wait for the scheduled time
|
||||
- Verify notification appears
|
||||
|
||||
**Expected Result**: Notification appears after app update
|
||||
|
||||
### Test 3: Multiple Notifications Recovery
|
||||
|
||||
**Objective**: Verify multiple notifications are restored correctly
|
||||
|
||||
**Steps**:
|
||||
1. **Schedule Multiple Notifications**:
|
||||
- Schedule 3-4 notifications at different times
|
||||
- Note all scheduled times
|
||||
|
||||
2. **Reboot Device**:
|
||||
```bash
|
||||
adb reboot
|
||||
```
|
||||
|
||||
3. **Verify All Recovered**:
|
||||
```bash
|
||||
# Check all alarms
|
||||
adb shell "dumpsys alarm | grep timesafari"
|
||||
```
|
||||
- Should show all scheduled alarms
|
||||
|
||||
4. **Test Each Notification**:
|
||||
- Wait for each scheduled time
|
||||
- Verify each notification appears
|
||||
|
||||
**Expected Result**: All notifications appear at their scheduled times
|
||||
|
||||
## Automated Reboot Testing
|
||||
|
||||
### Bash Script for Reboot Testing
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# reboot-test.sh
|
||||
|
||||
set -e
|
||||
|
||||
APP_PACKAGE="com.timesafari.dailynotification"
|
||||
APP_ACTIVITY=".MainActivity"
|
||||
|
||||
echo "🔄 Starting Reboot Recovery Test"
|
||||
echo "================================"
|
||||
|
||||
# Function to wait for device
|
||||
wait_for_device() {
|
||||
echo "⏳ Waiting for device to be ready..."
|
||||
adb wait-for-device
|
||||
sleep 10 # Additional wait for boot completion
|
||||
}
|
||||
|
||||
# Function to schedule notification
|
||||
schedule_notification() {
|
||||
echo "📅 Scheduling test notification..."
|
||||
adb shell am start -n $APP_PACKAGE/$APP_ACTIVITY
|
||||
sleep 3
|
||||
|
||||
echo "⚠️ Manual step: Schedule notification in app"
|
||||
echo " - Tap 'Test Notification' button"
|
||||
echo " - Wait for 'Notification scheduled' message"
|
||||
read -p "Press Enter when notification is scheduled..."
|
||||
}
|
||||
|
||||
# Function to check recovery logs
|
||||
check_recovery_logs() {
|
||||
echo "🔍 Checking recovery logs..."
|
||||
if adb logcat -d | grep -q "Notification recovery completed successfully"; then
|
||||
echo "✅ Recovery completed successfully"
|
||||
return 0
|
||||
else
|
||||
echo "❌ Recovery not found in logs"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to check scheduled alarms
|
||||
check_scheduled_alarms() {
|
||||
echo "⏰ Checking scheduled alarms..."
|
||||
if adb shell "dumpsys alarm | grep timesafari" | grep -q "RTC_WAKEUP"; then
|
||||
echo "✅ Alarms scheduled correctly"
|
||||
return 0
|
||||
else
|
||||
echo "❌ No alarms found"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Main test
|
||||
main() {
|
||||
# Step 1: Schedule notification
|
||||
schedule_notification
|
||||
|
||||
# Step 2: Verify initial scheduling
|
||||
if check_scheduled_alarms; then
|
||||
echo "✅ Initial scheduling successful"
|
||||
else
|
||||
echo "❌ Initial scheduling failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Step 3: Reboot device
|
||||
echo "🔄 Rebooting device..."
|
||||
adb reboot
|
||||
wait_for_device
|
||||
|
||||
# Step 4: Check recovery
|
||||
if check_recovery_logs; then
|
||||
echo "✅ Recovery successful"
|
||||
else
|
||||
echo "❌ Recovery failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Step 5: Verify alarms restored
|
||||
if check_scheduled_alarms; then
|
||||
echo "✅ Alarms restored successfully"
|
||||
else
|
||||
echo "❌ Alarms not restored"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "🎉 Reboot recovery test completed successfully!"
|
||||
echo "⏰ Wait for the scheduled notification to appear"
|
||||
}
|
||||
|
||||
main
|
||||
```
|
||||
|
||||
### Python Script for Reboot Testing
|
||||
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Reboot Recovery Test Script
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import time
|
||||
import sys
|
||||
|
||||
class RebootTester:
|
||||
def __init__(self):
|
||||
self.package = "com.timesafari.dailynotification"
|
||||
self.activity = f"{self.package}/.MainActivity"
|
||||
|
||||
def run_command(self, command):
|
||||
"""Run ADB command"""
|
||||
return subprocess.run(f"adb {command}", shell=True, capture_output=True, text=True)
|
||||
|
||||
def wait_for_device(self):
|
||||
"""Wait for device to be ready"""
|
||||
print("⏳ Waiting for device...")
|
||||
self.run_command("wait-for-device")
|
||||
time.sleep(10) # Additional wait for boot completion
|
||||
|
||||
def schedule_notification(self):
|
||||
"""Schedule notification (manual step)"""
|
||||
print("📅 Scheduling notification...")
|
||||
self.run_command(f"shell am start -n {self.activity}")
|
||||
time.sleep(3)
|
||||
|
||||
print("⚠️ Manual step: Schedule notification in app")
|
||||
input("Press Enter when notification is scheduled...")
|
||||
|
||||
def check_recovery_logs(self):
|
||||
"""Check if recovery was successful"""
|
||||
result = self.run_command("logcat -d")
|
||||
return "Notification recovery completed successfully" in result.stdout
|
||||
|
||||
def check_scheduled_alarms(self):
|
||||
"""Check if alarms are scheduled"""
|
||||
result = self.run_command('shell "dumpsys alarm | grep timesafari"')
|
||||
return "RTC_WAKEUP" in result.stdout
|
||||
|
||||
def reboot_device(self):
|
||||
"""Reboot the device"""
|
||||
print("🔄 Rebooting device...")
|
||||
self.run_command("reboot")
|
||||
self.wait_for_device()
|
||||
|
||||
def run_test(self):
|
||||
"""Run complete reboot test"""
|
||||
print("🔄 Starting Reboot Recovery Test")
|
||||
print("=" * 40)
|
||||
|
||||
# Schedule notification
|
||||
self.schedule_notification()
|
||||
|
||||
# Verify initial scheduling
|
||||
if self.check_scheduled_alarms():
|
||||
print("✅ Initial scheduling successful")
|
||||
else:
|
||||
print("❌ Initial scheduling failed")
|
||||
return False
|
||||
|
||||
# Reboot device
|
||||
self.reboot_device()
|
||||
|
||||
# Check recovery
|
||||
if self.check_recovery_logs():
|
||||
print("✅ Recovery successful")
|
||||
else:
|
||||
print("❌ Recovery failed")
|
||||
return False
|
||||
|
||||
# Verify alarms restored
|
||||
if self.check_scheduled_alarms():
|
||||
print("✅ Alarms restored successfully")
|
||||
else:
|
||||
print("❌ Alarms not restored")
|
||||
return False
|
||||
|
||||
print("🎉 Reboot recovery test completed!")
|
||||
return True
|
||||
|
||||
if __name__ == "__main__":
|
||||
tester = RebootTester()
|
||||
if tester.run_test():
|
||||
sys.exit(0)
|
||||
else:
|
||||
sys.exit(1)
|
||||
```
|
||||
|
||||
## ADB Commands for Reboot Testing
|
||||
|
||||
### Device Management
|
||||
```bash
|
||||
# Reboot device
|
||||
adb reboot
|
||||
|
||||
# Wait for device to be ready
|
||||
adb wait-for-device
|
||||
|
||||
# Check if device is ready
|
||||
adb shell getprop sys.boot_completed
|
||||
```
|
||||
|
||||
### Recovery Monitoring
|
||||
```bash
|
||||
# Monitor recovery logs in real-time
|
||||
adb logcat | grep -i "bootreceiver\|recovery"
|
||||
|
||||
# Check recovery logs
|
||||
adb logcat -d | grep -i "bootreceiver\|recovery"
|
||||
|
||||
# Check boot receiver registration
|
||||
adb shell "dumpsys package com.timesafari.dailynotification | grep -A10 -B10 receiver"
|
||||
```
|
||||
|
||||
### Alarm Verification
|
||||
```bash
|
||||
# Check scheduled alarms before reboot
|
||||
adb shell "dumpsys alarm | grep timesafari"
|
||||
|
||||
# Check scheduled alarms after reboot
|
||||
adb shell "dumpsys alarm | grep timesafari"
|
||||
|
||||
# Check exact alarm permissions
|
||||
adb shell "dumpsys alarm | grep SCHEDULE_EXACT_ALARM"
|
||||
```
|
||||
|
||||
## Troubleshooting Reboot Recovery
|
||||
|
||||
### Common Issues
|
||||
|
||||
#### 1. Boot Receiver Not Triggered
|
||||
**Symptoms**: No recovery logs after reboot
|
||||
**Solutions**:
|
||||
- Check boot receiver registration in manifest
|
||||
- Verify `BOOT_COMPLETED` permission is granted
|
||||
- Check if device supports boot receiver (some OEMs disable it)
|
||||
|
||||
#### 2. Recovery Fails
|
||||
**Symptoms**: Recovery logs show errors
|
||||
**Solutions**:
|
||||
- Check SharedPreferences data integrity
|
||||
- Verify notification content is valid
|
||||
- Check alarm scheduling permissions
|
||||
|
||||
#### 3. Alarms Not Restored
|
||||
**Symptoms**: No alarms after recovery
|
||||
**Solutions**:
|
||||
- Check exact alarm permissions
|
||||
- Verify alarm scheduling logic
|
||||
- Check battery optimization settings
|
||||
|
||||
### Debug Commands
|
||||
|
||||
```bash
|
||||
# Check boot receiver status
|
||||
adb shell "dumpsys package com.timesafari.dailynotification | grep -A5 -B5 receiver"
|
||||
|
||||
# Check recovery manager logs
|
||||
adb logcat -d | grep -i "rebootrecovery"
|
||||
|
||||
# Check notification storage
|
||||
adb shell "run-as com.timesafari.dailynotification ls -la /data/data/com.timesafari.dailynotification/shared_prefs/"
|
||||
|
||||
# Check alarm manager state
|
||||
adb shell "dumpsys alarm | head -20"
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Testing Environment
|
||||
- Use physical device for most accurate results
|
||||
- Test on multiple Android versions
|
||||
- Test on different OEMs (Samsung, Huawei, etc.)
|
||||
- Test with different battery optimization settings
|
||||
|
||||
### Test Data
|
||||
- Use realistic notification content
|
||||
- Test with multiple notifications
|
||||
- Test with different time intervals
|
||||
- Test with various notification priorities
|
||||
|
||||
### Documentation
|
||||
- Record test results with timestamps
|
||||
- Screenshot notification appearances
|
||||
- Log any errors or unexpected behavior
|
||||
- Document device-specific issues
|
||||
|
||||
## Success Criteria
|
||||
|
||||
### ✅ Test Passes When:
|
||||
- Boot receiver is triggered after reboot
|
||||
- Recovery logs show successful restoration
|
||||
- Alarms are rescheduled correctly
|
||||
- Notifications appear at scheduled times
|
||||
- Multiple notifications are handled correctly
|
||||
|
||||
### ❌ Test Fails When:
|
||||
- Boot receiver is not triggered
|
||||
- Recovery fails with errors
|
||||
- Alarms are not restored
|
||||
- Notifications don't appear
|
||||
- App crashes during recovery
|
||||
|
||||
## Conclusion
|
||||
|
||||
The reboot recovery system ensures that scheduled notifications survive device reboots and app updates. Regular testing of this functionality is crucial for maintaining reliable notification delivery in production environments.
|
||||
|
||||
For questions or issues, refer to the troubleshooting section or check the plugin logs using the provided ADB commands.
|
||||
Reference in New Issue
Block a user