android / uamp

A sample audio app for Android
Apache License 2.0
13.11k stars 3.76k forks source link

MusicService stops running in foreground after being paused #444

Closed mhelder closed 3 years ago

mhelder commented 3 years ago

MusicService contains some logic that will promote the service to the foreground when it's actively playing audio. This logic depends on two things:

  1. whether the posted notification is ongoing
  2. whether the service hasn't already been promoted to the foreground (described by the local flag isForegroundService)

This is the relevant code: https://github.com/android/uamp/blob/8dda0e8d3cb4ec9d4422fb40b02ea65bfd3f1b6c/common/src/main/java/com/example/android/uamp/media/MusicService.kt#L581-L590

There are two places where the service is 'demoted' to the background again:

  1. When the notification is cancelled
  2. When the player's playback state changes to paused (playWhenReady == false)

Relevant code snippets:

https://github.com/android/uamp/blob/8dda0e8d3cb4ec9d4422fb40b02ea65bfd3f1b6c/common/src/main/java/com/example/android/uamp/media/MusicService.kt#L592-L596

https://github.com/android/uamp/blob/8dda0e8d3cb4ec9d4422fb40b02ea65bfd3f1b6c/common/src/main/java/com/example/android/uamp/media/MusicService.kt#L615-L621

Notice the difference? When the playback state changes to paused, the service is demoted to the background but isForegroundService isn't updated accordingly (unlike when the notification gets cancelled). This means that when playback gets resumed, the service isn't promoted to the foreground again (from onNotificationPosted) because isForegroundService is still set to true.

This can also be evidenced through adb:

Initial playback:

> adb shell dmpsys activity services MusicService | grep isForeground
    isForeground=true foregroundId=45881 foregroundNoti=Notification(pri=-1 contentView=com.example.android.uamp.next/0x109007f vibrate=null sound=null defaults=0x0 flags=0x62 color=0x00000000 category=transport actions=1 vis=PUBLIC)

After pausing and resuming playback:

> adb shell dmpsys activity services MusicService | grep isForeground
    isForeground=false foregroundId=45881 foregroundNoti=Notification(pri=-1 contentView=com.example.android.uamp.next/0x109007f vibrate=null sound=null defaults=0x0 flags=0x62 color=0x00000000 category=transport actions=1 vis=PUBLIC)

Would you accept a PR to fix this?


Some context: what led me to dive into this is that we have a Podcast player app that's heavily based on UAMP. Our service implementation has a ~95% overlap with MusicService - the main difference is that we use a different layer of abstraction for resolving/loading audio (basically what MusicSource takes care of in UAMP).

We get a lot of reports from users - primarily with Samsung devices - that playback randomly stops while the app is the background. This is hard to reproduce on our development devices, and the fact that the reports our mostly from Samsung users can have different reasons: Samsung has a large market share in our geographic region, but Samsung is also known to impose 'battery optimisations' and 'background restrictions' that break valid background use cases for 3rd party apps.

We're somewhat optimistic/hopeful that correctly promoting the app to the foreground again will reduce the number of user reports concerning background playback issues, but the proof will be in the pudding.

mobileappconsultant commented 3 years ago

I would definitely want this or a way around this problem @mhelder

nic0lette commented 3 years ago

Would you accept a PR to fix this?

Sure. I try to merge any bug fixes I can, so long as they meet the style, etc... of the project. If you make a PR for this, assign me as the reviewer and I'll try to get it merged.

abdurahmanadilovic commented 2 years ago

@mobileappconsultant @nic0lette with changes on android 12, when the app is in the background, it's not possible to start a foreground service, which means that promoting the service to the background will result in a crash if the user presses play and then pause in the notification while the app is in the background?