|
| 1 | +# Google Play Full-Screen Intent Declaration |
| 2 | + |
| 3 | +This document prepares the Play Console review material for issue #445 under |
| 4 | +parent track #465. It is not a record of submission. A human with Play Console |
| 5 | +access must submit the declaration and attach release-candidate QA evidence. |
| 6 | + |
| 7 | +Checked against Google policy guidance on 2026-05-10: |
| 8 | + |
| 9 | +- Google Play policy: `USE_FULL_SCREEN_INTENT` on Android 14+ is auto-granted |
| 10 | + only for apps whose core function is setting alarms or handling calls, and |
| 11 | + apps targeting Android 14+ should submit the Play Console declaration to |
| 12 | + establish pre-grant eligibility. |
| 13 | + https://support.google.com/googleplay/android-developer/answer/16558241?hl=en |
| 14 | +- Android platform guidance: Google Play revokes full-screen intent permission |
| 15 | + for installed apps that do not have calling or alarm functionality. |
| 16 | + https://source.android.com/docs/core/permissions/fsi-limits |
| 17 | + |
| 18 | +## Declaration Position |
| 19 | + |
| 20 | +OnTime should declare `USE_FULL_SCREEN_INTENT` for the setting-an-alarm use |
| 21 | +case. |
| 22 | + |
| 23 | +OnTime is a schedule preparation and reminder app. Users create schedule entries |
| 24 | +and enable schedule alarms so the app can alert them at the preparation start |
| 25 | +time. The full-screen intent is reserved for that user-scheduled alarm moment, |
| 26 | +when the user needs immediate, time-sensitive notice to start preparing for a |
| 27 | +schedule. |
| 28 | + |
| 29 | +The app does not use full-screen intent for marketing, ads, generic push |
| 30 | +messages, preparation-step notifications, or other low-priority notifications. |
| 31 | + |
| 32 | +## Play Console Draft Text |
| 33 | + |
| 34 | +Use case category: |
| 35 | + |
| 36 | +```text |
| 37 | +Setting an alarm |
| 38 | +``` |
| 39 | + |
| 40 | +Short justification: |
| 41 | + |
| 42 | +```text |
| 43 | +OnTime uses full-screen intent only for user-scheduled schedule alarms. Users |
| 44 | +create schedules and enable alarms/reminders so OnTime can alert them at the |
| 45 | +preparation start time. The full-screen alarm UI appears only when a scheduled |
| 46 | +alarm fires and helps the user start or dismiss that alarm. |
| 47 | +``` |
| 48 | + |
| 49 | +Detailed reviewer explanation: |
| 50 | + |
| 51 | +```text |
| 52 | +OnTime's core functionality is schedule preparation with alarms/reminders. A |
| 53 | +user can create a schedule and enable schedule alarms. When an alarm time is |
| 54 | +reached, OnTime posts an Android alarm-category notification with a full-screen |
| 55 | +intent to show the alarm UI. The full-screen UI contains only alarm controls, |
| 56 | +including "Start preparing" and "Dismiss", and routes the user into the |
| 57 | +schedule preparation flow. |
| 58 | +
|
| 59 | +Full-screen intent is not used for promotional content, ads, generic app |
| 60 | +updates, social messages, or ordinary push notifications. Non-alarm push and |
| 61 | +local notifications use normal notification channels. Payloads identified as |
| 62 | +schedule_alarm are suppressed from the generic notification path so the native |
| 63 | +alarm path owns alarm presentation. |
| 64 | +``` |
| 65 | + |
| 66 | +Reviewer evidence to attach: |
| 67 | + |
| 68 | +```text |
| 69 | +1. AndroidManifest.xml declares USE_FULL_SCREEN_INTENT for the app-owned alarm |
| 70 | + behavior. |
| 71 | +2. NativeAlarmReceiver posts the only full-screen notification and marks it as |
| 72 | + Notification.CATEGORY_ALARM. |
| 73 | +3. AlarmRingingActivity is the full-screen UI and only exposes alarm actions: |
| 74 | + Start preparing and Dismiss. |
| 75 | +4. NotificationService suppresses schedule_alarm payloads in generic push/local |
| 76 | + notification paths. |
| 77 | +5. QA evidence shows a user-created schedule alarm firing on a locked/off-screen |
| 78 | + Android device and shows generic notifications do not launch full-screen UI. |
| 79 | +``` |
| 80 | + |
| 81 | +## Source Evidence |
| 82 | + |
| 83 | +Manifest permission: |
| 84 | + |
| 85 | +- `android/app/src/main/AndroidManifest.xml` declares |
| 86 | + `android.permission.USE_FULL_SCREEN_INTENT`. |
| 87 | +- The release permission audit keeps this permission only for the |
| 88 | + user-scheduled alarm ringing notification: |
| 89 | + `docs/Android-Manifest-Permissions.md`. |
| 90 | + |
| 91 | +Full-screen notification path: |
| 92 | + |
| 93 | +- `android/app/src/main/kotlin/club/devkor/ontime/NativeAlarmReceiver.kt` |
| 94 | + creates channel `on_time_alarm_full_screen`, sets |
| 95 | + `Notification.CATEGORY_ALARM`, sets priority `PRIORITY_MAX`, and calls |
| 96 | + `setFullScreenIntent(fullScreenIntent, true)`. |
| 97 | +- The receiver skips posting the alarm notification if Android 13+ |
| 98 | + notification permission is denied. |
| 99 | + |
| 100 | +Full-screen alarm UI: |
| 101 | + |
| 102 | +- `android/app/src/main/kotlin/club/devkor/ontime/AlarmRingingActivity.kt` |
| 103 | + is configured as the alarm UI with `showWhenLocked`, `turnScreenOn`, and |
| 104 | + alarm-only controls. |
| 105 | +- `AlarmRingingActivity` captures alarm payload fields and forces |
| 106 | + `type=schedule_alarm` and `promptVariant=alarm`. |
| 107 | + |
| 108 | +Scheduling and routing: |
| 109 | + |
| 110 | +- `android/app/src/main/kotlin/club/devkor/ontime/MainActivity.kt` schedules |
| 111 | + native alarms through `AlarmManager.setAlarmClock` and supplies the |
| 112 | + full-screen activity pending intent as the alarm clock show intent. |
| 113 | +- `lib/domain/use-cases/reconcile_alarms_use_case.dart` derives desired alarm |
| 114 | + records from schedule and preparation data and schedules only future alarm |
| 115 | + times within the alarm coverage window. |
| 116 | +- `lib/core/services/alarm_scheduler_service.dart` passes schedule alarm |
| 117 | + payloads to the native alarm channel. |
| 118 | +- `lib/core/services/notification_service.dart` suppresses `schedule_alarm` |
| 119 | + payloads from generic FCM/local notification display and routes alarm taps to |
| 120 | + `/scheduleStart`. |
| 121 | + |
| 122 | +## QA Checklist For Submission Evidence |
| 123 | + |
| 124 | +Record the app version, Android device model, Android version, build type, and |
| 125 | +timestamp for each run. |
| 126 | + |
| 127 | +- User-scheduled alarm fires while the screen is locked and opens the full-screen |
| 128 | + alarm UI. |
| 129 | +- User-scheduled alarm fires while the screen is off and opens the full-screen |
| 130 | + alarm UI. |
| 131 | +- The full-screen alarm UI shows alarm-only controls and no promotional or |
| 132 | + generic content. |
| 133 | +- Tapping "Start preparing" opens the schedule preparation flow for the alarm |
| 134 | + schedule. |
| 135 | +- Tapping "Dismiss" stops the alarm UI and clears the alarm notification. |
| 136 | +- A generic push notification does not open a full-screen UI. |
| 137 | +- A preparation-step notification does not open a full-screen UI. |
| 138 | +- Android 13+ notification-denied state does not post the full-screen alarm |
| 139 | + notification. |
| 140 | +- Android 12+ exact-alarm-denied state does not schedule a native full-screen |
| 141 | + alarm and instead follows the documented permission/fallback behavior. |
| 142 | + |
| 143 | +## Play Console Submission Steps |
| 144 | + |
| 145 | +1. Open the target app in Play Console. |
| 146 | +2. Open the app content or policy declaration area that contains full-screen |
| 147 | + intent permission declarations for the active Android target level. |
| 148 | +3. Select the alarm use case for `USE_FULL_SCREEN_INTENT`. |
| 149 | +4. Paste the short justification and reviewer explanation above. |
| 150 | +5. Attach or reference QA evidence from the release-candidate build. |
| 151 | +6. Confirm the app listing describes schedule preparation, reminders, and alarms |
| 152 | + consistently with `docs/Google-Play-Listing-Copy.md`. |
| 153 | +7. Submit the declaration. |
| 154 | +8. Update #445 with the submission date, reviewer evidence location, device/OS |
| 155 | + matrix, and any Play Console response. |
| 156 | + |
| 157 | +## Remaining Human Tasks |
| 158 | + |
| 159 | +- Submit the Play Console declaration from an authorized account. |
| 160 | +- Run and record the QA checklist on release-candidate Android builds. |
| 161 | +- Attach screenshots or screen recordings that show full-screen behavior only |
| 162 | + for user-scheduled alarms. |
| 163 | +- Leave #445 open until declaration submission and QA evidence are complete. |
| 164 | + |
0 commit comments