Skip to content

[Release] Unify alarm permission and fallback delivery policy #534

Description

@jjoonleo

Problem

Alarm permission handling has no single source of truth. AlarmGateCubit, My Page, /allowAlarm, and ReconcileAlarmsUseCase each interpret exact-alarm permission and notification fallback differently. This makes the same device state behave as prompt-required, alarms-off, or successfully armed depending on entry point.

Related to #465. This should also be resolved before #457 QA, otherwise QA may validate inconsistent behavior.

Evidence

  • AlarmGateCubit.requestPermission() treats denied native permission plus granted notification fallback as granted, enables alarms, and reconciles.
  • AlarmGateCubit.refreshPermission() checks native permission first and still emits required when native permission is denied, even if fallback is granted.
  • /allowAlarm exits to /home when requestPermission() returns granted, so fallback grant can look fully allowed from that screen.
  • My Page toggle requires exact-alarm recovery before enabling alarms, then disables/cancels alarms if exact permission is still missing, even when fallback could be available.
  • ReconcileAlarmsUseCase arms localNotification fallback when exact-alarm permission is denied and notification fallback permission is granted, reporting armed with no permission issue.
  • Existing tests encode both sides: alarm gate/reconcile tests allow fallback delivery, while My Page tests keep alarms disabled on exact permission denial.

Proposed direction

Define one alarm delivery policy for the matrix of native capability, native permission, fallback capability, fallback permission, and user dismissal. Use it from alarm gate refresh/request, /allowAlarm, My Page status/toggle, and reconciliation.

Decide explicitly whether native denied + fallback granted means:

  • alarms stay enabled and are armed via fallback, with exact-alarm recovery shown as non-blocking; or
  • alarms are considered permission-blocked and disabled until exact permission is restored.

Then apply that decision consistently across UI, routing, settings updates, reconciliation status, and QA wording.

Acceptance criteria

  • A single shared policy/helper/use case determines alarm delivery mode, blocking permission issue, prompt behavior, and whether alarms should be disabled.
  • AlarmGateCubit.refreshPermission() and requestPermission() agree for native-denied/fallback-granted states.
  • My Page toggle and status use the same policy as reconciliation instead of duplicating exact-alarm/fallback checks.
  • /allowAlarm copy and navigation reflect the chosen policy.
  • ReconcileAlarmsUseCase status reporting matches the chosen UI policy.
  • Tests cover native granted, native denied with fallback granted, native denied with fallback denied, native unsupported with fallback granted, and all-provider-unavailable states.
  • [Release] QA alarm and notification flows on Android #457 QA checklist can validate one expected permission/fallback behavior instead of separate behavior per entry point.

Related: #465, #457

Source: Codex codebase audit on 2026-06-28.

Metadata

Metadata

Assignees

No one assigned

    Labels

    androidAndroid platform workbugSomething isn't workingproduction-readinessWork required before production releaseqaQuality assurance and manual verificationrefactorrelease-p1Required for first app release readiness

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions