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

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

Merge "Add the "Connect a device" button on demand to the media item list." into main

parents 8dc4a85a c80df016
Loading
Loading
Loading
Loading
+26 −8
Original line number Diff line number Diff line
@@ -609,8 +609,7 @@ public class MediaSwitchingController
                        devices,
                        getSelectedMediaDevice(),
                        connectedMediaDevice,
                        needToHandleMutingExpectedDevice,
                        getConnectNewDeviceItem());
                        needToHandleMutingExpectedDevice);
            } else {
                List<MediaItem> updatedMediaItems =
                        buildMediaItems(
@@ -701,7 +700,6 @@ public class MediaSwitchingController
                }
            }
            dividerItems.forEach(finalMediaItems::add);
            attachConnectNewDeviceItemIfNeeded(finalMediaItems);
            return finalMediaItems;
        }
    }
@@ -765,7 +763,6 @@ public class MediaSwitchingController
                finalMediaItems.add(MediaItem.createDeviceMediaItem(device));
            }
        }
        attachConnectNewDeviceItemIfNeeded(finalMediaItems);
        return finalMediaItems;
    }

@@ -879,6 +876,15 @@ public class MediaSwitchingController
        });
    }

    private List<MediaItem> getOutputDeviceList(boolean addConnectDeviceButton) {
        List<MediaItem> mediaItems = new ArrayList<>(
                mOutputMediaItemListProxy.getOutputMediaItemList());
        if (addConnectDeviceButton) {
            attachConnectNewDeviceItemIfNeeded(mediaItems);
        }
        return mediaItems;
    }

    private void addInputDevices(List<MediaItem> mediaItems) {
        mediaItems.add(
                MediaItem.createGroupDividerMediaItem(
@@ -886,22 +892,34 @@ public class MediaSwitchingController
        mediaItems.addAll(mInputMediaItemList);
    }

    private void addOutputDevices(List<MediaItem> mediaItems) {
    private void addOutputDevices(List<MediaItem> mediaItems, boolean addConnectDeviceButton) {
        mediaItems.add(
                MediaItem.createGroupDividerMediaItem(
                        mContext.getString(R.string.media_output_group_title)));
        mediaItems.addAll(mOutputMediaItemListProxy.getOutputMediaItemList());
        mediaItems.addAll(getOutputDeviceList(addConnectDeviceButton));
    }

    /**
     * Returns a list of media items to be rendered in the device list. For backward compatibility
     * reasons, adds a "Connect a device" button by default.
     */
    public List<MediaItem> getMediaItemList() {
        return getMediaItemList(true /* addConnectDeviceButton */);
    }

    /**
     * Returns a list of media items to be rendered in the device list.
     * @param addConnectDeviceButton Whether to add a "Connect a device" button to the list.
     */
    public List<MediaItem> getMediaItemList(boolean addConnectDeviceButton) {
        // If input routing is not enabled, only return output media items.
        if (!enableInputRouting()) {
            return mOutputMediaItemListProxy.getOutputMediaItemList();
            return getOutputDeviceList(addConnectDeviceButton);
        }

        // If input routing is enabled, return both output and input media items.
        List<MediaItem> mediaItems = new ArrayList<>();
        addOutputDevices(mediaItems);
        addOutputDevices(mediaItems, addConnectDeviceButton);
        addInputDevices(mediaItems);
        return mediaItems;
    }
+2 −14
Original line number Diff line number Diff line
@@ -44,7 +44,6 @@ public class OutputMediaItemListProxy {
    private final List<MediaItem> mSelectedMediaItems;
    private final List<MediaItem> mSuggestedMediaItems;
    private final List<MediaItem> mSpeakersAndDisplaysMediaItems;
    @Nullable private MediaItem mConnectNewDeviceMediaItem;

    public OutputMediaItemListProxy(Context context) {
        mContext = context;
@@ -88,9 +87,6 @@ public class OutputMediaItemListProxy {
                                    R.string.media_output_group_title_speakers_and_displays)));
            finalMediaItems.addAll(mSpeakersAndDisplaysMediaItems);
        }
        if (mConnectNewDeviceMediaItem != null) {
            finalMediaItems.add(mConnectNewDeviceMediaItem);
        }
        return finalMediaItems;
    }

@@ -99,8 +95,7 @@ public class OutputMediaItemListProxy {
            List<MediaDevice> devices,
            List<MediaDevice> selectedDevices,
            @Nullable MediaDevice connectedMediaDevice,
            boolean needToHandleMutingExpectedDevice,
            @Nullable MediaItem connectNewDeviceMediaItem) {
            boolean needToHandleMutingExpectedDevice) {
        Set<String> selectedOrConnectedMediaDeviceIds =
                selectedDevices.stream().map(MediaDevice::getId).collect(Collectors.toSet());
        if (connectedMediaDevice != null) {
@@ -177,7 +172,6 @@ public class OutputMediaItemListProxy {
        mSuggestedMediaItems.addAll(updatedSuggestedMediaItems);
        mSpeakersAndDisplaysMediaItems.clear();
        mSpeakersAndDisplaysMediaItems.addAll(updatedSpeakersAndDisplaysMediaItems);
        mConnectNewDeviceMediaItem = connectNewDeviceMediaItem;

        // The cached mOutputMediaItemList is cleared upon any update to individual media item
        // lists. This ensures getOutputMediaItemList() computes and caches a fresh list on the next
@@ -197,10 +191,6 @@ public class OutputMediaItemListProxy {
            mSelectedMediaItems.removeIf((MediaItem::isMutingExpectedDevice));
            mSuggestedMediaItems.removeIf((MediaItem::isMutingExpectedDevice));
            mSpeakersAndDisplaysMediaItems.removeIf((MediaItem::isMutingExpectedDevice));
            if (mConnectNewDeviceMediaItem != null
                    && mConnectNewDeviceMediaItem.isMutingExpectedDevice()) {
                mConnectNewDeviceMediaItem = null;
            }
        }
        mOutputMediaItemList.removeIf((MediaItem::isMutingExpectedDevice));
    }
@@ -211,7 +201,6 @@ public class OutputMediaItemListProxy {
            mSelectedMediaItems.clear();
            mSuggestedMediaItems.clear();
            mSpeakersAndDisplaysMediaItems.clear();
            mConnectNewDeviceMediaItem = null;
        }
        mOutputMediaItemList.clear();
    }
@@ -221,8 +210,7 @@ public class OutputMediaItemListProxy {
        if (Flags.fixOutputMediaItemListIndexOutOfBoundsException()) {
            return mSelectedMediaItems.isEmpty()
                    && mSuggestedMediaItems.isEmpty()
                    && mSpeakersAndDisplaysMediaItems.isEmpty()
                    && (mConnectNewDeviceMediaItem == null);
                    && mSpeakersAndDisplaysMediaItems.isEmpty();
        } else {
            return mOutputMediaItemList.isEmpty();
        }
+49 −7
Original line number Diff line number Diff line
@@ -1483,6 +1483,44 @@ public class MediaSwitchingControllerTest extends SysuiTestCase {
        verify(mLocalMediaManager, atLeastOnce()).connectDevice(outputMediaDevice);
    }

    @Test
    public void connectDeviceButton_remoteDevice_noButton() {
        when(mMediaDevice1.getFeatures()).thenReturn(
                ImmutableList.of(MediaRoute2Info.FEATURE_REMOTE_PLAYBACK));
        when(mLocalMediaManager.getCurrentConnectedDevice()).thenReturn(mMediaDevice1);
        mMediaSwitchingController.start(mCb);
        mMediaSwitchingController.onDeviceListUpdate(mMediaDevices);

        List<MediaItem> resultList = mMediaSwitchingController.getMediaItemList();

        assertThat(getNumberOfConnectDeviceButtons(resultList)).isEqualTo(0);
    }

    @Test
    public void connectDeviceButton_localDevice_hasButton() {
        when(mLocalMediaManager.getCurrentConnectedDevice()).thenReturn(mMediaDevice1);
        mMediaSwitchingController.start(mCb);
        mMediaSwitchingController.onDeviceListUpdate(mMediaDevices);

        List<MediaItem> resultList = mMediaSwitchingController.getMediaItemList();

        assertThat(getNumberOfConnectDeviceButtons(resultList)).isEqualTo(1);
        assertThat(resultList.get(resultList.size() - 1).getMediaItemType()).isEqualTo(
                MediaItem.MediaItemType.TYPE_PAIR_NEW_DEVICE);
    }

    @Test
    public void connectDeviceButton_localDeviceButtonDisabledByParam_noButton() {
        when(mLocalMediaManager.getCurrentConnectedDevice()).thenReturn(mMediaDevice1);
        mMediaSwitchingController.start(mCb);
        mMediaSwitchingController.onDeviceListUpdate(mMediaDevices);

        List<MediaItem> resultList = mMediaSwitchingController.getMediaItemList(
                false /* addConnectDeviceButton */);

        assertThat(getNumberOfConnectDeviceButtons(resultList)).isEqualTo(0);
    }

    @DisableFlags(Flags.FLAG_ENABLE_AUDIO_INPUT_DEVICE_ROUTING_AND_VOLUME_CONTROL)
    @Test
    public void connectDeviceButton_presentAtAllTimesForNonGroupOutputs() {
@@ -1495,7 +1533,8 @@ public class MediaSwitchingControllerTest extends SysuiTestCase {
                .getSelectedMediaDevice();

        // Verify that there is initially one "Connect a device" button present.
        assertThat(getNumberOfConnectDeviceButtons()).isEqualTo(1);
        assertThat(getNumberOfConnectDeviceButtons(
                mMediaSwitchingController.getMediaItemList())).isEqualTo(1);

        // Change the selected device, and verify that there is still one "Connect a device" button
        // present.
@@ -1504,7 +1543,8 @@ public class MediaSwitchingControllerTest extends SysuiTestCase {
                .getSelectedMediaDevice();
        mMediaSwitchingController.onDeviceListUpdate(mMediaDevices);

        assertThat(getNumberOfConnectDeviceButtons()).isEqualTo(1);
        assertThat(getNumberOfConnectDeviceButtons(
                mMediaSwitchingController.getMediaItemList())).isEqualTo(1);
    }

    @EnableFlags(Flags.FLAG_ENABLE_AUDIO_INPUT_DEVICE_ROUTING_AND_VOLUME_CONTROL)
@@ -1523,7 +1563,8 @@ public class MediaSwitchingControllerTest extends SysuiTestCase {
        doReturn(selectedInputMediaDevice).when(mInputRouteManager).getSelectedInputDevice();

        // Verify that there is initially one "Connect a device" button present.
        assertThat(getNumberOfConnectDeviceButtons()).isEqualTo(1);
        assertThat(getNumberOfConnectDeviceButtons(
                mMediaSwitchingController.getMediaItemList())).isEqualTo(1);

        // Change the selected device, and verify that there is still one "Connect a device" button
        // present.
@@ -1532,7 +1573,8 @@ public class MediaSwitchingControllerTest extends SysuiTestCase {
                .getSelectedMediaDevice();
        mMediaSwitchingController.onDeviceListUpdate(mMediaDevices);

        assertThat(getNumberOfConnectDeviceButtons()).isEqualTo(1);
        assertThat(getNumberOfConnectDeviceButtons(
                mMediaSwitchingController.getMediaItemList())).isEqualTo(1);
    }

    @EnableFlags(Flags.FLAG_ENABLE_OUTPUT_SWITCHER_DEVICE_GROUPING)
@@ -1633,7 +1675,7 @@ public class MediaSwitchingControllerTest extends SysuiTestCase {
        when(mLocalMediaManager.isPreferenceRouteListingExist()).thenReturn(false);
        mMediaSwitchingController.start(mCb);
        reset(mCb);
        mMediaSwitchingController.getMediaItemList().clear();
        mMediaSwitchingController.clearMediaItemList();
    }

    @DisableFlags(Flags.FLAG_ENABLE_OUTPUT_SWITCHER_DEVICE_GROUPING)
@@ -1691,9 +1733,9 @@ public class MediaSwitchingControllerTest extends SysuiTestCase {
        assertThat(items.get(0).isFirstDeviceInGroup()).isTrue();
    }

    private int getNumberOfConnectDeviceButtons() {
    private int getNumberOfConnectDeviceButtons(List<MediaItem> itemList) {
        int numberOfConnectDeviceButtons = 0;
        for (MediaItem item : mMediaSwitchingController.getMediaItemList()) {
        for (MediaItem item : itemList) {
            if (item.getMediaItemType() == MediaItem.MediaItemType.TYPE_PAIR_NEW_DEVICE) {
                numberOfConnectDeviceButtons++;
            }
+8 −59
Original line number Diff line number Diff line
@@ -58,7 +58,6 @@ public class OutputMediaItemListProxyTest extends SysuiTestCase {

    private MediaItem mMediaItem1;
    private MediaItem mMediaItem2;
    private MediaItem mConnectNewDeviceMediaItem;
    private OutputMediaItemListProxy mOutputMediaItemListProxy;

    @Parameters(name = "{0}")
@@ -83,7 +82,6 @@ public class OutputMediaItemListProxyTest extends SysuiTestCase {
        when(mMediaDevice4.getId()).thenReturn(DEVICE_ID_4);
        mMediaItem1 = MediaItem.createDeviceMediaItem(mMediaDevice1);
        mMediaItem2 = MediaItem.createDeviceMediaItem(mMediaDevice2);
        mConnectNewDeviceMediaItem = MediaItem.createPairNewDeviceMediaItem();

        mOutputMediaItemListProxy = new OutputMediaItemListProxy(mContext);
    }
@@ -98,8 +96,7 @@ public class OutputMediaItemListProxyTest extends SysuiTestCase {
                /* devices= */ List.of(mMediaDevice2, mMediaDevice3),
                /* selectedDevices */ List.of(mMediaDevice3),
                /* connectedMediaDevice= */ null,
                /* needToHandleMutingExpectedDevice= */ false,
                /* connectNewDeviceMediaItem= */ null);
                /* needToHandleMutingExpectedDevice= */ false);

        // Check the output media items to be
        //     * a media item with the selected mMediaDevice3
@@ -115,8 +112,7 @@ public class OutputMediaItemListProxyTest extends SysuiTestCase {
                /* devices= */ List.of(mMediaDevice4, mMediaDevice1, mMediaDevice3, mMediaDevice2),
                /* selectedDevices */ List.of(mMediaDevice3),
                /* connectedMediaDevice= */ null,
                /* needToHandleMutingExpectedDevice= */ false,
                /* connectNewDeviceMediaItem= */ null);
                /* needToHandleMutingExpectedDevice= */ false);

        // Check the output media items to be
        //     * a media item with the selected route mMediaDevice3
@@ -136,8 +132,7 @@ public class OutputMediaItemListProxyTest extends SysuiTestCase {
                /* devices= */ List.of(mMediaDevice1, mMediaDevice3, mMediaDevice2),
                /* selectedDevices */ List.of(mMediaDevice1, mMediaDevice3),
                /* connectedMediaDevice= */ null,
                /* needToHandleMutingExpectedDevice= */ false,
                /* connectNewDeviceMediaItem= */ null);
                /* needToHandleMutingExpectedDevice= */ false);

        // Check the output media items to be
        //     * a media item with the selected route mMediaDevice3
@@ -161,8 +156,7 @@ public class OutputMediaItemListProxyTest extends SysuiTestCase {
                /* devices= */ List.of(mMediaDevice2, mMediaDevice4, mMediaDevice3, mMediaDevice1),
                /* selectedDevices */ List.of(mMediaDevice1, mMediaDevice2, mMediaDevice3),
                /* connectedMediaDevice= */ null,
                /* needToHandleMutingExpectedDevice= */ false,
                /* connectNewDeviceMediaItem= */ null);
                /* needToHandleMutingExpectedDevice= */ false);

        if (Flags.enableOutputSwitcherDeviceGrouping()) {
            // When the device grouping is enabled, the order of selected devices are preserved:
@@ -197,8 +191,7 @@ public class OutputMediaItemListProxyTest extends SysuiTestCase {
                /* devices= */ List.of(mMediaDevice4, mMediaDevice1, mMediaDevice3, mMediaDevice2),
                /* selectedDevices */ List.of(mMediaDevice2, mMediaDevice3),
                /* connectedMediaDevice= */ null,
                /* needToHandleMutingExpectedDevice= */ false,
                /* connectNewDeviceMediaItem= */ null);
                /* needToHandleMutingExpectedDevice= */ false);

        if (Flags.enableOutputSwitcherDeviceGrouping()) {
            // When the device grouping is enabled, the order of selected devices are preserved:
@@ -233,8 +226,7 @@ public class OutputMediaItemListProxyTest extends SysuiTestCase {
                /* devices= */ List.of(mMediaDevice1, mMediaDevice3, mMediaDevice4),
                /* selectedDevices */ List.of(mMediaDevice3),
                /* connectedMediaDevice= */ null,
                /* needToHandleMutingExpectedDevice= */ false,
                /* connectNewDeviceMediaItem= */ null);
                /* needToHandleMutingExpectedDevice= */ false);

        if (Flags.enableOutputSwitcherDeviceGrouping()) {
            // When the device grouping is enabled, the order of selected devices are preserved:
@@ -261,47 +253,6 @@ public class OutputMediaItemListProxyTest extends SysuiTestCase {
        }
    }

    @EnableFlags(Flags.FLAG_FIX_OUTPUT_MEDIA_ITEM_LIST_INDEX_OUT_OF_BOUNDS_EXCEPTION)
    @Test
    public void updateMediaDevices_withConnectNewDeviceMediaItem_shouldUpdateMediaItemList() {
        assertThat(mOutputMediaItemListProxy.isEmpty()).isTrue();

        // Create the initial output media item list with a connect new device media item.
        mOutputMediaItemListProxy.updateMediaDevices(
                /* devices= */ List.of(mMediaDevice2, mMediaDevice3),
                /* selectedDevices */ List.of(mMediaDevice3),
                /* connectedMediaDevice= */ null,
                /* needToHandleMutingExpectedDevice= */ false,
                mConnectNewDeviceMediaItem);

        // Check the output media items to be
        //     * a media item with the selected mMediaDevice3
        //     * a group divider for suggested devices
        //     * a media item with the mMediaDevice2
        //     * a connect new device media item
        assertThat(mOutputMediaItemListProxy.getOutputMediaItemList())
                .contains(mConnectNewDeviceMediaItem);
        assertThat(getMediaDevices(mOutputMediaItemListProxy.getOutputMediaItemList()))
                .containsExactly(mMediaDevice3, null, mMediaDevice2, null);

        // Update the output media item list without a connect new device media item.
        mOutputMediaItemListProxy.updateMediaDevices(
                /* devices= */ List.of(mMediaDevice2, mMediaDevice3),
                /* selectedDevices */ List.of(mMediaDevice3),
                /* connectedMediaDevice= */ null,
                /* needToHandleMutingExpectedDevice= */ false,
                /* connectNewDeviceMediaItem= */ null);

        // Check the output media items to be
        //     * a media item with the selected mMediaDevice3
        //     * a group divider for suggested devices
        //     * a media item with the mMediaDevice2
        assertThat(mOutputMediaItemListProxy.getOutputMediaItemList())
                .doesNotContain(mConnectNewDeviceMediaItem);
        assertThat(getMediaDevices(mOutputMediaItemListProxy.getOutputMediaItemList()))
                .containsExactly(mMediaDevice3, null, mMediaDevice2);
    }

    @DisableFlags(Flags.FLAG_FIX_OUTPUT_MEDIA_ITEM_LIST_INDEX_OUT_OF_BOUNDS_EXCEPTION)
    @Test
    public void clearAndAddAll_shouldUpdateMediaItemList() {
@@ -325,8 +276,7 @@ public class OutputMediaItemListProxyTest extends SysuiTestCase {
                /* devices= */ List.of(mMediaDevice1),
                /* selectedDevices */ List.of(),
                /* connectedMediaDevice= */ null,
                /* needToHandleMutingExpectedDevice= */ false,
                /* connectNewDeviceMediaItem= */ null);
                /* needToHandleMutingExpectedDevice= */ false);
        assertThat(mOutputMediaItemListProxy.isEmpty()).isFalse();

        mOutputMediaItemListProxy.clear();
@@ -354,8 +304,7 @@ public class OutputMediaItemListProxyTest extends SysuiTestCase {
                /* devices= */ List.of(mMediaDevice1),
                /* selectedDevices */ List.of(),
                /* connectedMediaDevice= */ null,
                /* needToHandleMutingExpectedDevice= */ false,
                /* connectNewDeviceMediaItem= */ null);
                /* needToHandleMutingExpectedDevice= */ false);
        assertThat(mOutputMediaItemListProxy.isEmpty()).isFalse();

        mOutputMediaItemListProxy.removeMutingExpectedDevices();