diff --git a/docs/android-app-analysis.md b/docs/android-app-analysis.md index 2ae196a..16b5119 100644 --- a/docs/android-app-analysis.md +++ b/docs/android-app-analysis.md @@ -184,6 +184,8 @@ assets/public/ ├── index.html # Main test interface (549 lines) ├── capacitor.js # Capacitor runtime ├── capacitor_plugins.js # Plugin JavaScript bridge + +> **Note:** On pure Capacitor builds, the runtime is `capacitor.js`. Only include `cordova.js/cordova_plugins.js` if Cordova-compat is enabled; otherwise remove those references for accuracy. └── plugins/ # Plugin JavaScript files ``` @@ -363,6 +365,14 @@ android { **Purpose**: Auto-generated Capacitor configuration **Note**: Regenerated on each `npx cap sync` - should not be manually edited +**Manifest Hygiene (Quick Scan)** +- [ ] `` +- [ ] `` (if you truly need exact) +- [ ] `` +- [ ] BootReceiver: `exported="true"` + BOOT_COMPLETED filter +- [ ] Other receivers exported=false unless needed +- [ ] No stray `android:permission=` on BootReceiver + ## Runtime Behavior ### App Startup Sequence @@ -533,6 +543,8 @@ This architecture serves as both a practical testing tool and a reference implem - `requestNotificationPermissions() -> {granted: boolean, permissions: {...}}` - `getNotificationStatus() -> {isEnabled, isScheduled, nextNotificationTime, ...}` +**Status Matrix MUST include:** `postNotificationsGranted`, `exactAlarmGranted`, `channelEnabled`, `batteryOptimizationsIgnored`, `canScheduleNow`. + ## Permission & Settings Truth Table | Symptom | Likely Cause | Action | diff --git a/docs/android-app-improvement-plan.md b/docs/android-app-improvement-plan.md index 420dbee..65bc77a 100644 --- a/docs/android-app-improvement-plan.md +++ b/docs/android-app-improvement-plan.md @@ -230,6 +230,10 @@ public class ScheduleDaily { - **Error Handling**: Standardized error responses - **Validation**: Input validation before processing +### Exact-Alarm Decision Rule (User-Visible) +If `SCHEDULE_EXACT_ALARM` is **granted** → schedule with `setExactAndAllowWhileIdle`. +If **denied or quota-limited** → schedule via WorkManager (exp backoff + jitter) and surface `E_EXACT_ALARM_DENIED` (with "Degraded timing — Doze may delay" hint). + ### 3. Service Locator **Purpose**: Dependency injection for testability @@ -413,12 +417,12 @@ export class SchemaValidator { errors.push('Time must be in HH:mm format'); } - // Validate title length + // Validate title length (enforce exactly: title ≤ 100 chars) if (request.title && request.title.length > 100) { errors.push('Title must be 100 characters or less'); } - // Validate body length + // Validate body length (enforce exactly: body ≤ 500 chars) if (request.body && request.body.length > 500) { errors.push('Body must be 500 characters or less'); } @@ -433,9 +437,17 @@ export class SchemaValidator { errors.push('Priority must be low, default, or high'); } + // Reject unknown fields + const allowedFields = ['time', 'title', 'body', 'sound', 'priority']; + const unknownFields = Object.keys(request).filter(key => !allowedFields.includes(key)); + if (unknownFields.length > 0) { + errors.push(`Unknown fields: ${unknownFields.join(', ')}`); + } + return { isValid: errors.length === 0, - errors + errors, + message: errors.join('; ') // Single joined message for UI display }; } } @@ -495,6 +507,11 @@ public class SecureNetworkClient { #### Implementation Plan ```xml + + + + + + android:exported="true"> @@ -809,6 +825,12 @@ interface ScheduleResponse { - Implement progress logging - Create log export functionality +**Event IDs (minimum set)** +- EVT_SCHEDULE_REQUEST / EVT_SCHEDULE_OK / EVT_SCHEDULE_FAIL +- EVT_BOOT_REHYDRATE_START / EVT_BOOT_REHYDRATE_DONE +- EVT_CHANNEL_STATUS / EVT_PERM_STATUS / EVT_EXACT_ALARM_STATUS +- EVT_DOZE_FALLBACK_TAKEN / EVT_WORKER_RETRY + ### Phase 3: Security & Performance - [ ] **Security Hardening** - Add network security measures @@ -941,6 +963,8 @@ By following this plan, the test app will become more maintainable, reliable, an | E_CHANNEL_DISABLED | Channel blocked/low importance | Open channel settings | | E_EXACT_ALARM_DENIED | No exact alarm | Open exact alarm settings / fallback | | E_DOZE_LIMIT | Throttled by Doze | Expect delays; fallback taken | +| E_CHANNEL_MISSING | Channel ID not found at runtime | Recreate channel; verify ID & importance | +| E_BAD_CONFIG | Missing/invalid plugin config at startup | Check `capacitor.config.json` and diagnostics dump | ## Runbooks @@ -952,3 +976,10 @@ Check storage for orphan schedule rows; verify idempotent rescheduler logs. ### Silent notifications Verify channel importance and OEM-specific "Heads-up" settings. + +### Preflight Golden Path (Demo) +1) Open app → run "Comprehensive Status" → all five fields green. +2) Tap "Open Channel Settings" → ensure importance = High. +3) Tap "Open Exact Alarm Settings" → grant if available. +4) Run "Immediate Notification" → toast & notif appear within 5s. +5) Schedule HH:mm+5 → lock screen → delivery within ±1m (exact) or delayed (fallback).