screentinker/android/app
Claude acadb4c1f4 Stop the playlist and the OTA checker when the Activity is destroyed
onDestroy already shuts down the wall and group controllers, and its comment says exactly why: those
Handlers are on the main looper, which outlives the Activity, so a surviving tick "would keep
broadcasting sync frames against the released player forever". Three other things on that same looper
were never stopped.

PlaylistController kept advancing after the Activity was gone. Every tick wrote the resume index and
emitted play_start/play_end through the still-live WebSocketService, so after any relaunch — the
"launch" command, Relauncher after OTA or boot, a re-pair, or a config change outside the ones the
manifest handles — two controllers were reporting playback for one screen. That inflates Total Plays
and Hours in Reports for that panel, and races over the resume position #234 depends on. Widget items
also re-entered showWidget on a WebView nobody owned any more.

UpdateChecker was never stopped either, and its install receiver was never unregistered:
installReceiverRegistered is per-instance, so each recreate added another checker polling
/api/update/check and another receiver for INSTALL_COMPLETE. N of those turns one
STATUS_PENDING_USER_ACTION into N confirm dialogs stacked over customer content, and concurrent
checkers race in tryPackageInstaller — which starts by abandoning ALL of the app's installer
sessions, so one can abandon another's staged session mid-flight and the update never completes.
shutdown() now does both, and the receiver is held so it can actually be unregistered.

The Activity's own posted callbacks (the 30s failure-check loop among them) are cleared too.

134 Android JVM tests green. The effect is a leak and a duplicate reporting stream rather than a
wrong value on a screen, so it is verified by reading the lifecycle rather than by a unit test.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uaeo9MvzKoyXuN6ZsbhtkL
2026-07-30 21:03:19 -05:00
..
src Stop the playlist and the OTA checker when the Activity is destroyed 2026-07-30 21:03:19 -05:00
build.gradle.kts chore(release): v1.9.27 2026-07-30 19:16:55 -05:00
proguard-rules.pro Initial open source release 2026-04-08 12:14:53 -05:00