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

Commit 8cc6d31d authored by Shaowei Shen's avatar Shaowei Shen Committed by Automerger Merge Worker
Browse files

Merge "[Output Switcher] Add group title" into tm-qpr-dev am: b379d5c3

parents b61ce03d b379d5c3
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -2406,6 +2406,8 @@
    <string name="media_output_dialog_accessibility_seekbar">Volume</string>
    <!-- Summary for media output volume of a device in percentage [CHAR LIMIT=NONE] -->
    <string name="media_output_dialog_volume_percentage"><xliff:g id="percentage" example="10">%1$d</xliff:g>%%</string>
    <!-- Title for Speakers and Displays group. [CHAR LIMIT=NONE] -->
    <string name="media_output_group_title_speakers_and_displays">Speakers &amp; Displays</string>

    <!-- Media Output Broadcast Dialog -->
    <!-- Title for Broadcast First Notify Dialog [CHAR LIMIT=60] -->
+7 −0
Original line number Diff line number Diff line
@@ -70,6 +70,13 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
        if (mController.isAdvancedLayoutSupported()) {
            if (position >= mController.getMediaItemList().size()) {
                if (DEBUG) {
                    Log.d(TAG, "Incorrect position: " + position + " list size: "
                            + mController.getMediaItemList().size());
                }
                return;
            }
            MediaItem currentMediaItem = mController.getMediaItemList().get(position);
            switch (currentMediaItem.getMediaItemType()) {
                case MediaItem.MediaItemType.TYPE_GROUP_DIVIDER:
+9 −14
Original line number Diff line number Diff line
@@ -84,8 +84,7 @@ public abstract class MediaOutputBaseAdapter extends
            int viewType) {
        mContext = viewGroup.getContext();
        mHolderView = LayoutInflater.from(mContext).inflate(
                mController.isAdvancedLayoutSupported() ? MediaItem.getMediaLayoutId(
                        viewType) /*R.layout.media_output_list_item_advanced*/
                mController.isAdvancedLayoutSupported() ? MediaItem.getMediaLayoutId(viewType)
                        : R.layout.media_output_list_item, viewGroup, false);

        return null;
@@ -308,9 +307,10 @@ public abstract class MediaOutputBaseAdapter extends
                        updateTitleIcon(currentVolume == 0 ? R.drawable.media_output_icon_volume_off
                                        : R.drawable.media_output_icon_volume,
                                mController.getColorItemContent());
                    }
                    } else {
                        animateCornerAndVolume(mSeekBar.getProgress(),
                                MediaOutputSeekbar.scaleVolumeToProgress(currentVolume));
                    }
                } else {
                    if (!mVolumeAnimator.isStarted()) {
                        if (mController.isAdvancedLayoutSupported()) {
@@ -396,23 +396,18 @@ public abstract class MediaOutputBaseAdapter extends
        }

        void updateMutedVolumeIcon() {
            mIconAreaLayout.setBackground(
                    mContext.getDrawable(R.drawable.media_output_item_background_active));
            updateTitleIcon(R.drawable.media_output_icon_volume_off,
                    mController.getColorItemContent());
            final GradientDrawable iconAreaBackgroundDrawable =
                    (GradientDrawable) mIconAreaLayout.getBackground();
            iconAreaBackgroundDrawable.setCornerRadius(mController.getActiveRadius());
        }

        void updateUnmutedVolumeIcon() {
            mIconAreaLayout.setBackground(
                    mContext.getDrawable(R.drawable.media_output_title_icon_area)
            );
            updateTitleIcon(R.drawable.media_output_icon_volume,
                    mController.getColorItemContent());
            final GradientDrawable iconAreaBackgroundDrawable =
                    (GradientDrawable) mIconAreaLayout.getBackground();
            iconAreaBackgroundDrawable.setCornerRadii(new float[]{
                    mController.getActiveRadius(),
                    mController.getActiveRadius(),
                    0, 0, 0, 0, mController.getActiveRadius(), mController.getActiveRadius()
            });
        }

        void updateTitleIcon(@DrawableRes int id, int color) {
+40 −7
Original line number Diff line number Diff line
@@ -87,9 +87,11 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executor;
@@ -275,7 +277,9 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,

    @Override
    public void onDeviceListUpdate(List<MediaDevice> devices) {
        if (mMediaDevices.isEmpty() || !mIsRefreshing) {
        boolean isListEmpty =
                isAdvancedLayoutSupported() ? mMediaItemList.isEmpty() : mMediaDevices.isEmpty();
        if (isListEmpty || !mIsRefreshing) {
            buildMediaDevices(devices);
            mCallback.onDeviceListChanged();
        } else {
@@ -646,16 +650,19 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
                        for (MediaDevice device : devices) {
                            if (device.isMutingExpectedDevice()) {
                                mMediaItemList.add(0, new MediaItem(device));
                                mMediaItemList.add(1, new MediaItem(mContext.getString(
                                        R.string.media_output_group_title_speakers_and_displays),
                                        MediaItem.MediaItemType.TYPE_GROUP_DIVIDER));
                            } else {
                                mMediaItemList.add(new MediaItem(device));
                            }
                        }
                        mMediaItemList.add(new MediaItem());
                    } else {
                        mMediaItemList.addAll(
                                devices.stream().map(MediaItem::new).collect(Collectors.toList()));
                        categorizeMediaItems(null);
                    }

                    categorizeMediaItems();
                    return;
                }
                // selected device exist
@@ -666,11 +673,12 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
                        mMediaItemList.add(new MediaItem(device));
                    }
                }
                categorizeMediaItems();
                categorizeMediaItems(connectedMediaDevice);
                return;
            }
            // To keep the same list order
            final List<MediaDevice> targetMediaDevices = new ArrayList<>();
            final Map<Integer, MediaItem> dividerItems = new HashMap<>();
            for (MediaItem originalMediaItem : mMediaItemList) {
                for (MediaDevice newDevice : devices) {
                    if (originalMediaItem.getMediaDevice().isPresent()
@@ -680,6 +688,10 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
                        break;
                    }
                }
                if (originalMediaItem.getMediaItemType()
                        == MediaItem.MediaItemType.TYPE_GROUP_DIVIDER) {
                    dividerItems.put(mMediaItemList.indexOf(originalMediaItem), originalMediaItem);
                }
            }
            if (targetMediaDevices.size() != devices.size()) {
                devices.removeAll(targetMediaDevices);
@@ -688,13 +700,34 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
            mMediaItemList.clear();
            mMediaItemList.addAll(
                    targetMediaDevices.stream().map(MediaItem::new).collect(Collectors.toList()));
            categorizeMediaItems();
            dividerItems.forEach((key, item) -> {
                mMediaItemList.add(key, item);
            });
            mMediaItemList.add(new MediaItem());
        }
    }

    private void categorizeMediaItems() {
    private void categorizeMediaItems(MediaDevice connectedMediaDevice) {
        synchronized (mMediaDevicesLock) {
            //TODO(255124239): do the categorization here
            Set<String> selectedDevicesIds = getSelectedMediaDevice().stream().map(
                    MediaDevice::getId).collect(Collectors.toSet());
            if (connectedMediaDevice != null) {
                selectedDevicesIds.add(connectedMediaDevice.getId());
            }
            int latestSelected = 1;
            for (MediaItem item : mMediaItemList) {
                if (item.getMediaDevice().isPresent()) {
                    MediaDevice device = item.getMediaDevice().get();
                    if (selectedDevicesIds.contains(device.getId())) {
                        latestSelected = mMediaItemList.indexOf(item) + 1;
                    } else {
                        mMediaItemList.add(latestSelected, new MediaItem(mContext.getString(
                                R.string.media_output_group_title_speakers_and_displays),
                                MediaItem.MediaItemType.TYPE_GROUP_DIVIDER));
                        break;
                    }
                }
            }
            mMediaItemList.add(new MediaItem());
        }
    }
+20 −0
Original line number Diff line number Diff line
@@ -102,6 +102,8 @@ public class MediaOutputControllerTest extends SysuiTestCase {
    private MediaOutputController.Callback mCb = mock(MediaOutputController.Callback.class);
    private MediaDevice mMediaDevice1 = mock(MediaDevice.class);
    private MediaDevice mMediaDevice2 = mock(MediaDevice.class);
    private MediaItem mMediaItem1 = mock(MediaItem.class);
    private MediaItem mMediaItem2 = mock(MediaItem.class);
    private NearbyDevice mNearbyDevice1 = mock(NearbyDevice.class);
    private NearbyDevice mNearbyDevice2 = mock(NearbyDevice.class);
    private MediaMetadata mMediaMetadata = mock(MediaMetadata.class);
@@ -125,6 +127,7 @@ public class MediaOutputControllerTest extends SysuiTestCase {
    private LocalMediaManager mLocalMediaManager;
    private List<MediaController> mMediaControllers = new ArrayList<>();
    private List<MediaDevice> mMediaDevices = new ArrayList<>();
    private List<MediaItem> mMediaItemList = new ArrayList<>();
    private List<NearbyDevice> mNearbyDevices = new ArrayList<>();
    private MediaDescription mMediaDescription;
    private List<RoutingSessionInfo> mRoutingSessionInfos = new ArrayList<>();
@@ -157,6 +160,11 @@ public class MediaOutputControllerTest extends SysuiTestCase {
        when(mMediaDevice2.getId()).thenReturn(TEST_DEVICE_2_ID);
        mMediaDevices.add(mMediaDevice1);
        mMediaDevices.add(mMediaDevice2);
        when(mMediaItem1.getMediaDevice()).thenReturn(Optional.of(mMediaDevice1));
        when(mMediaItem2.getMediaDevice()).thenReturn(Optional.of(mMediaDevice2));
        mMediaItemList.add(mMediaItem1);
        mMediaItemList.add(mMediaItem2);


        when(mNearbyDevice1.getMediaRoute2Id()).thenReturn(TEST_DEVICE_1_ID);
        when(mNearbyDevice1.getRangeZone()).thenReturn(NearbyDevice.RANGE_CLOSE);
@@ -313,6 +321,18 @@ public class MediaOutputControllerTest extends SysuiTestCase {
        assertThat(mMediaOutputController.mNeedRefresh).isTrue();
    }

    @Test
    public void advanced_onDeviceListUpdate_isRefreshing_updatesNeedRefreshToTrue() {
        when(mFlags.isEnabled(Flags.OUTPUT_SWITCHER_ADVANCED_LAYOUT)).thenReturn(true);
        mMediaOutputController.start(mCb);
        reset(mCb);
        mMediaOutputController.mIsRefreshing = true;

        mMediaOutputController.onDeviceListUpdate(mMediaDevices);

        assertThat(mMediaOutputController.mNeedRefresh).isTrue();
    }

    @Test
    public void cancelMuteAwaitConnection_cancelsWithMediaManager() {
        when(mAudioManager.getMutingExpectedDevice()).thenReturn(mock(AudioDeviceAttributes.class));