Skip to content

Bug: PendingIntent identity mismatch can leave stale or duplicate boot-restored alarms #887

@Rahul-2k4

Description

@Rahul-2k4

Description

Alarm scheduling, cancellation, and boot restore do not consistently target the same PendingIntent identity.

The app now routes normal alarm scheduling through AlarmScheduleContract, but there is still upgrade and restore risk around legacy boot-restored alarms and mixed request-code usage. This can leave an old alarm armed when the user expects the latest schedule to replace it.

Affected Code

  • android/app/src/main/kotlin/com/ccextractor/ultimate_alarm_clock/ultimate_alarm_clock/AlarmScheduleContract.kt
  • android/app/src/main/kotlin/com/ccextractor/ultimate_alarm_clock/ultimate_alarm_clock/BootReceiver.kt
  • android/app/src/main/kotlin/com/ccextractor/ultimate_alarm_clock/ultimate_alarm_clock/MainActivity.kt

Why this matters

This is an alarm app, so duplicate or zombie alarms are a trust-breaking bug.

A user can:

  • edit an alarm
  • reboot the phone
  • or upgrade from an older install state

and still have a previously scheduled alarm fire because cancellation and restore are not fully modeled around one stable identity contract.

Current Observations

The current code already contains legacy cancellation handling in AlarmScheduleContract.clear(), which shows this mismatch has existed across scheduling generations.

That makes this a repo-level correctness issue, not just cleanup.

Expected Behavior

  • the currently active alarm schedule should be represented by one consistent PendingIntent identity contract
  • schedule, cancel, and boot restore should all operate on that same contract
  • upgrade paths should explicitly cancel any legacy alarm identities

Suggested Fix

  • centralize alarm PendingIntent creation in one helper
  • define stable request codes and flags for:
    • main alarm broadcast
    • activity check service
    • location check service
    • weather check service
  • ensure all old boot-restored identities are cancelled during clear/reschedule
  • add regression tests for upgrade-time and boot-time behavior

Acceptance Criteria

  • editing or rescheduling an alarm does not leave the previous alarm armed
  • reboot restore does not create a duplicate alarm delivery path
  • legacy boot-restored alarms are cancelled during migration/cleanup
  • native tests cover the PendingIntent identity contract

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions