Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Playback resumption notification not showing for API 31+ with MediaSessionService #933

Open
1 task
svenoaks opened this issue Dec 29, 2023 · 5 comments
Open
1 task
Assignees

Comments

@svenoaks
Copy link

Version

Media3 1.2.0

More version details

No response

Devices that reproduce the issue

API 31-34 emulators, some physical devices tested also

Devices that do not reproduce the issue

<= Api 30 emulators, some physical devices tested also

Reproducible in the demo app?

Not tested

Reproduction steps

This is an extension of the comments for #672, we would like to have a MediaSessionService app post a playback resumption notification on all API levels

manifest permissions:

<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />

where applicable, the POST_NOTIFICATIONS is granted at runtime prior to restarting the app and demonstrating the behavior

service declaration:

<service
            android:name=".player.PlaybackService"
            android:foregroundServiceType="mediaPlayback"
            android:exported="true">
            <intent-filter>
                <action android:name="androidx.media3.session.MediaSessionService"/>
                <action android:name="android.media.browse.MediaBrowserService"/>
            </intent-filter>
        </service>

playback resumption is implemented and working on all API levels

On the stated API levels, started playback, then paused and put the app in the background

Expected result

after a couple of minutes of the app being in the background, the normal notification disappears and a playback resumption notification appears with a play button only on all API levels

On API 30, we get logs such as these:

2023-12-29 12:12:05.386   684-684   MediaResumeListener     com.android.systemui                 D  Checking for service component for com.smp.musicspeed
2023-12-29 12:12:05.387   684-760   MediaResumeListener     com.android.systemui                 D  Testing if we can connect to ComponentInfo{com.smp.musicspeed/com.smp.musicspeed.player.PlaybackService}
2023-12-29 12:12:05.436   684-684   MediaResumeListener     com.android.systemui                 D  Checking for service component for com.smp.musicspeed
2023-12-29 12:12:05.446   684-760   MediaResumeListener     com.android.systemui                 D  Testing if we can connect to ComponentInfo{com.smp.musicspeed/com.smp.musicspeed.player.PlaybackService}
2023-12-29 12:12:05.477   684-684   MediaResumeListener     com.android.systemui                 D  Checking for service component for com.smp.musicspeed
2023-12-29 12:12:05.483   684-760   MediaResumeListener     com.android.systemui                 D  Testing if we can connect to ComponentInfo{com.smp.musicspeed/com.smp.musicspeed.player.PlaybackService}
2023-12-29 12:12:05.522   684-760   MediaResumeListener     com.android.systemui                 D  yes we can resume with ComponentInfo{com.smp.musicspeed/com.smp.musicspeed.player.PlaybackService}

Actual result

On the states API levels, the normal notification is removed, but a playback resumption notification does not appear

On API 31+, we get logs such as these:

2023-12-29 12:13:48.109   747-747   MediaResumeListener     com.android.systemui                 D  Checking for service component for com.smp.musicspeed
2023-12-29 12:13:48.109   747-864   MediaResumeListener     com.android.systemui                 D  Testing if we can connect to ComponentInfo{com.smp.musicspeed/com.smp.musicspeed.player.PlaybackService}
2023-12-29 12:13:48.199   747-864   MediaResumeListener     com.android.systemui                 D  Connected to ComponentInfo{com.smp.musicspeed/com.smp.musicspeed.player.PlaybackService}
2023-12-29 12:13:48.201   747-864   MediaResumeListener     com.android.systemui                 E  Cannot resume with ComponentInfo{com.smp.musicspeed/com.smp.musicspeed.player.PlaybackService}

Media

not applicable

Bug Report

@marcbaechinger
Copy link
Contributor

marcbaechinger commented Dec 29, 2023

Thanks for your report.

I think this is an enhancement more than a bug. The MediaSessionService isn't supposed to support the resumption notification. As mentioned in #672 if this just works with MediaSessionService then we should keep this behavior. I'll change our demo app to see what it needs to make this work for MediaSessionService.

We'll use this issue to track what we find.

@marcbaechinger
Copy link
Contributor

marcbaechinger commented Jan 3, 2024

I have investigated why the playback resumption notification doesn't work with a MediaSessionService and what it would need to make it work for MediaSessionService as well (I tested with API 33).

First, as mentioned in the other issue, System UI uses a documented contract of calling methods of a MediaBrowserService to figure out whether an app supports resumption or not. The MediaLibraryService implements responding to these call under the hood. If the MediaButtonReceiver is found in the manifest MediaLibrarySessionImpl responds by accepting resumption.

In the case of this issue where we advertise a MediaSessionService as a MediaBrowserService in the manifest, this only works partially because MediaSessionServiceLegacyStub that is receiving the calls from the client propagates calls to onGetRoot, but not for onLoadChildren.

I have implemented onLoadChildren quickly to send the signal to SystemUI from onLoadChildren with a MediaSessionService. Doing so makes the resumption notification work and without apps needing to change some code in their MediaSessionService implementation besides of course implementing Callback.onPlaybackResmption.

I'm having some concerns in doing such a change though.

Firstly, I'm not sure whether this will be forward-compatible once SystemUI would migrate to Media3. If the contract is mapped to Media3 1:1 then you would need a MediaLibraryService that is advertised as a such. Then advertising a MediaSessionService as a MediaLibraryService sounds plain wrong. Such a change would then become a hacky solution and apps that did this would (silently) not get the resumption notification anymore for the latest API and end up with a regression that may require quite some effort.

The second reason is that I think for your use case you can just do a MediaLibraryService out of your MediaSessionService with very little effort:

  1. Make your service callback extend from MediaLibrarySession.Callback instead. All additional methods have a default implementation and you don't need to implement them if you only want the resumption notification.
  2. Make you service extend from MediaLibraryService instead of MediaSessionService. This is a one line change in your existing service.
  3. When you build the session you use MediaLibrarySession.Builder instead of MediaSession.Builder. The callback goes into the constructor instead of the setter which should do it.

Because your service is now usingMediaLibraryServiceLegacyStub you get the required handling of System UI resumption contract calls for free. Because the library already makes sure this will work when System UI would migrate to Media3 with the same contract, this solution is save from suffer a regression or requiring work from the app side.

So I'd actually recommend to try this approach because I can't see any downsides of this. The only user of these methods you want to support is System UI and thats already given. No other app than System UI will get the under-the-hood treatment and called from elsewhere the default MediaLibrarySession.Callback implementation responds with a unsupported exception as long as an app doesn't override the defaults.

If you want this safe and now, I'd recommend to go that MediaLibraryService route.

@svenoaks
Copy link
Author

svenoaks commented Jan 3, 2024

@marcbaechinger Thanks for the detailed instructions, the playback resumption notification now is appearing on later API with the MediaLibraryService in use.

I did notice there is one drawback with this, it exacerbates #805. Instead of the dead notification only sticking around for the 2 minutes the service is still alive, it just stays around indefinitely, and is not replaced with playback resumption notification. I am able to reproduce this every time on a Pixel 6a following the procedure, so I hope there can be fix or workaround for #805 soon.

@marcbaechinger
Copy link
Contributor

Ok, cool. Glad that worked.

There is nothing we can do about #805. This is a bug in Android 14 that's reported internally and being worked on.

@svenoaks
Copy link
Author

svenoaks commented Jan 5, 2024

I tested this more, and it seems the playback resumption notification doesn't get shown on Samsung devices with Android 13/14 (not tested on 12, it does show on 11). Changing to the MediaLibraryService only added the notification on emulators and Pixel device. I guess Samsung just doesn't support the notification for the playback resumption API? 🤷‍♂️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants