media: MediaLibraryService.MediaLibrarySession::notifyChildrenChanged doesn't update Android Auto Browse
Version
Media3 1.1.0
More version details
I have an issue when a MediaItem is added locally on the device, I call MediaLibraryService.MediaLibrarySession::notifyChildrenChanged with the updated library, however the browser in Android Auto isn’t updated (the Queue is however updated).
Wondering if there are issues in this area, or if this is not the correct API to call?
Devices that reproduce the issue
Pixel 7 with Sony Android Auto head unit Emulated Pixel 6 and Android Auto head unit emulator I believe all other devices.
Devices that do not reproduce the issue
None
Reproducible in the demo app?
Not tested
Reproduction steps
Connect phone to Android Auto head unit Add an item to the phone’s media database Call the MediaLibraryService.MediaLibrarySession::notifyChildrenChanged API open the Browser on Android Auto Notice new stream is not displayed.
Expected result
New stream should be displayed.
Actual result
New stream is not displayed.
Media
N/A
Bug Report
- You will email the zip file produced by
adb bugreport
to dev.exoplayer@gmail.com after filing this issue.
About this issue
- Original URL
- State: closed
- Created a year ago
- Reactions: 1
- Comments: 28 (8 by maintainers)
Commits related to this issue
- Add default implementation of Callback.onSubscribe The library already maintains the subscribed controllers internally. This change adds `MediaLibrarySession.getSubscribedControllers(mediaId)` to acc... — committed to androidx/media by marcbaechinger 9 months ago
- Add isAutomotiveController and isAutoCompanionController Issue: androidx/media#561 Issue: androidx/media#644 Issue: androidx/media#645 PiperOrigin-RevId: 568948230 — committed to androidx/media by marcbaechinger 9 months ago
- Add default implementation of Callback.onSubscribe The library already maintains the subscribed controllers internally. This change adds `MediaLibrarySession.getSubscribedControllers(mediaId)` to acc... — committed to hugohlln/media by marcbaechinger 9 months ago
- Add isAutomotiveController and isAutoCompanionController Issue: androidx/media#561 Issue: androidx/media#644 Issue: androidx/media#645 PiperOrigin-RevId: 568948230 — committed to hugohlln/media by marcbaechinger 9 months ago
The commit above provides a default implementation of
Callback.onSubscribe(parentId)
. It callsCallback.onGetItem(parentId)
and expects the app to return a browsable item withRESULT_SUCCESS
. If this is the case the browser is automatically subscribed andnotifyChildrenChanged(browser, ...)
is called once immediately.An app can later call
MediaLibrarySession.getSubscribedControllers(parentId)
to get all controllers subscribed to theparentId
and callnotifyChildrenChanged(controller, parentId, ...)
to inform about further changes.This behavior can be changed by overriding
MediaLibrarySession.Callback.onSubscribe()
.This will be included in 1.2.0 for which we will ship the next alpha soon. I’m closing this issue. Please open a new issue if required.
I now grasp the reasoning behind the decision to not have
onSubscribe
automatically returnRESULT_SUCCESS
. Lemme offer my perspective on this matter, based on my observations of media apps (note that this is subjective) :I believe that most media apps don’t require verification of callers. This is primarily because media content, like music, is generally not sensitive (with an emphasis on “most” here). Additionally, it’s rare, if not non-existent, to encounter malicious apps that would attempt to exploit a media app’s browser service solely to access its data. Many music apps either play local files or enable remote music playback, such as the likes of Spotify.
In my experience, there’s often no need to validate the identity of callers. The need for caller identity verification is quite niche and, therefore, negligible. I don’t see any compelling reasons, other than those you’ve mentioned, for
onSubscribe
not to returnRESULT_SUCCESS
by default. Implementing a default limit of 20 subscribers seems practical, and in reality, this limit would likely never be reached. To mitigate any potential confusion, it would be beneficial to include this information in the Javadocs; this way any confusion can be addressed, and users will have clear guidance on the limit.Let alone the fact that this may potentially fix the (probably) broken Android Auto support, where Android Auto is not refreshing the media library (#644) since it’s requiring all browsers to explicitly subscribe in order to receive callbacks. This however will require some way to add the android auto browser passively to the subscriber list.
I had a problem where
notifyChildrenChanged
did nothing even after subscription, but @marcbaechinger’s comment pointed me in the right direction. I should have overriddenonSubscribe
and made it returnFutures.immediateFuture(LibraryResult.ofVoid())
. This way, the subscription seemingly got registered as it should be and everything worked great. Thank you so much for your assistance.By the way, I think the Javadocs should put a lot more emphasis on this, because it’s pretty easy to miss, or maybe make the onSubscribe return a RESULT_SUCCESS by default ?
@marcbaechinger Assuming this is a common requirement for Android Auto implementations, would it make sense to maintain this
Map<String, List<ControllerInfo>>
(keyed byparentId
) inside the library instead? And then add a convenience getter along the lines ofgetSubscribersForParentId(String)
?@ChernyshovYuriy
Hey Yuriy! Nice to meet you again. It’s been a while! 😃
That’s the correct API to use.
I tested your case with the session demo app and this seems to work I’m afraid. So not sure how helpful the following is for you:
I changed
PlaybackService.onGetChildren
of the session demo app as follows:This worked for me by just deploying the session demo app from Android Studio to the Automotive emulator. Then select another app (like News), and then select the demo app again to make it load the library root.
This change adds an
if
statement that is executed once when the children of theparentId
with value[artist]The Kyoto Connection
are requested. I then post a delayedRunnable
that after 10 seconds callssession.notifyChildrenChanged(browser, parentId, children.size, params)
.I added a bit more logs in other classes, but essentially I see at the end that 10 seconds after the category is requested (
19:31:40.609
), the call tonotifyChildrenChanged
makes Automotive request the category again:I’m testing with Automotive emulator API 29 that I randomly created with the device manager.
I noticed that Automotive is only subscribed to a single
parentId
at the time, which is the categroy that is currently displayed. When the user navigates away from thatparentId
, the subscribtion is removed. What I’m trying to say is that the expectation has to be that Automotive is only subscribed to the categroy that is currently duisplayed by the UI. I’m not sure from your report whether this is the case when you test, so wanted to clarify.When testing with https://github.com/googlesamples/android-media-controller I see similar behaviour.
Specifically, with both, Automotive and the controller test app I see that
MediaLirbarySessionImpl.subscriptions
has the subscription for the givenparentId
stored as expected.So this looks fine to me from the library side. The only thing that comes to mind is whether your service overrides
subscribe
/unsubscribe
and returns a result withRESULT_SUCCESS
? Because if not, then the subscription is not registered.