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

Register correct MediaButtonReceiver in MediaSessionLegacyStub #314

Closed
1 task
marcbaechinger opened this issue Apr 11, 2023 · 2 comments
Closed
1 task
Assignees
Labels

Comments

@marcbaechinger
Copy link
Contributor

Media3 Version

Media3 1.0.0

Devices that reproduce the issue

All devices

Devices that do not reproduce the issue

No response

Reproducible in the demo app?

Yes

Reproduction steps

  1. Start session demo app
  2. Start playback.
  3. Pause playback
  4. Dismiss app from recent app.
  5. Press play on a BT headset

Expected result

App is started again

Actual result

CancellationException because the PendingIntent is cancelled.

Media

Any media from the session demo

Bug Report

@marcbaechinger
Copy link
Contributor Author

marcbaechinger commented Apr 11, 2023

When running

adb shell dumbsys media_session

The following pending intent is registered:

Last MediaButtonReceiver: MBR {pi=PendingIntent{c9283b3: PendingIntentRecord{df4cd70 com.example.android.uamp.next startForegroundService}}, type=3

However, the pending intent is already cancelled by the the MediaSessionImpl when the session is released. This is wrong, instead the pending intent needs to be removed entierly.

instead, the MediaSessionLegacyStub should do:

When the session is created:

  1. Check whether the app has a broadcast receiver for ACTION_MEDIA_BUTTON in the manifest. If this is the case this receiver should be used as the component and pending intent passed to the constructor of MediaSessionCompat.
  2. If no app provider receiver is provided and the session is housed by a service, the pending intent is used as the mbr component and pending intent.
  3. If not in a service, a new runtime broadcast receiver is used instead.

When the session is released:

  1. Use mediaSessionCompat.setMediaButtonReceiver(null) unless the app has provided its own broadcast receiver in the manifest.

Note: An app can only be restarted by BT headset if:

  1. A broadcast receiver for ACTION_MEDIA_BUTTON is registered in the manifest by the app developer. With this the app claims to be able to start playback when the service is started with a pending intent from BT headset.
  2. The apps needs to implement playback resumption like described in MediaLibraryService throws ForegroundServiceDidNotStartInTimeException #167 (comment)

A fix for this is in review internally.

Related documentation:
https://developer.android.com/guide/topics/media-apps/mediabuttons

@marcbaechinger marcbaechinger self-assigned this Apr 11, 2023
rohitjoins pushed a commit that referenced this issue Apr 12, 2023
This change selects the best suited media button receiver
component and pending intent when creating the legacy
session. This is important to ensure that a service can
be started with a media button event from BT headsets
after the app has been terminated.

The `MediaSessionLegacyStub` selects the best suited
receiver to be passed to the `MediaSessionCompat`
constructor.

1. When the app has declared a broadcast receiver for
 `ACTION_MEDIA_BUTTON` in the manifest, this broadcast
 receiver is used.
2. When the session is housed in a service, the service
 component is used as a fallback.
3. As a last resort a receiver is created at runtime.

When the `MediaSessionLegacyStub` is released, the media
button receiver is removed unless the app has provided a
media button receiver in the manifest. In this case we
assume the app supports resuming when the BT play intent
arrives at `MediaSessionService.onStartCommand`.

#minor-release

Issue: #167
Issue: #27
Issue: #314
PiperOrigin-RevId: 523638051
rohitjoins pushed a commit that referenced this issue Apr 18, 2023
This change selects the best suited media button receiver
component and pending intent when creating the legacy
session. This is important to ensure that a service can
be started with a media button event from BT headsets
after the app has been terminated.

The `MediaSessionLegacyStub` selects the best suited
receiver to be passed to the `MediaSessionCompat`
constructor.

1. When the app has declared a broadcast receiver for
 `ACTION_MEDIA_BUTTON` in the manifest, this broadcast
 receiver is used.
2. When the session is housed in a service, the service
 component is used as a fallback.
3. As a last resort a receiver is created at runtime.

When the `MediaSessionLegacyStub` is released, the media
button receiver is removed unless the app has provided a
media button receiver in the manifest. In this case we
assume the app supports resuming when the BT play intent
arrives at `MediaSessionService.onStartCommand`.

Issue: #167
Issue: #27
Issue: #314
PiperOrigin-RevId: 523638051
(cherry picked from commit e54a934)
@marcbaechinger
Copy link
Contributor Author

Closing as this is released with 1.0.1.

@androidx androidx locked and limited conversation to collaborators Jun 21, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

1 participant