Skip to content

Player still stops on 1.5.1 (since v1.0.4): foreground service dropped 10 minutes after a track change #2233

Description

@Dollarius

Thanks @maxrave-dev for the audio-focus fix in core f293309 (1.5.0): that part of #2022 is now fixed. But I found another cause of music stopping, still present in 1.5.1 (Galaxy S23, Android 16, FOSS APK).

What I can observe (3 sessions tonight, same pattern each time): exactly 10 minutes after a track change, the foreground service flag is silently removed while music is still playing. About a minute later Android stops the service as idle, the app loses network, and playback starves at the next track. This leads to music stopping after 4-5 songs, as observed by @Lunar-Flame69 @MrDaraku @Allzweck @Prosto-Pasha @afabmoro97 @dafcavservicios @okcomputerfan.

20:54:54.261 D CrossfadeExoPlayerAdapter: End of stream reached      <- track change, playing fine
21:04:54.330 D NotificationService: removeFlagFromNotificationLocked
             pkg = com.maxrave.simpmusic notificationId = 200, flag = 64   <- +10:00.07: FGS dropped mid-track
21:05:42.245 W System.err: android_getaddrinfo failed: EAI_NODATA    <- idle app loses network
21:05:54.325 W ActivityManager: Stopping service due to app idle:
             u0a252 ... com.maxrave.simpmusic/...SimpleMediaService  <- +1 min: service stopped
21:08:30.740 E ExoPlayerImplInternal: ... Failed to resolve stream URL     <- next track starves

dumpsys activity services confirms it: isForeground=true at session start, silently false mid-playback, no pause anywhere in the log. The other two sessions show the same 10-minute delta (20:24:49 to 20:34:49, and one at 19:56:08).

My best guess at the mechanism: media3 1.9+ keeps the foreground service alive with a "user engaged" check plus a 10-minute grace timer. During a track swap, loadAndPlayTrackInternal swaps the ForwardingPlayer delegate and notifies MediaSession while the promoted precached player still has playWhenReady=false (play() comes a few lines later). That brief "not playing" sample could arm the timer, and the cancellation on re-engagement seems to never happen, maybe because media3's internal controller snapshot goes stale after the delegate swap. I'm not sure about the exact media3 internals here.

Possible fixes:

  1. In loadAndPlayTrackInternal, call play() before swapDelegate() / notifyMediaItemChanged(), so MediaSession never observes playWhenReady=false during a swap (the crossfade path already does this).
  2. In SimpleMediaService.onUpdateNotification, force startInForegroundRequired = true whenever session.player is actually playing, which should self-heal any wrong demotion within seconds.

Same symptom: #2222 (open), #2155, and older: #1995, #1983, #1965, #1948, #1894, #1847, #1818, #1386.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions