From 0a1e6a16f59d1c90288c5d9c4f54e4d3fa0d9235 Mon Sep 17 00:00:00 2001 From: Matthew Raymer Date: Fri, 24 Oct 2025 10:09:00 +0000 Subject: [PATCH] docs: add operational sections to Android app analysis and implementation plan MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add 5 surgical sections to android-app-analysis.md: * Assumptions & Versions table (Android SDK, Capacitor, WorkManager, Room, Exact Alarms) * Bridge Surface summary with method I/O shapes * Permission & Settings Truth Table (symptoms → actions) * Runtime Flow Diagram (mermaid) * Cordova vs Capacitor assets accuracy note - Add 6 execution rails to android-app-improvement-plan.md: * Phase DoD blocks for PR gating * RACI for multi-contributor PRs * PR Checklist template * Test Matrix from scenarios * Error Code Canon table * Operational Runbooks stubs - Fix accuracy: correct 'cordova.js' references to 'capacitor.js' - Make Status Matrix required fields explicit (5 specific fields) - Keep existing structure intact, minimal churn approach --- docs/android-app-analysis.md | 55 ++++++++++++++++++++-- docs/android-app-improvement-plan.md | 68 +++++++++++++++++++++++++++- 2 files changed, 119 insertions(+), 4 deletions(-) diff --git a/docs/android-app-analysis.md b/docs/android-app-analysis.md index 134495e..2ae196a 100644 --- a/docs/android-app-analysis.md +++ b/docs/android-app-analysis.md @@ -41,7 +41,7 @@ The `/android/app` directory contains a **Capacitor-based Android test applicati ├─────────────────────────────────────────────────────────────┤ │ Web Assets (/www) │ │ ├── index.html (Test Interface) │ -│ ├── cordova.js (Capacitor Runtime) │ +│ ├── capacitor.js (Capacitor Runtime) │ │ └── plugins/ (Plugin JavaScript) │ ├─────────────────────────────────────────────────────────────┤ │ Native Plugin Integration │ @@ -182,8 +182,8 @@ The `/www` directory (mapped to `assets/public/`) contains the web application t ``` assets/public/ ├── index.html # Main test interface (549 lines) -├── cordova.js # Capacitor runtime -├── cordova_plugins.js # Plugin JavaScript bridge +├── capacitor.js # Capacitor runtime +├── capacitor_plugins.js # Plugin JavaScript bridge └── plugins/ # Plugin JavaScript files ``` @@ -513,3 +513,52 @@ The `/android/app` portion of the DailyNotification plugin represents a well-arc The integration between the web assets (`/www`) and native Android code through Capacitor's bridge system creates a seamless testing environment that allows developers to validate plugin functionality in real-time while providing an intuitive interface for non-technical users to test and understand the plugin's capabilities. This architecture serves as both a practical testing tool and a reference implementation for integrating the DailyNotification plugin into other applications. + +## Assumptions & Versions + +| Topic | Value | Notes | +|---|---|---| +| Android min/target SDK | 24 / 35 | Align with `compileSdkVersion`/`targetSdkVersion`. | +| Capacitor | v5.x | Confirm web asset naming (`capacitor.js` vs Cordova shims). | +| WorkManager | 2.9.0 | Matches Gradle deps listed. | +| Room | 2.6.1 | Matches Gradle deps listed. | +| Exact Alarms | Tiramisu+ | Requires user grant on many OEMs. | + +## Bridge Surface (Summary) + +- `scheduleDailyNotification(req: {time, title, body, sound, priority}) -> {success, scheduledAt?, error?}` +- `checkPermissionStatus() -> {postNotificationsGranted, exactAlarmGranted, batteryOptIgnored, channelEnabled, ...}` +- `openChannelSettings() -> {opened: boolean}` +- `openExactAlarmSettings() -> {opened: boolean}` +- `requestNotificationPermissions() -> {granted: boolean, permissions: {...}}` +- `getNotificationStatus() -> {isEnabled, isScheduled, nextNotificationTime, ...}` + +## Permission & Settings Truth Table + +| Symptom | Likely Cause | Action | +|---|---|---| +| No notification posts | `POST_NOTIFICATIONS` denied | Call `requestNotificationPermissions()` | +| Fires late/misses | No exact alarm grant / Doze | `openExactAlarmSettings()` or fallback to WorkManager | +| Silent notifications | Channel disabled/low importance | `openChannelSettings()` then retest | +| Battery optimization kills | App not whitelisted | Guide user to battery optimization settings | +| Boot reschedule fails | `RECEIVE_BOOT_COMPLETED` denied | Check manifest receiver registration | + +## Runtime Flow Diagram + +```mermaid +graph TD + A[JavaScript Call] --> B[Capacitor Bridge] + B --> C[@PluginMethod] + C --> D[Use Case Handler] + D --> E{Alarm vs WorkManager} + E -->|Exact Alarm| F[AlarmManager] + E -->|Fallback| G[WorkManager] + F --> H[BootReceiver] + G --> H + H --> I[NotificationReceiver] + I --> J[UI Update] +``` + +## Cordova vs Capacitor Assets – Accuracy Note + +> **Note:** If using pure Capacitor v5, the web runtime is `capacitor.js`. If Cordova compatibility is enabled, `cordova.js/cordova_plugins.js` will appear; otherwise remove those references here for accuracy. diff --git a/docs/android-app-improvement-plan.md b/docs/android-app-improvement-plan.md index c077f67..420dbee 100644 --- a/docs/android-app-improvement-plan.md +++ b/docs/android-app-improvement-plan.md @@ -830,7 +830,7 @@ interface ScheduleResponse { ## Acceptance Criteria ### Status Matrix -- [ ] Reports all relevant runtime capabilities +- [ ] Reports all relevant runtime capabilities (postNotifications, exactAlarms, channelEnabled, batteryOptIgnored, canScheduleNow) - [ ] Shows live channel state - [ ] Provides actionable buttons for issues - [ ] Exports diagnostics as JSON @@ -886,3 +886,69 @@ This implementation plan provides a structured approach to improving the DailyNo The phased approach allows for incremental improvements while ensuring each phase delivers value. The acceptance criteria provide clear success metrics for each improvement area. By following this plan, the test app will become more maintainable, reliable, and user-friendly while providing a solid foundation for future enhancements. + +## Phase DoD (Definition of Done) + +### Phase 1 DoD +- Status Matrix renders 5 fields: postNotifications, exactAlarms, channelEnabled, batteryOptIgnored, canScheduleNow. +- Input schema rejects bad `time`, long `title/body`, wrong `priority`. +- Boot reschedule idempotent (no dup rows, migration fence). +- @PluginMethod bodies ≤ 25 LOC, delegate to use-cases. + +### Phase 2 DoD +- Test UI split into modular scenarios with fixtures. +- Instrumentation tests cover channel disabled and exact alarm denied paths. +- Structured logging with event IDs for all operations. +- Error handling returns canonical error codes. + +### Phase 3 DoD +- Security hardening implemented (HTTPS enforcement, input validation). +- Performance optimizations deployed (lazy loading, backoff strategy). +- Complete documentation with runbooks and API reference. +- Diagnostics system operational with health checks. + +## RACI +- Owner: Android plugin maintainer +- Review: Mobile lead +- Consult: QA (instrumented tests), Web (bridge TS) +- Inform: Docs + +## PR Checklist (copy/paste into PR template) + +- [ ] Input validated at bridge boundary (unit tested) +- [ ] Use-case class created/updated (no logic in @PluginMethod) +- [ ] Logs include event IDs (start/finish/error) +- [ ] Status Matrix field(s) updated if capability changed +- [ ] Runbooks section touched if behavior changed + +## Test Matrix + +| Scenario | Method(s) | Setup | Expected | +|---|---|---| +| Immediate notify | scheduleDailyNotification | Channel ON, perms granted | Success + toast seen | +| Channel disabled path | isChannelEnabled/openChannelSettings | Disable channel | Canonical `E_CHANNEL_DISABLED` | +| Exact alarm denied path | openExactAlarmSettings | Revoke exact alarm | Fallback path taken; logged `DOZE_FALLBACK` | +| Boot reschedule | BootReceiver | Reboot emulator | One (not duplicate) schedule restored | + +## Error Codes (canonical) + +| Code | Meaning | Hint | +|---|---|---| +| E_INVALID_TIME | HH:mm invalid | Use 24h HH:mm | +| E_TITLE_TOO_LONG | >100 chars | Trim title | +| E_BODY_TOO_LONG | >500 chars | Trim body | +| E_PERMISSION_DENIED | Missing POST_NOTIFICATIONS | Request permission | +| 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 | + +## Runbooks + +### No notifications fire +Checks → Fix → Verify (matrix first, then perms, channel, exact alarm). + +### Duplicates after reboot +Check storage for orphan schedule rows; verify idempotent rescheduler logs. + +### Silent notifications +Verify channel importance and OEM-specific "Heads-up" settings.