Baseflow / XamarinMediaManager

Cross platform Xamarin plugin to play and control Audio and Video
https://baseflow.com
MIT License
768 stars 305 forks source link

Android background audio playback stops due to app being killed for excessive CPU use #860

Closed sschaub closed 2 years ago

sschaub commented 2 years ago

🐛 Bug Report

XMM Release: 1.1.0

Android background audio playback stops after a period of time in some scenarios. This occurs in cases where the user pauses media playback and then resumes it. In that scenario, the MediaBrowserService does not restart the foreground service. After a period of time, the OS kills the app due to excessive CPU use.

Expected behavior

The foreground service should be running anytime the app is playing media to prevent the OS from killing the app.

Reproduction steps

  1. Start playing an audio clip. Play audio, then navigate away from app. Using adb shell dumpsys activity processes verify that the foreground service is running:
    Process LRU list (sorted by oom_adj, 36 total, non-act at 8, non-svc at 8):
    Proc # 2: prcp   F/S/FGS  ---  t: 0 16895:com.company.MyApp/u0a154 (fg-service)
  2. Pause playback. Note that the foreground service is stopped:
    Proc # 2: prev   b/ /SVC  ---  t: 0 17497:com.company.MyApp/u0a154 (cch-started-ui-services)
  3. Resume playback.
  4. Navigate away from the app. Using adb shell dumpsys activity processes, notice that the foreground service is not running.
    Proc # 2: prev   b/ /SVC  ---  t: 0 17497:com.company.MyApp/u0a154 (cch-started-ui-services)
  5. After a period of time, the app is killed due to excessive CPU use, as revealed in the adb log:
    ActivityManager: Killing 17072:com.company.MyApp/u0a158 (adj 700): excessive cpu 55260 during 300018 dur=749370 limit=10

Configuration

Version: 1.x

Platform:

sschaub commented 2 years ago

I was able to work around this in the 1.1.0 version of XMM without resorting to creating a custom build of XMM. I did that by replacing the stock MediaBrowserService with a custom version that impements the technique in #861, using XMM's customization capabilities. For those who might be interested, here's how I did it:

  1. I created a custom MMMediaBrowserService that restarts the foreground service (see attached).
  2. I created a custom MMMediaBrowserManager that overrides the stock MediaBrowserService with MMMediaBrowserService (see attached)
  3. In my MainActivity.cs, I installed MMMediaBrowserManager as follows:
    CrossMediaManager.Android.MediaBrowserManager = new MMMediaBrowserManager();
    CrossMediaManager.Current.Init(this);

    MMMediaBrowserManager.cs.txt MMMediaBrowserService.cs.txt