Loading android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java +25 −3 Original line number Diff line number Diff line Loading @@ -153,6 +153,12 @@ public class MediaPlayerList { mMediaSessionManager.getActiveSessions(null); for (android.media.session.MediaController controller : controllers) { if ((controller.getFlags() & MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY) != 0) { // GLOBAL_PRIORITY session is created by Telecom to handle call control key events // but Bluetooth Headset profile handles the key events for calls so we don't have // to handle these sessions in AVRCP. continue; } addMediaPlayer(controller); } Loading Loading @@ -665,7 +671,7 @@ public class MediaPlayerList { private void sendMediaUpdate(MediaData data) { d("sendMediaUpdate"); if (mCallback == null) { if (mCallback == null || data == null) { return; } Loading @@ -680,7 +686,8 @@ public class MediaPlayerList { mCallback.run(data); } private final MediaSessionManager.OnActiveSessionsChangedListener @VisibleForTesting final MediaSessionManager.OnActiveSessionsChangedListener mActiveSessionsChangedListener = new MediaSessionManager.OnActiveSessionsChangedListener() { @Override Loading @@ -699,6 +706,13 @@ public class MediaPlayerList { HashSet<String> addedPackages = new HashSet<String>(); for (int i = 0; i < newControllers.size(); i++) { if ((newControllers.get(i).getFlags() & MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY) != 0) { Log.d(TAG, "onActiveSessionsChanged: controller: " + newControllers.get(i).getPackageName() + " ignored due to global priority flag"); continue; } Log.d(TAG, "onActiveSessionsChanged: controller: " + newControllers.get(i).getPackageName()); if (addedPackages.contains(newControllers.get(i).getPackageName())) { Loading Loading @@ -845,7 +859,8 @@ public class MediaPlayerList { } }; private final MediaSessionManager.OnMediaKeyEventSessionChangedListener @VisibleForTesting final MediaSessionManager.OnMediaKeyEventSessionChangedListener mMediaKeyEventSessionChangedListener = new MediaSessionManager.OnMediaKeyEventSessionChangedListener() { @Override Loading @@ -862,6 +877,13 @@ public class MediaPlayerList { if (token != null) { android.media.session.MediaController controller = new android.media.session.MediaController(mContext, token); if ((controller.getFlags() & MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY) != 0) { // Skip adding controller for GLOBAL_PRIORITY session. Log.i(TAG, "onMediaKeyEventSessionChanged," + " ignoring global priority session"); return; } if (!haveMediaPlayer(controller.getPackageName())) { // Since we have a controller, we can try to to recover by adding the // player and then setting it as active. Loading android/app/tests/unit/src/com/android/bluetooth/audio_util/MediaPlayerListTest.java +37 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static org.mockito.Mockito.*; import android.content.Context; import android.content.pm.PackageManager; import android.media.AudioManager; import android.media.session.MediaSession; import android.media.session.MediaSessionManager; import android.media.session.PlaybackState; import android.os.Looper; Loading Loading @@ -57,6 +58,7 @@ public class MediaPlayerListTest { private final String mFlagDexmarker = System.getProperty("dexmaker.share_classloader", "false"); private MediaPlayerWrapper.Callback mActivePlayerCallback; private MediaSessionManager mMediaSessionManager; @Before public void setUp() throws Exception { Loading @@ -76,7 +78,7 @@ public class MediaPlayerListTest { when(mMockContext.getSystemServiceName(AudioManager.class)) .thenReturn(Context.AUDIO_SERVICE); MediaSessionManager mMediaSessionManager = InstrumentationRegistry.getTargetContext() mMediaSessionManager = InstrumentationRegistry.getTargetContext() .getSystemService(MediaSessionManager.class); PackageManager mockPackageManager = mock(PackageManager.class); when(mMockContext.getSystemService(Context.MEDIA_SESSION_SERVICE)) Loading Loading @@ -187,4 +189,38 @@ public class MediaPlayerListTest { verify(mMediaUpdateCallback, never()).run(any()); } @Test public void testSkipGlobalPrioritySession() { // Store current active media player. MediaPlayerWrapper activeMediaPlayer = mMediaPlayerList.getActivePlayer(); // Create MediaSession with GLOBAL_PRIORITY flag. MediaSession session = new MediaSession( InstrumentationRegistry.getTargetContext(), MediaPlayerListTest.class.getSimpleName()); session.setFlags(MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY | MediaSession.FLAG_HANDLES_MEDIA_BUTTONS); // Use MediaPlayerList onMediaKeyEventSessionChanged callback to send the new session. mMediaPlayerList.mMediaKeyEventSessionChangedListener.onMediaKeyEventSessionChanged( session.getController().getPackageName(), session.getSessionToken()); // Retrieve the current available controllers ArrayList<android.media.session.MediaController> currentControllers = new ArrayList<android.media.session.MediaController>( mMediaSessionManager.getActiveSessions(null)); // Add the new session currentControllers.add(session.getController()); // Use MediaPlayerList onActiveSessionsChanged callback to send the new session. mMediaPlayerList.mActiveSessionsChangedListener.onActiveSessionsChanged( currentControllers); // Retrieve the new active MediaSession. MediaPlayerWrapper newActiveMediaPlayer = mMediaPlayerList.getActivePlayer(); // Should be the same as before. Assert.assertEquals(activeMediaPlayer, newActiveMediaPlayer); session.release(); } } Loading
android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java +25 −3 Original line number Diff line number Diff line Loading @@ -153,6 +153,12 @@ public class MediaPlayerList { mMediaSessionManager.getActiveSessions(null); for (android.media.session.MediaController controller : controllers) { if ((controller.getFlags() & MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY) != 0) { // GLOBAL_PRIORITY session is created by Telecom to handle call control key events // but Bluetooth Headset profile handles the key events for calls so we don't have // to handle these sessions in AVRCP. continue; } addMediaPlayer(controller); } Loading Loading @@ -665,7 +671,7 @@ public class MediaPlayerList { private void sendMediaUpdate(MediaData data) { d("sendMediaUpdate"); if (mCallback == null) { if (mCallback == null || data == null) { return; } Loading @@ -680,7 +686,8 @@ public class MediaPlayerList { mCallback.run(data); } private final MediaSessionManager.OnActiveSessionsChangedListener @VisibleForTesting final MediaSessionManager.OnActiveSessionsChangedListener mActiveSessionsChangedListener = new MediaSessionManager.OnActiveSessionsChangedListener() { @Override Loading @@ -699,6 +706,13 @@ public class MediaPlayerList { HashSet<String> addedPackages = new HashSet<String>(); for (int i = 0; i < newControllers.size(); i++) { if ((newControllers.get(i).getFlags() & MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY) != 0) { Log.d(TAG, "onActiveSessionsChanged: controller: " + newControllers.get(i).getPackageName() + " ignored due to global priority flag"); continue; } Log.d(TAG, "onActiveSessionsChanged: controller: " + newControllers.get(i).getPackageName()); if (addedPackages.contains(newControllers.get(i).getPackageName())) { Loading Loading @@ -845,7 +859,8 @@ public class MediaPlayerList { } }; private final MediaSessionManager.OnMediaKeyEventSessionChangedListener @VisibleForTesting final MediaSessionManager.OnMediaKeyEventSessionChangedListener mMediaKeyEventSessionChangedListener = new MediaSessionManager.OnMediaKeyEventSessionChangedListener() { @Override Loading @@ -862,6 +877,13 @@ public class MediaPlayerList { if (token != null) { android.media.session.MediaController controller = new android.media.session.MediaController(mContext, token); if ((controller.getFlags() & MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY) != 0) { // Skip adding controller for GLOBAL_PRIORITY session. Log.i(TAG, "onMediaKeyEventSessionChanged," + " ignoring global priority session"); return; } if (!haveMediaPlayer(controller.getPackageName())) { // Since we have a controller, we can try to to recover by adding the // player and then setting it as active. Loading
android/app/tests/unit/src/com/android/bluetooth/audio_util/MediaPlayerListTest.java +37 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static org.mockito.Mockito.*; import android.content.Context; import android.content.pm.PackageManager; import android.media.AudioManager; import android.media.session.MediaSession; import android.media.session.MediaSessionManager; import android.media.session.PlaybackState; import android.os.Looper; Loading Loading @@ -57,6 +58,7 @@ public class MediaPlayerListTest { private final String mFlagDexmarker = System.getProperty("dexmaker.share_classloader", "false"); private MediaPlayerWrapper.Callback mActivePlayerCallback; private MediaSessionManager mMediaSessionManager; @Before public void setUp() throws Exception { Loading @@ -76,7 +78,7 @@ public class MediaPlayerListTest { when(mMockContext.getSystemServiceName(AudioManager.class)) .thenReturn(Context.AUDIO_SERVICE); MediaSessionManager mMediaSessionManager = InstrumentationRegistry.getTargetContext() mMediaSessionManager = InstrumentationRegistry.getTargetContext() .getSystemService(MediaSessionManager.class); PackageManager mockPackageManager = mock(PackageManager.class); when(mMockContext.getSystemService(Context.MEDIA_SESSION_SERVICE)) Loading Loading @@ -187,4 +189,38 @@ public class MediaPlayerListTest { verify(mMediaUpdateCallback, never()).run(any()); } @Test public void testSkipGlobalPrioritySession() { // Store current active media player. MediaPlayerWrapper activeMediaPlayer = mMediaPlayerList.getActivePlayer(); // Create MediaSession with GLOBAL_PRIORITY flag. MediaSession session = new MediaSession( InstrumentationRegistry.getTargetContext(), MediaPlayerListTest.class.getSimpleName()); session.setFlags(MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY | MediaSession.FLAG_HANDLES_MEDIA_BUTTONS); // Use MediaPlayerList onMediaKeyEventSessionChanged callback to send the new session. mMediaPlayerList.mMediaKeyEventSessionChangedListener.onMediaKeyEventSessionChanged( session.getController().getPackageName(), session.getSessionToken()); // Retrieve the current available controllers ArrayList<android.media.session.MediaController> currentControllers = new ArrayList<android.media.session.MediaController>( mMediaSessionManager.getActiveSessions(null)); // Add the new session currentControllers.add(session.getController()); // Use MediaPlayerList onActiveSessionsChanged callback to send the new session. mMediaPlayerList.mActiveSessionsChangedListener.onActiveSessionsChanged( currentControllers); // Retrieve the new active MediaSession. MediaPlayerWrapper newActiveMediaPlayer = mMediaPlayerList.getActivePlayer(); // Should be the same as before. Assert.assertEquals(activeMediaPlayer, newActiveMediaPlayer); session.release(); } }