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

Commit 3e98792e authored by Alexandr Shabalin's avatar Alexandr Shabalin Committed by Android (Google) Code Review
Browse files

Merge "Remove MediaDevice list filtering methods from InfoMediaManager." into main

parents 7763531d 7b238ed7
Loading
Loading
Loading
Loading
+3 −46
Original line number Diff line number Diff line
@@ -605,50 +605,6 @@ public abstract class InfoMediaManager {
        return true;
    }

    /**
     * Returns the list of {@link MediaDevice media devices} that can be added to the current {@link
     * RoutingSessionInfo routing session}.
     */
    @NonNull
    List<MediaDevice> getSelectableMediaDevices() {
        synchronized (mLock) {
            return mMediaDevices.stream().filter(MediaDevice::isSelectable).toList();
        }
    }

    /**
     * Returns the list of {@link MediaDevice media devices} that can be transferred to with the
     * current {@link RoutingSessionInfo routing session} by the media route provider.
     */
    @NonNull
    List<MediaDevice> getTransferableMediaDevices() {
        synchronized (mLock) {
            return mMediaDevices.stream().filter(MediaDevice::isTransferable).toList();
        }
    }

    /**
     * Returns the list of {@link MediaDevice media devices} that can be deselected from the current
     * {@link RoutingSessionInfo routing session}.
     */
    @NonNull
    List<MediaDevice> getDeselectableMediaDevices() {
        synchronized (mLock) {
            return mMediaDevices.stream().filter(MediaDevice::isDeselectable).toList();
        }
    }

    /**
     * Returns the list of {@link MediaDevice media devices} that are selected in the current {@link
     * RoutingSessionInfo routing session}.
     */
    @NonNull
    List<MediaDevice> getSelectedMediaDevices() {
        synchronized (mLock) {
            return mMediaDevices.stream().filter(MediaDevice::isSelected).toList();
        }
    }

    /* package */ void adjustDeviceVolume(MediaDevice device, int volume) {
        Log.i(TAG, "adjustDeviceVolume(), device = " + device.getName() + "/" + device.getId()
                + " volume = " + volume);
@@ -780,8 +736,9 @@ public abstract class InfoMediaManager {

    private boolean isSuggestedDeviceSelected(
            @NonNull SuggestedDeviceState newSuggestedDeviceState) {
        return getSelectedMediaDevices().stream().anyMatch(device ->
                Objects.equals(
        return mMediaDevices.stream().anyMatch(device ->
                device.isSelected()
                && Objects.equals(
                        device.getId(),
                        newSuggestedDeviceState
                                .getSuggestedDeviceInfo()
+0 −38
Original line number Diff line number Diff line
@@ -415,35 +415,6 @@ public class LocalMediaManager implements BluetoothCallback {
        return mInfoMediaManager.removeDeviceFromPlayMedia(device);
    }

    /**
     * Get the MediaDevice list that can be added to current media.
     *
     * @return list of MediaDevice
     */
    public List<MediaDevice> getSelectableMediaDevice() {
        return mInfoMediaManager.getSelectableMediaDevices();
    }

    /**
     * Gets the MediaDevice list that can be transferred to with the current media session by the
     * media route provider.
     *
     * @return list of MediaDevice
     */
    @NonNull
    public List<MediaDevice> getTransferableMediaDevices() {
        return mInfoMediaManager.getTransferableMediaDevices();
    }

    /**
     * Get the MediaDevice list that can be removed from current media session.
     *
     * @return list of MediaDevice
     */
    public List<MediaDevice> getDeselectableMediaDevice() {
        return mInfoMediaManager.getDeselectableMediaDevices();
    }

    /**
     * Get the current session's release type.
     *
@@ -460,15 +431,6 @@ public class LocalMediaManager implements BluetoothCallback {
        return mInfoMediaManager.releaseSession();
    }

    /**
     * Get the MediaDevice list that has been selected to current media.
     *
     * @return list of MediaDevice
     */
    public List<MediaDevice> getSelectedMediaDevice() {
        return mInfoMediaManager.getSelectedMediaDevices();
    }

    /**
     * Requests a volume change for a specific media device.
     *
+8 −160
Original line number Diff line number Diff line
@@ -30,7 +30,6 @@ import static android.media.MediaRoute2ProviderService.REASON_UNKNOWN_ERROR;
import static com.android.settingslib.media.LocalMediaManager.MediaDeviceState.STATE_SELECTED;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
@@ -59,9 +58,6 @@ import android.os.Build;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.media.flags.Flags;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
@@ -87,11 +83,6 @@ import org.robolectric.util.ReflectionHelpers;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

@RunWith(RobolectricTestRunner.class)
public class InfoMediaManagerTest {
@@ -683,10 +674,14 @@ public class InfoMediaManagerTest {

        when(mRouterManager.getRoutingSessions(TEST_PACKAGE_NAME))
                .thenReturn(List.of(TEST_SYSTEM_ROUTING_SESSION));
        List<MediaDevice> transferableDevices = mInfoMediaManager.getTransferableMediaDevices();
        List<MediaDevice> selectedDevices = mInfoMediaManager.getSelectedMediaDevices();
        List<MediaDevice> selectableDevices = mInfoMediaManager.getSelectableMediaDevices();
        List<MediaDevice> deselectableDevices = mInfoMediaManager.getDeselectableMediaDevices();
        List<MediaDevice> transferableDevices = mInfoMediaManager.mMediaDevices.stream().filter(
                MediaDevice::isTransferable).toList();
        List<MediaDevice> selectedDevices = mInfoMediaManager.mMediaDevices.stream().filter(
                MediaDevice::isSelected).toList();
        List<MediaDevice> selectableDevices = mInfoMediaManager.mMediaDevices.stream().filter(
                MediaDevice::isSelectable).toList();
        List<MediaDevice> deselectableDevices = mInfoMediaManager.mMediaDevices.stream().filter(
                MediaDevice::isDeselectable).toList();

        assertThat(transferableDevices.size()).isEqualTo(3);
        // The "COMPLEX" device is transferable because it's a non-system route for a system session
@@ -731,16 +726,6 @@ public class InfoMediaManagerTest {
        assertThat(deselectableDevice.isDeselectable()).isTrue();
    }

    @Test
    public void getSelectableMediaDevice_notContainPackageName_returnEmpty() {
        final RoutingSessionInfo info = mock(RoutingSessionInfo.class);

        when(mRoutingController.getRoutingSessionInfo()).thenReturn(info);
        when(info.getClientPackageName()).thenReturn("com.fake.packagename");

        assertThat(mInfoMediaManager.getSelectableMediaDevices()).isEmpty();
    }

    @Test
    public void adjustSessionVolume_routingSessionInfoIsNull_noCrash() {
        mInfoMediaManager.adjustSessionVolume(null, 10);
@@ -868,143 +853,6 @@ public class InfoMediaManagerTest {
        verify(mCallback, times(2)).onDeviceListAdded(any());
    }

    @Test
    public void onDeviceListAdded_callingGettersInCallback_shouldNotCauseDeadlock()
            throws InterruptedException {
        when(mRouterManager.getRoutingSessions(anyString())).thenReturn(
                List.of(TEST_SYSTEM_ROUTING_SESSION));
        when(mRouterManager.getSelectedRoutes(any())).thenReturn(
                List.of(TEST_SELECTED_SYSTEM_ROUTE));

        ExecutorService executor = Executors.newSingleThreadExecutor();

        final CountDownLatch callbackEnteredLatch = new CountDownLatch(1);
        final CountDownLatch mainThreadActionLatch = new CountDownLatch(1);

        final AtomicBoolean callbackCompletedSuccessfully = new AtomicBoolean(false);

        InfoMediaManager.MediaDeviceCallback mediaDeviceCallback =
                new InfoMediaManager.MediaDeviceCallback() {
                    @Override
                    public void onDeviceListAdded(@NonNull List<MediaDevice> devices) {
                        try {
                            callbackEnteredLatch.countDown();
                            // Pausing the callback and waiting for the main thread to act.
                            boolean mainThreadUnblocked = mainThreadActionLatch.await(
                                    ASYNC_TIMEOUT_SECONDS, TimeUnit.SECONDS);
                            callbackCompletedSuccessfully.set(mainThreadUnblocked);
                        } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                        }
                    }

                    @Override
                    public void onDeviceListRemoved(@NonNull List<MediaDevice> devices) {
                    }

                    @Override
                    public void onConnectedDeviceChanged(@Nullable String id) {
                    }

                    @Override
                    public void onRequestFailed(int reason) {
                    }
                };


        // This will invoke a callback in the background thread.
        executor.submit(() -> mInfoMediaManager.registerCallback(mediaDeviceCallback));

        if (!callbackEnteredLatch.await(ASYNC_TIMEOUT_SECONDS, TimeUnit.SECONDS)) {
            throw new AssertionError("Callback was never entered.");
        }

        // While the callback execution is on pause, make a call to a potential blocking method.
        mInfoMediaManager.getSelectedMediaDevices();

        // Signal the waiting callback thread that it can now proceed.
        mainThreadActionLatch.countDown();
        executor.shutdown();
        assertWithMessage("Deadlock detected! The test timed out.").that(
                executor.awaitTermination(ASYNC_TIMEOUT_SECONDS, TimeUnit.SECONDS)).isTrue();

        assertThat(callbackCompletedSuccessfully.get()).isTrue();
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_SUGGESTED_DEVICE_API)
    public void onSuggestedDeviceUpdated_callingGettersInCallback_shouldNotCauseDeadlock()
            throws InterruptedException {
        ExecutorService executor = Executors.newSingleThreadExecutor();

        final CountDownLatch callbackEnteredLatch = new CountDownLatch(1);
        final CountDownLatch mainThreadActionLatch = new CountDownLatch(1);

        final AtomicBoolean callbackCompletedSuccessfully = new AtomicBoolean(false);

        InfoMediaManager.MediaDeviceCallback mediaDeviceCallback =
                new InfoMediaManager.MediaDeviceCallback() {
                    @Override
                    public void onDeviceListAdded(@NonNull List<MediaDevice> devices) {
                    }

                    @Override
                    public void onDeviceListRemoved(@NonNull List<MediaDevice> devices) {
                    }

                    @Override
                    public void onConnectedDeviceChanged(@Nullable String id) {
                    }

                    @Override
                    public void onRequestFailed(int reason) {
                    }

                    @Override
                    public void onSuggestedDeviceUpdated(
                            @Nullable SuggestedDeviceState suggestedDevice) {
                        try {
                            callbackEnteredLatch.countDown();
                            // Pausing the callback and waiting for the main thread to act.
                            boolean mainThreadUnblocked = mainThreadActionLatch.await(
                                    ASYNC_TIMEOUT_SECONDS, TimeUnit.SECONDS);
                            callbackCompletedSuccessfully.set(mainThreadUnblocked);
                        } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                        }
                    }
                };

        SuggestedDeviceInfo suggestedDeviceInfo = new SuggestedDeviceInfo.Builder("device_name",
                TEST_ID_3, 0).build();
        setAvailableRoutesList(TEST_PACKAGE_NAME);

        // This will invoke a callback in the background thread.
        executor.submit(() -> {
            mInfoMediaManager.registerCallback(mediaDeviceCallback);
            verify(mRouter2).registerDeviceSuggestionsUpdatesCallback(any(),
                    mDeviceSuggestionsUpdatesCallback.capture());

            mDeviceSuggestionsUpdatesCallback.getValue().onSuggestionsUpdated("random_package_name",
                    List.of(suggestedDeviceInfo));
        });

        if (!callbackEnteredLatch.await(ASYNC_TIMEOUT_SECONDS, TimeUnit.SECONDS)) {
            throw new AssertionError("Callback was never entered.");
        }

        // While the callback execution is on pause, make a call to a potential blocking method.
        mInfoMediaManager.getSelectedMediaDevices();

        // Signal the waiting callback thread that it can now proceed.
        mainThreadActionLatch.countDown();
        executor.shutdown();
        assertWithMessage("Deadlock detected! The test timed out.").that(
                executor.awaitTermination(ASYNC_TIMEOUT_SECONDS, TimeUnit.SECONDS)).isTrue();

        assertThat(callbackCompletedSuccessfully.get()).isTrue();
    }

    @Test
    public void addMediaDevice_verifyDeviceTypeCanCorrespondToMediaDevice() {
        final MediaRoute2Info route2Info = mock(MediaRoute2Info.class);
+0 −5
Original line number Diff line number Diff line
@@ -71,9 +71,4 @@ public class NoOpInfoMediaManagerTest {
        // Make sure we return a placeholder routing session so that we avoid OOB exceptions.
        assertThat(mInfoMediaManager.getRoutingSessionsForPackage()).hasSize(1);
    }

    @Test
    public void getSelectedMediaDevices_returnsEmptyList() {
        assertThat(mInfoMediaManager.getSelectedMediaDevices()).isEmpty();
    }
}
+31 −59
Original line number Diff line number Diff line
@@ -53,7 +53,6 @@ import com.android.settingslib.utils.ThreadUtils;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.res.R;

import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.ListeningExecutorService;

import org.junit.Before;
@@ -201,10 +200,8 @@ public class MediaOutputAdapterLegacyTest extends SysuiTestCase {

    @Test
    public void onBindViewHolder_bindConnectedRemoteDevice_verifyView() {
        when(mMediaSwitchingController.getSelectedMediaDevice())
                .thenReturn(ImmutableList.of(mMediaDevice1));
        when(mMediaSwitchingController.getSelectableMediaDevice())
                .thenReturn(ImmutableList.of(mMediaDevice2));
        when(mMediaDevice1.isSelected()).thenReturn(true);
        when(mMediaDevice2.isSelectable()).thenReturn(true);
        when(mMediaSwitchingController.isCurrentConnectedDeviceRemote()).thenReturn(true);
        mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
                .onCreateViewHolder(new LinearLayout(mContext), 0);
@@ -222,8 +219,7 @@ public class MediaOutputAdapterLegacyTest extends SysuiTestCase {

    @Test
    public void onBindViewHolder_bindConnectedRemoteDevice_verifyContentDescriptionNotNull() {
        when(mMediaSwitchingController.getSelectableMediaDevice())
                .thenReturn(ImmutableList.of(mMediaDevice2));
        when(mMediaDevice2.isSelectable()).thenReturn(true);
        when(mMediaSwitchingController.isCurrentConnectedDeviceRemote()).thenReturn(true);
        mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
                .onCreateViewHolder(new LinearLayout(mContext), 0);
@@ -239,7 +235,6 @@ public class MediaOutputAdapterLegacyTest extends SysuiTestCase {

    @Test
    public void onBindViewHolder_bindSingleConnectedRemoteDevice_verifyView() {
        when(mMediaSwitchingController.getSelectableMediaDevice()).thenReturn(ImmutableList.of());
        when(mMediaSwitchingController.isCurrentConnectedDeviceRemote()).thenReturn(true);
        mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
                .onCreateViewHolder(new LinearLayout(mContext), 0);
@@ -257,7 +252,6 @@ public class MediaOutputAdapterLegacyTest extends SysuiTestCase {
    @Test
    public void onBindViewHolder_bindConnectedRemoteDeviceWithOnGoingSession_verifyView() {
        when(mMediaDevice1.hasOngoingSession()).thenReturn(true);
        when(mMediaSwitchingController.getSelectableMediaDevice()).thenReturn(ImmutableList.of());
        when(mMediaSwitchingController.isCurrentConnectedDeviceRemote()).thenReturn(true);
        mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
                .onCreateViewHolder(new LinearLayout(mContext), 0);
@@ -278,7 +272,6 @@ public class MediaOutputAdapterLegacyTest extends SysuiTestCase {
    public void onBindViewHolder_bindConnectedRemoteDeviceWithHostOnGoingSession_verifyView() {
        when(mMediaDevice1.hasOngoingSession()).thenReturn(true);
        when(mMediaDevice1.isHostForOngoingSession()).thenReturn(true);
        when(mMediaSwitchingController.getSelectableMediaDevice()).thenReturn(ImmutableList.of());
        when(mMediaSwitchingController.isCurrentConnectedDeviceRemote()).thenReturn(true);
        mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
                .onCreateViewHolder(new LinearLayout(mContext), 0);
@@ -386,9 +379,7 @@ public class MediaOutputAdapterLegacyTest extends SysuiTestCase {

    @Test
    public void onBindViewHolder_bindSelectableDevice_verifyView() {
        List<MediaDevice> selectableDevices = new ArrayList<>();
        selectableDevices.add(mMediaDevice2);
        when(mMediaSwitchingController.getSelectableMediaDevice()).thenReturn(selectableDevices);
        when(mMediaDevice2.isSelectable()).thenReturn(true);
        mMediaOutputAdapter.onBindViewHolder(mViewHolder, 1);

        assertThat(mViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE);
@@ -406,10 +397,11 @@ public class MediaOutputAdapterLegacyTest extends SysuiTestCase {

    @Test
    public void onBindViewHolder_bindDeselectableDevice_verifyView() {
        when(mMediaSwitchingController.getSelectedMediaDevice()).thenReturn(
                List.of(mMediaDevice1, mMediaDevice2));
        when(mMediaSwitchingController.getDeselectableMediaDevice()).thenReturn(
                List.of(mMediaDevice1, mMediaDevice2));
        when(mMediaDevice1.isSelected()).thenReturn(true);
        when(mMediaDevice1.isDeselectable()).thenReturn(true);
        when(mMediaDevice2.isSelected()).thenReturn(true);
        when(mMediaDevice2.isDeselectable()).thenReturn(true);
        when(mMediaSwitchingController.hasGroupPlayback()).thenReturn(true);
        when(mMediaSwitchingController.hasGroupPlayback()).thenReturn(true);

        mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
@@ -428,20 +420,17 @@ public class MediaOutputAdapterLegacyTest extends SysuiTestCase {

    @Test
    public void onBindViewHolder_changingSelectedValue_doesntTriggerChangeListener() {
        List<MediaDevice> selectableDevices = List.of(mMediaDevice2);
        List<MediaDevice> selectedDevices = new ArrayList<>();
        selectedDevices.add(mMediaDevice1);
        when(mMediaSwitchingController.getSelectableMediaDevice()).thenReturn(selectableDevices);
        when(mMediaSwitchingController.getSelectedMediaDevice()).thenReturn(selectedDevices);
        when(mMediaSwitchingController.getDeselectableMediaDevice()).thenReturn(
                List.of(mMediaDevice1, mMediaDevice2));
        when(mMediaDevice1.isSelected()).thenReturn(true);
        when(mMediaDevice1.isDeselectable()).thenReturn(true);
        when(mMediaDevice2.isSelectable()).thenReturn(true);
        when(mMediaDevice2.isDeselectable()).thenReturn(true);

        // mMediaDevice2 is selected
        mMediaOutputAdapter.onBindViewHolder(mViewHolder, 1);
        assertThat(mViewHolder.mCheckBox.isChecked()).isFalse();

        // changing the selected state programmatically (not a user click)
        selectedDevices.add(mMediaDevice2);
        when(mMediaDevice2.isSelected()).thenReturn(true);

        mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
        // Expand the group control.
@@ -729,9 +718,7 @@ public class MediaOutputAdapterLegacyTest extends SysuiTestCase {

    @Test
    public void onGroupActionTriggered_clicksEndAreaOfSelectableDevice_triggerGrouping() {
        List<MediaDevice> selectableDevices = new ArrayList<>();
        selectableDevices.add(mMediaDevice2);
        when(mMediaSwitchingController.getSelectableMediaDevice()).thenReturn(selectableDevices);
        when(mMediaDevice2.isSelectable()).thenReturn(true);
        mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
                .onCreateViewHolder(new LinearLayout(mContext), 0);
        mMediaOutputAdapter.onBindViewHolder(mViewHolder, 1);
@@ -743,11 +730,8 @@ public class MediaOutputAdapterLegacyTest extends SysuiTestCase {

    @Test
    public void clickFullItemOfSelectableDevice_hasListingPreference_verifyConnectDevice() {
        List<MediaDevice> mediaDevices = new ArrayList<>();
        mediaDevices.add(mMediaDevice2);
        when(mMediaDevice2.hasRouteListingPreferenceItem()).thenReturn(true);
        when(mMediaSwitchingController.getSelectableMediaDevice()).thenReturn(mediaDevices);
        when(mMediaSwitchingController.getTransferableMediaDevices()).thenReturn(List.of());
        when(mMediaDevice2.isSelectable()).thenReturn(true);
        when(mMediaSwitchingController.isCurrentOutputDeviceHasSessionOngoing()).thenReturn(false);
        mMediaOutputAdapter.onBindViewHolder(mViewHolder, 1);

@@ -765,11 +749,9 @@ public class MediaOutputAdapterLegacyTest extends SysuiTestCase {

    @Test
    public void clickFullItemOfSelectableDevice_isTransferable_verifyConnectDevice() {
        List<MediaDevice> mediaDevices = new ArrayList<>();
        mediaDevices.add(mMediaDevice2);
        when(mMediaDevice2.hasRouteListingPreferenceItem()).thenReturn(false);
        when(mMediaSwitchingController.getSelectableMediaDevice()).thenReturn(mediaDevices);
        when(mMediaSwitchingController.getTransferableMediaDevices()).thenReturn(mediaDevices);
        when(mMediaDevice2.isTransferable()).thenReturn(true);
        when(mMediaDevice2.isSelectable()).thenReturn(true);
        when(mMediaSwitchingController.isCurrentOutputDeviceHasSessionOngoing()).thenReturn(false);
        mMediaOutputAdapter.onBindViewHolder(mViewHolder, 1);

@@ -787,11 +769,8 @@ public class MediaOutputAdapterLegacyTest extends SysuiTestCase {

    @Test
    public void clickFullItemOfSelectableDevice_notTransferable_verifyNotConnectDevice() {
        List<MediaDevice> mediaDevices = new ArrayList<>();
        mediaDevices.add(mMediaDevice2);
        when(mMediaDevice2.hasRouteListingPreferenceItem()).thenReturn(false);
        when(mMediaSwitchingController.getSelectableMediaDevice()).thenReturn(mediaDevices);
        when(mMediaSwitchingController.getTransferableMediaDevices()).thenReturn(List.of());
        when(mMediaDevice2.isSelectable()).thenReturn(true);
        when(mMediaSwitchingController.isCurrentOutputDeviceHasSessionOngoing()).thenReturn(false);
        mMediaOutputAdapter.onBindViewHolder(mViewHolder, 1);

@@ -809,12 +788,9 @@ public class MediaOutputAdapterLegacyTest extends SysuiTestCase {

    @Test
    public void onGroupActionTriggered_clickSelectedRemoteDevice_triggerUngrouping() {
        when(mMediaSwitchingController.getSelectableMediaDevice())
                .thenReturn(ImmutableList.of(mMediaDevice2));
        when(mMediaSwitchingController.getDeselectableMediaDevice())
                .thenReturn(ImmutableList.of(mMediaDevice1));
        when(mMediaSwitchingController.getSelectedMediaDevice())
                .thenReturn(ImmutableList.of(mMediaDevice1));
        when(mMediaDevice1.isSelected()).thenReturn(true);
        when(mMediaDevice1.isDeselectable()).thenReturn(true);
        when(mMediaDevice2.isSelectable()).thenReturn(true);
        when(mMediaSwitchingController.isCurrentConnectedDeviceRemote()).thenReturn(true);
        mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
                .onCreateViewHolder(new LinearLayout(mContext), 0);
@@ -827,8 +803,7 @@ public class MediaOutputAdapterLegacyTest extends SysuiTestCase {

    @Test
    public void onBindViewHolder_hasVolumeAdjustmentRestriction_verifySeekbarDisabled() {
        when(mMediaSwitchingController.getSelectedMediaDevice()).thenReturn(
                List.of(mMediaDevice1));
        when(mMediaDevice1.isSelected()).thenReturn(true);
        when(mMediaSwitchingController.isCurrentConnectedDeviceRemote()).thenReturn(true);
        when(mMediaSwitchingController.hasAdjustVolumeUserRestriction()).thenReturn(true);
        mMediaOutputAdapter.updateItems();
@@ -1006,11 +981,8 @@ public class MediaOutputAdapterLegacyTest extends SysuiTestCase {

    @Test
    public void deviceCanNotBeDeselected_verifyView() {
        List<MediaDevice> selectedDevices = new ArrayList<>();
        selectedDevices.add(mMediaDevice1);
        when(mMediaSwitchingController.getSelectableMediaDevice()).thenReturn(selectedDevices);
        when(mMediaSwitchingController.getSelectedMediaDevice()).thenReturn(selectedDevices);
        when(mMediaSwitchingController.getDeselectableMediaDevice()).thenReturn(new ArrayList<>());
        when(mMediaDevice1.isSelected()).thenReturn(true);
        when(mMediaDevice2.isSelectable()).thenReturn(true);

        mViewHolder = (MediaOutputAdapterLegacy.MediaDeviceViewHolderLegacy) mMediaOutputAdapter
                .onCreateViewHolder(
@@ -1026,12 +998,12 @@ public class MediaOutputAdapterLegacyTest extends SysuiTestCase {
    }

    private void initializeSession() {
        List<MediaDevice> selectedDevices = new ArrayList<>();
        selectedDevices.add(mMediaDevice1);
        selectedDevices.add(mMediaDevice2);
        when(mMediaSwitchingController.getSelectableMediaDevice()).thenReturn(selectedDevices);
        when(mMediaSwitchingController.getSelectedMediaDevice()).thenReturn(selectedDevices);
        when(mMediaSwitchingController.getDeselectableMediaDevice()).thenReturn(selectedDevices);
        when(mMediaDevice1.isSelected()).thenReturn(true);
        when(mMediaDevice1.isSelectable()).thenReturn(true);
        when(mMediaDevice1.isDeselectable()).thenReturn(true);
        when(mMediaDevice2.isSelected()).thenReturn(true);
        when(mMediaDevice2.isSelectable()).thenReturn(true);
        when(mMediaDevice2.isDeselectable()).thenReturn(true);
        when(mMediaSwitchingController.hasGroupPlayback()).thenReturn(true);

        mMediaOutputAdapter = new MediaOutputAdapterLegacy(mMediaSwitchingController, mMainExecutor,
Loading