Allow apps to provide custom Bundle equality logic
I'm having trouble with PlayerInterface.Listener.onTimelineChanged() not being consistently called when my SimpleBasePlayer-derived class updates an item's MediaMetadata.extra bundle and calls invalidateState().
I can see that this behavior is documented in various places:
- https://developer.android.com/reference/androidx/media3/common/MediaMetadata#extras()
Given the complexities of checking the equality of two
Bundleinstances, the contents of these extras are not considered in theequalsandhashCodeimplementation. - https://developer.android.com/reference/androidx/media3/common/MediaMetadata#equals(java.lang.Object)
Note: Equality checking does not consider
extras. - #470
I'm using the extras bundle to store information that changes at runtime (e.g. user-controlled tags), so I need some way to notify clients about changes. In order to force a playlist change when I modify the extras bundle, is my best bet changing the value of some arbitrary field in MediaMetadata, MediaItem, or SimpleBasePlayer.MediaItemData that I'm not currently using?
As you've pointed out, the equality of Bundle extras fields has come up a few times. We have no plans to implement general-purpose equality comparisons for these fields - but we have recently discussed the idea of allowing apps to provide a custom equality comparison, which I think would solve your issue (since you know the key values you want to inspect/compare).
We would likely try and do this in a way that's consistent for all the various extras fields in the library, which will require a bit of design thought (especially how we can keep the comparison consistent across both sides of the session/controller IPC for some of the extras fields) - so I'm afraid we don't have capacity to work on this soon - but it would be helpful if you could let us know if you agree whether this sort of approach would solve your problem.
In the meantime, I suspect what you've proposed is the best approach - or you could wire up your own direct side-channel from your SimpleBasePlayer to notify your clients of changes directly (assuming they are invoking your type directly, rather than via MediaSession/Controller).
@icbaker, thanks for the reply! I think that being able to supply a custom comparison as you suggested would work for my case.
In the meantime, here's what I went with in case it helps anyone else:
if (itemData.equals(old)) {
itemData = itemData.buildUpon().setManifest(object {}).build()
}
(I wasn't using the manifest field for anything.)
Updating title and labels to use this to track the idea of allowing apps to provide a custom equality for bundles.