DO NOT MERGE: Downbranch merge conflict[Output Switcher] Add "Suggested Devices" section in list
Add interface in MediaDevice to check if it is suggested device, add suggested device group divider in list when organize devices. This change will be guard by flag and actually enable in master branch. Bug: 258141461 Test: atest MediaOutputAdapterTest MediaOutputControllerTest MediaOutputBaseDialogTest MediaOutputDialogTest Change-Id: Ie6372e185eb095e87ca679a701f93e0f6fe2f9f3 Merged-In: Ie6372e185eb095e87ca679a701f93e0f6fe2f9f3
This commit is contained in:
committed by
Shaowei Shen
parent
840c39460f
commit
87e045dfac
@@ -184,6 +184,15 @@ public abstract class MediaDevice implements Comparable<MediaDevice> {
|
|||||||
*/
|
*/
|
||||||
public abstract String getId();
|
public abstract String getId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if device is suggested device from application
|
||||||
|
*
|
||||||
|
* @return true if device is suggested device
|
||||||
|
*/
|
||||||
|
public boolean isSuggestedDevice() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void setConnectedRecord() {
|
void setConnectedRecord() {
|
||||||
mConnectedRecord++;
|
mConnectedRecord++;
|
||||||
ConnectionRecordManager.getInstance().setConnectionRecord(mContext, getId(),
|
ConnectionRecordManager.getInstance().setConnectionRecord(mContext, getId(),
|
||||||
|
|||||||
@@ -2414,6 +2414,8 @@
|
|||||||
<string name="media_output_dialog_volume_percentage"><xliff:g id="percentage" example="10">%1$d</xliff:g>%%</string>
|
<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] -->
|
<!-- Title for Speakers and Displays group. [CHAR LIMIT=NONE] -->
|
||||||
<string name="media_output_group_title_speakers_and_displays">Speakers & Displays</string>
|
<string name="media_output_group_title_speakers_and_displays">Speakers & Displays</string>
|
||||||
|
<!-- Title for Suggested Devices group. [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="media_output_group_title_suggested_device">Suggested Devices</string>
|
||||||
|
|
||||||
<!-- Media Output Broadcast Dialog -->
|
<!-- Media Output Broadcast Dialog -->
|
||||||
<!-- Title for Broadcast First Notify Dialog [CHAR LIMIT=60] -->
|
<!-- Title for Broadcast First Notify Dialog [CHAR LIMIT=60] -->
|
||||||
|
|||||||
@@ -637,44 +637,21 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
|
|||||||
}
|
}
|
||||||
// For the first time building list, to make sure the top device is the connected
|
// For the first time building list, to make sure the top device is the connected
|
||||||
// device.
|
// device.
|
||||||
|
boolean needToHandleMutingExpectedDevice =
|
||||||
|
hasMutingExpectedDevice() && !isCurrentConnectedDeviceRemote();
|
||||||
|
final MediaDevice connectedMediaDevice =
|
||||||
|
needToHandleMutingExpectedDevice ? null
|
||||||
|
: getCurrentConnectedMediaDevice();
|
||||||
if (mMediaItemList.isEmpty()) {
|
if (mMediaItemList.isEmpty()) {
|
||||||
boolean needToHandleMutingExpectedDevice =
|
|
||||||
hasMutingExpectedDevice() && !isCurrentConnectedDeviceRemote();
|
|
||||||
final MediaDevice connectedMediaDevice =
|
|
||||||
needToHandleMutingExpectedDevice ? null
|
|
||||||
: getCurrentConnectedMediaDevice();
|
|
||||||
if (connectedMediaDevice == null) {
|
if (connectedMediaDevice == null) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "No connected media device or muting expected device exist.");
|
Log.d(TAG, "No connected media device or muting expected device exist.");
|
||||||
}
|
}
|
||||||
if (needToHandleMutingExpectedDevice) {
|
categorizeMediaItems(null, devices, needToHandleMutingExpectedDevice);
|
||||||
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);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// selected device exist
|
// selected device exist
|
||||||
for (MediaDevice device : devices) {
|
categorizeMediaItems(connectedMediaDevice, devices, false);
|
||||||
if (TextUtils.equals(device.getId(), connectedMediaDevice.getId())) {
|
|
||||||
mMediaItemList.add(0, new MediaItem(device));
|
|
||||||
} else {
|
|
||||||
mMediaItemList.add(new MediaItem(device));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
categorizeMediaItems(connectedMediaDevice);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// To keep the same list order
|
// To keep the same list order
|
||||||
@@ -708,31 +685,46 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void categorizeMediaItems(MediaDevice connectedMediaDevice) {
|
private void categorizeMediaItems(MediaDevice connectedMediaDevice, List<MediaDevice> devices,
|
||||||
|
boolean needToHandleMutingExpectedDevice) {
|
||||||
synchronized (mMediaDevicesLock) {
|
synchronized (mMediaDevicesLock) {
|
||||||
Set<String> selectedDevicesIds = getSelectedMediaDevice().stream().map(
|
Set<String> selectedDevicesIds = getSelectedMediaDevice().stream().map(
|
||||||
MediaDevice::getId).collect(Collectors.toSet());
|
MediaDevice::getId).collect(Collectors.toSet());
|
||||||
if (connectedMediaDevice != null) {
|
if (connectedMediaDevice != null) {
|
||||||
selectedDevicesIds.add(connectedMediaDevice.getId());
|
selectedDevicesIds.add(connectedMediaDevice.getId());
|
||||||
}
|
}
|
||||||
int latestSelected = 1;
|
boolean suggestedDeviceAdded = false;
|
||||||
for (MediaItem item : mMediaItemList) {
|
boolean displayGroupAdded = false;
|
||||||
if (item.getMediaDevice().isPresent()) {
|
for (MediaDevice device : devices) {
|
||||||
MediaDevice device = item.getMediaDevice().get();
|
if (needToHandleMutingExpectedDevice && device.isMutingExpectedDevice()) {
|
||||||
if (selectedDevicesIds.contains(device.getId())) {
|
mMediaItemList.add(0, new MediaItem(device));
|
||||||
latestSelected = mMediaItemList.indexOf(item) + 1;
|
} else if (!needToHandleMutingExpectedDevice && selectedDevicesIds.contains(
|
||||||
} else {
|
device.getId())) {
|
||||||
mMediaItemList.add(latestSelected, new MediaItem(mContext.getString(
|
mMediaItemList.add(0, new MediaItem(device));
|
||||||
R.string.media_output_group_title_speakers_and_displays),
|
} else {
|
||||||
MediaItem.MediaItemType.TYPE_GROUP_DIVIDER));
|
if (device.isSuggestedDevice() && !suggestedDeviceAdded) {
|
||||||
break;
|
attachGroupDivider(mContext.getString(
|
||||||
|
R.string.media_output_group_title_suggested_device));
|
||||||
|
suggestedDeviceAdded = true;
|
||||||
|
} else if (!device.isSuggestedDevice() && !displayGroupAdded) {
|
||||||
|
attachGroupDivider(mContext.getString(
|
||||||
|
R.string.media_output_group_title_speakers_and_displays));
|
||||||
|
displayGroupAdded = true;
|
||||||
}
|
}
|
||||||
|
mMediaItemList.add(new MediaItem(device));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mMediaItemList.add(new MediaItem());
|
mMediaItemList.add(new MediaItem());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void attachGroupDivider(String title) {
|
||||||
|
synchronized (mMediaDevicesLock) {
|
||||||
|
mMediaItemList.add(
|
||||||
|
new MediaItem(title, MediaItem.MediaItemType.TYPE_GROUP_DIVIDER));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void attachRangeInfo(List<MediaDevice> devices) {
|
private void attachRangeInfo(List<MediaDevice> devices) {
|
||||||
for (MediaDevice mediaDevice : devices) {
|
for (MediaDevice mediaDevice : devices) {
|
||||||
if (mNearbyDeviceInfoMap.containsKey(mediaDevice.getId())) {
|
if (mNearbyDeviceInfoMap.containsKey(mediaDevice.getId())) {
|
||||||
|
|||||||
@@ -102,8 +102,6 @@ public class MediaOutputControllerTest extends SysuiTestCase {
|
|||||||
private MediaOutputController.Callback mCb = mock(MediaOutputController.Callback.class);
|
private MediaOutputController.Callback mCb = mock(MediaOutputController.Callback.class);
|
||||||
private MediaDevice mMediaDevice1 = mock(MediaDevice.class);
|
private MediaDevice mMediaDevice1 = mock(MediaDevice.class);
|
||||||
private MediaDevice mMediaDevice2 = 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 mNearbyDevice1 = mock(NearbyDevice.class);
|
||||||
private NearbyDevice mNearbyDevice2 = mock(NearbyDevice.class);
|
private NearbyDevice mNearbyDevice2 = mock(NearbyDevice.class);
|
||||||
private MediaMetadata mMediaMetadata = mock(MediaMetadata.class);
|
private MediaMetadata mMediaMetadata = mock(MediaMetadata.class);
|
||||||
@@ -127,7 +125,6 @@ public class MediaOutputControllerTest extends SysuiTestCase {
|
|||||||
private LocalMediaManager mLocalMediaManager;
|
private LocalMediaManager mLocalMediaManager;
|
||||||
private List<MediaController> mMediaControllers = new ArrayList<>();
|
private List<MediaController> mMediaControllers = new ArrayList<>();
|
||||||
private List<MediaDevice> mMediaDevices = new ArrayList<>();
|
private List<MediaDevice> mMediaDevices = new ArrayList<>();
|
||||||
private List<MediaItem> mMediaItemList = new ArrayList<>();
|
|
||||||
private List<NearbyDevice> mNearbyDevices = new ArrayList<>();
|
private List<NearbyDevice> mNearbyDevices = new ArrayList<>();
|
||||||
private MediaDescription mMediaDescription;
|
private MediaDescription mMediaDescription;
|
||||||
private List<RoutingSessionInfo> mRoutingSessionInfos = new ArrayList<>();
|
private List<RoutingSessionInfo> mRoutingSessionInfos = new ArrayList<>();
|
||||||
@@ -162,10 +159,6 @@ public class MediaOutputControllerTest extends SysuiTestCase {
|
|||||||
when(mMediaDevice2.getId()).thenReturn(TEST_DEVICE_2_ID);
|
when(mMediaDevice2.getId()).thenReturn(TEST_DEVICE_2_ID);
|
||||||
mMediaDevices.add(mMediaDevice1);
|
mMediaDevices.add(mMediaDevice1);
|
||||||
mMediaDevices.add(mMediaDevice2);
|
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.getMediaRoute2Id()).thenReturn(TEST_DEVICE_1_ID);
|
||||||
@@ -337,6 +330,35 @@ public class MediaOutputControllerTest extends SysuiTestCase {
|
|||||||
|
|
||||||
assertThat(devices.containsAll(mMediaDevices)).isTrue();
|
assertThat(devices.containsAll(mMediaDevices)).isTrue();
|
||||||
assertThat(devices.size()).isEqualTo(mMediaDevices.size());
|
assertThat(devices.size()).isEqualTo(mMediaDevices.size());
|
||||||
|
assertThat(mMediaOutputController.getMediaItemList().size()).isEqualTo(
|
||||||
|
mMediaDevices.size() + 2);
|
||||||
|
verify(mCb).onDeviceListChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void advanced_categorizeMediaItems_withSuggestedDevice_verifyDeviceListSize() {
|
||||||
|
when(mFlags.isEnabled(Flags.OUTPUT_SWITCHER_ADVANCED_LAYOUT)).thenReturn(true);
|
||||||
|
when(mMediaDevice1.isSuggestedDevice()).thenReturn(true);
|
||||||
|
when(mMediaDevice2.isSuggestedDevice()).thenReturn(false);
|
||||||
|
|
||||||
|
mMediaOutputController.start(mCb);
|
||||||
|
reset(mCb);
|
||||||
|
mMediaOutputController.getMediaItemList().clear();
|
||||||
|
mMediaOutputController.onDeviceListUpdate(mMediaDevices);
|
||||||
|
final List<MediaDevice> devices = new ArrayList<>();
|
||||||
|
int dividerSize = 0;
|
||||||
|
for (MediaItem item : mMediaOutputController.getMediaItemList()) {
|
||||||
|
if (item.getMediaDevice().isPresent()) {
|
||||||
|
devices.add(item.getMediaDevice().get());
|
||||||
|
}
|
||||||
|
if (item.getMediaItemType() == MediaItem.MediaItemType.TYPE_GROUP_DIVIDER) {
|
||||||
|
dividerSize++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assertThat(devices.containsAll(mMediaDevices)).isTrue();
|
||||||
|
assertThat(devices.size()).isEqualTo(mMediaDevices.size());
|
||||||
|
assertThat(dividerSize).isEqualTo(2);
|
||||||
verify(mCb).onDeviceListChanged();
|
verify(mCb).onDeviceListChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user