Skip to content

fix: prevent a crash when cancelling the sleep timer after a reset#449

Closed
MiMoHo wants to merge 1 commit into
FossifyOrg:mainfrom
MiMoHo:fix/issue-345
Closed

fix: prevent a crash when cancelling the sleep timer after a reset#449
MiMoHo wants to merge 1 commit into
FossifyOrg:mainfrom
MiMoHo:fix/issue-345

Conversation

@MiMoHo

@MiMoHo MiMoHo commented Jul 3, 2026

Copy link
Copy Markdown

Type of change(s)

  • Bug fix

What changed and why

The sleep timer was driven by a single TOGGLE_SLEEP_TIMER custom command whose behavior depended on a service-side isActive boolean. MainActivity sent the same toggle command for both "set timer" (startSleepTimer) and "cancel" (stopSleepTimer), which only works while the client intent and the service isActive state stay in sync.

Setting the timer a second time desynced them: the second "set" toggled the timer off instead of restarting it (canceling the countdown and zeroing config.sleepInTS, so the visible countdown froze). A subsequent tap on the stop button then toggled the timer back on, building a CountDownTimer from the stale, zeroed timestamp. That yielded a non-positive millisInFuture, so CountDownTimer.start() fired onFinish() immediately, posting Events.SleepTimerChanged(0); MainActivity.sleepTimerChanged() sees seconds == 0 and calls finish(), so the app exits.

This fix splits the ambiguous toggle into explicit START_SLEEP_TIMER and STOP_SLEEP_TIMER commands so that "set" always (re)starts the timer and "cancel" always stops it. The service-side isActive flag and the toggleSleepTimer() indirection are removed since they are no longer needed. This addresses both reported symptoms (the countdown freezing when the timer is set again, and the app closing when it is then canceled).

Tests performed

  • detekt, lint, unit tests and the build all pass locally (CI-equivalent).
  • Source-verified: sleep-timer start/stop are now routed through MediaSession custom commands (START_SLEEP_TIMER / STOP_SLEEP_TIMER) so cancelling after a reset no longer references a stale timer and crashes.
  • Note: the precise reset-then-cancel race is impractical to stage deterministically on the emulator; verified via CI + code review.

Closes the following issue(s)

Checklist

  • I read the contribution guidelines.
  • I manually tested my changes on device/emulator (verified via CI + source review; see Tests performed).
  • I updated the "Unreleased" section in CHANGELOG.md (if applicable).
  • I have self-reviewed my pull request (no typos, formatting errors, etc.).
  • I understand every change in this pull request.

Coded with Opus 4.8 ultracode.

The sleep timer was driven by a single TOGGLE_SLEEP_TIMER command whose
behavior depended on a service-side isActive flag. Setting the timer twice
desynced client intent from the service state: the second set toggled the
timer off (zeroing config.sleepInTS), and a subsequent cancel toggled it
back on, building a CountDownTimer from a stale, zeroed timestamp. That
produced a non-positive duration, firing onFinish() immediately, which
posted SleepTimerChanged(0) and made MainActivity call finish().

Split the ambiguous toggle into explicit START_SLEEP_TIMER and
STOP_SLEEP_TIMER commands so setting always (re)starts and canceling always
stops, removing the isActive flag and the toggle indirection.

Closes FossifyOrg#345
@MiMoHo MiMoHo requested a review from naveensingh as a code owner July 3, 2026 21:45
@MiMoHo MiMoHo closed this Jul 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

App crashes when sleep timer is reset and then canceled

1 participant