Skip to content

MediaController eats Listener.onMediaItemTransition() calls available in a player listener #2997

@nift4

Description

@nift4

Version

Media3 main branch

More version details

32a8060

Devices that reproduce the issue

API 36 emulator

Devices that do not reproduce the issue

N/A

Reproducible in the demo app?

Yes

Reproduction steps

  1. apply this patch to demo app
diff --git a/demos/session/src/main/java/androidx/media3/demo/session/PlayerActivity.kt b/demos/session/src/main/java/androidx/media3/demo/session/PlayerActivity.kt
index 1c36a6b6bd..0f1d78288c 100644
--- a/demos/session/src/main/java/androidx/media3/demo/session/PlayerActivity.kt
+++ b/demos/session/src/main/java/androidx/media3/demo/session/PlayerActivity.kt
@@ -143,6 +143,12 @@ class PlayerActivity : AppCompatActivity() {
             mediaItemListAdapter.notifyDataSetChanged()
           }
         }
+          override fun onMediaItemTransition(
+              mediaItem: MediaItem?,
+              reason: @Player.MediaItemTransitionReason Int
+          ) {
+              Log.i("hi", "<CONTROLLER> transition to $mediaItem for reason $reason")
+          }
       }
     )
   }
diff --git a/demos/session_service/src/main/java/androidx/media3/demo/session/DemoPlaybackService.kt b/demos/session_service/src/main/java/androidx/media3/demo/session/DemoPlaybackService.kt
index 81502f5ee8..bef1391ee2 100644
--- a/demos/session_service/src/main/java/androidx/media3/demo/session/DemoPlaybackService.kt
+++ b/demos/session_service/src/main/java/androidx/media3/demo/session/DemoPlaybackService.kt
@@ -32,8 +32,10 @@ import androidx.datastore.dataStore
 import androidx.lifecycle.lifecycleScope
 import androidx.media3.cast.CastPlayer
 import androidx.media3.common.AudioAttributes
+import androidx.media3.common.MediaItem
 import androidx.media3.common.Player
 import androidx.media3.common.listenTo
+import androidx.media3.common.util.Log
 import androidx.media3.common.util.UnstableApi
 import androidx.media3.demo.session.service.R
 import androidx.media3.exoplayer.ExoPlayer
@@ -160,6 +162,14 @@ open class DemoPlaybackService : MediaLibraryService() {
         storeCurrentMediaItem()
       }
     }
+    player.addListener(object : Player.Listener {
+        override fun onMediaItemTransition(
+            mediaItem: MediaItem?,
+            reason: @Player.MediaItemTransitionReason Int
+        ) {
+            Log.i("hi", "<PLAYER> transition to $mediaItem for reason $reason")
+        }
+    })
 
     mediaLibrarySession =
       MediaLibrarySession.Builder(this, player, createLibrarySessionCallback())
  1. launch demo-session
  2. enter any submenu with songs
  3. press the "add to playlist" symbol twice for the same song
  4. then, press the "add to playlist" symbol for another song
  5. press "current playlist" and let playback run (or skip..) until we are about to switch playlist position (from "first song, copy 1" to "first song, copy 2")
  6. after this has occured, inspect logs
  7. now again et playback run (or skip..) until we are about to switch playlist position (from "first song, copy 2" to "second song")
  8. after this has occured, again, inspect logs

Expected result

In both cases, both player and controller log line are visible, ie onMediaItemTransition() is called on controller if it's called on Player.

Actual result

I  <PLAYER> transition to androidx.media3.common.MediaItem@1462c515 for reason 1
[...]
I  <PLAYER> transition to androidx.media3.common.MediaItem@f8bdaa8d for reason 1
I  <CONTROLLER> transition to androidx.media3.common.MediaItem@f8bdaa8d for reason 1

For the transition between two copies of the same song, Player.Listener.onMediaItemTransition() is called when using player.addListener(), but not controller.addListener().
For transition between two different songs, both callbacks are called.

I believe this is the case due to this equals() check:

@Nullable
@Player.MediaItemTransitionReason
Integer mediaItemTransitionReason =
!Objects.equals(oldPlayerInfo.getCurrentMediaItem(), finalPlayerInfo.getCurrentMediaItem())
? finalPlayerInfo.mediaItemTransitionReason
: null;

This is confusing and prevents me from using onMediaItemTransition() as callback to change currentMediaItemIndex in queue UI.

Media

any demo media

Bug Report

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions