Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 08a33bd4 authored by Etienne Ruffieux's avatar Etienne Ruffieux
Browse files

[AVRCP] Skip GLOBAL_PRIORITY MediaSessions

MediaSession with GLOBAL_PRIORITY flag set is created by
Telecom to handle wired headset key events during call.

In Bluetooth, these key events go through HFP and not AVRCP
so we don't want to have them as active media session.

Bug: 266171157
Tag: #feature
Test: atest MediaPlayerListTest, MediaPlayerWrapperTest
Change-Id: Ie017ecd76da14aa955964b5c0daf2a83269c37d7
parent 3e736f59
Loading
Loading
Loading
Loading
+25 −3
Original line number Diff line number Diff line
@@ -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);
        }

@@ -665,7 +671,7 @@ public class MediaPlayerList {

    private void sendMediaUpdate(MediaData data) {
        d("sendMediaUpdate");
        if (mCallback == null) {
        if (mCallback == null || data == null) {
            return;
        }

@@ -680,7 +686,8 @@ public class MediaPlayerList {
        mCallback.run(data);
    }

    private final MediaSessionManager.OnActiveSessionsChangedListener
    @VisibleForTesting
    final MediaSessionManager.OnActiveSessionsChangedListener
            mActiveSessionsChangedListener =
            new MediaSessionManager.OnActiveSessionsChangedListener() {
        @Override
@@ -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())) {
@@ -845,7 +859,8 @@ public class MediaPlayerList {
        }
    };

    private final MediaSessionManager.OnMediaKeyEventSessionChangedListener
    @VisibleForTesting
    final MediaSessionManager.OnMediaKeyEventSessionChangedListener
            mMediaKeyEventSessionChangedListener =
            new MediaSessionManager.OnMediaKeyEventSessionChangedListener() {
                @Override
@@ -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.
+37 −1
Original line number Diff line number Diff line
@@ -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;
@@ -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 {
@@ -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))
@@ -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();
    }
}