Add entry point at output switcher to do group operation
-Entry point is available only when there are more than 1 connected device
-Add group Slice item when it is available
-Add intent filter in manifest
-Add test case
Bug: 146813761
Test: make -j42 RunSettingsRoboTests
Change-Id: If398b7a31219fd1910503d96fe7593622528c792
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index ef38240..12075a2 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -3202,6 +3202,10 @@
<action android:name="com.android.settings.panel.action.MEDIA_OUTPUT" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
+ <intent-filter>
+ <action android:name="com.android.settings.panel.action.MEDIA_OUTPUT_GROUP" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
</activity-alias>
<provider android:name=".slices.SettingsSliceProvider"
diff --git a/src/com/android/settings/media/MediaOutputGroupSlice.java b/src/com/android/settings/media/MediaOutputGroupSlice.java
index 521b605..d60ae22 100644
--- a/src/com/android/settings/media/MediaOutputGroupSlice.java
+++ b/src/com/android/settings/media/MediaOutputGroupSlice.java
@@ -118,8 +118,7 @@
return listBuilder.build();
}
- private void addRow(ListBuilder listBuilder, List<MediaDevice> mediaDevices,
- boolean selected) {
+ private void addRow(ListBuilder listBuilder, List<MediaDevice> mediaDevices, boolean selected) {
for (MediaDevice device : mediaDevices) {
final int maxVolume = device.getMaxVolume();
final IconCompat titleIcon = Utils.createIconWithDrawable(device.getIcon());
diff --git a/src/com/android/settings/media/MediaOutputSlice.java b/src/com/android/settings/media/MediaOutputSlice.java
index eff838d..026b8a8 100644
--- a/src/com/android/settings/media/MediaOutputSlice.java
+++ b/src/com/android/settings/media/MediaOutputSlice.java
@@ -44,6 +44,7 @@
import com.android.settings.slices.SliceBackgroundWorker;
import com.android.settings.slices.SliceBroadcastReceiver;
import com.android.settingslib.media.MediaDevice;
+import com.android.settingslib.media.MediaOutputSliceConstants;
import java.util.Collection;
@@ -54,6 +55,8 @@
private static final String TAG = "MediaOutputSlice";
private static final String MEDIA_DEVICE_ID = "media_device_id";
+ private static final String MEDIA_GROUP_DEVICE = "media_group_device";
+ private static final String MEDIA_GROUP_REQUEST = "media_group_request";
private static final int NON_SLIDER_VALUE = -1;
public static final String MEDIA_PACKAGE_NAME = "media_package_name";
@@ -86,52 +89,94 @@
final Collection<MediaDevice> devices = getMediaDevices();
final MediaDeviceUpdateWorker worker = getWorker();
- final MediaDevice connectedDevice = worker.getCurrentConnectedMediaDevice();
- final boolean isTouched = worker.getIsTouched();
- // Fix the last top device when user press device to transfer.
- final MediaDevice topDevice = isTouched ? worker.getTopDevice() : connectedDevice;
- if (topDevice != null) {
- addRow(topDevice, connectedDevice, listBuilder);
- worker.setTopDevice(topDevice);
- }
+ if (worker.getSelectedMediaDevice().size() > 1) {
+ // Insert group item to the first when it is available
+ listBuilder.addInputRange(getGroupRow());
+ // Add all other devices
+ for (MediaDevice device : devices) {
+ addRow(device, null /* connectedDevice */, listBuilder);
+ }
+ } else {
+ final MediaDevice connectedDevice = worker.getCurrentConnectedMediaDevice();
+ final boolean isTouched = worker.getIsTouched();
+ // Fix the last top device when user press device to transfer.
+ final MediaDevice topDevice = isTouched ? worker.getTopDevice() : connectedDevice;
- for (MediaDevice device : devices) {
- if (topDevice == null
- || !TextUtils.equals(topDevice.getId(), device.getId())) {
- addRow(device, connectedDevice, listBuilder);
+ if (topDevice != null) {
+ addRow(topDevice, connectedDevice, listBuilder);
+ worker.setTopDevice(topDevice);
+ }
+
+ for (MediaDevice device : devices) {
+ if (topDevice == null || !TextUtils.equals(topDevice.getId(), device.getId())) {
+ addRow(device, connectedDevice, listBuilder);
+ }
}
}
-
return listBuilder.build();
}
- private void addRow(MediaDevice device, MediaDevice connectedDevice, ListBuilder listBuilder) {
- if (connectedDevice != null && TextUtils.equals(device.getId(), connectedDevice.getId())) {
- listBuilder.addInputRange(getActiveDeviceHeaderRow(device));
- } else {
- listBuilder.addRow(getMediaDeviceRow(device));
- }
- }
-
- private ListBuilder.InputRangeBuilder getActiveDeviceHeaderRow(MediaDevice device) {
- final String title = device.getName();
- final IconCompat icon = getDeviceIconCompat(device);
-
+ private ListBuilder.InputRangeBuilder getGroupRow() {
+ final IconCompat icon = IconCompat.createWithResource(mContext,
+ R.drawable.ic_speaker_group_black_24dp);
+ final CharSequence sessionName = getWorker().getSessionName();
+ final CharSequence title = TextUtils.isEmpty(sessionName)
+ ? mContext.getString(R.string.media_output_group) : sessionName;
final PendingIntent broadcastAction =
- getBroadcastIntent(mContext, device.getId(), device.hashCode());
+ getBroadcastIntent(mContext, MEDIA_GROUP_DEVICE, MEDIA_GROUP_DEVICE.hashCode());
final SliceAction primarySliceAction = SliceAction.createDeeplink(broadcastAction, icon,
ListBuilder.ICON_IMAGE, title);
final ListBuilder.InputRangeBuilder builder = new ListBuilder.InputRangeBuilder()
.setTitleItem(icon, ListBuilder.ICON_IMAGE)
.setTitle(title)
.setPrimaryAction(primarySliceAction)
- .setInputAction(getSliderInputAction(device.hashCode(), device.getId()))
- .setMax(device.getMaxVolume())
- .setValue(device.getCurrentVolume());
+ .setInputAction(getSliderInputAction(MEDIA_GROUP_DEVICE.hashCode(),
+ MEDIA_GROUP_DEVICE))
+ .setMax(getWorker().getSessionVolumeMax())
+ .setValue(getWorker().getSessionVolume())
+ .addEndItem(getEndItemSliceAction());
return builder;
}
+ private void addRow(MediaDevice device, MediaDevice connectedDevice, ListBuilder listBuilder) {
+ if (connectedDevice != null && TextUtils.equals(device.getId(), connectedDevice.getId())) {
+ final String title = device.getName();
+ final IconCompat icon = getDeviceIconCompat(device);
+
+ final PendingIntent broadcastAction =
+ getBroadcastIntent(mContext, device.getId(), device.hashCode());
+ final SliceAction primarySliceAction = SliceAction.createDeeplink(broadcastAction, icon,
+ ListBuilder.ICON_IMAGE, title);
+
+ if (device.getMaxVolume() > 0) {
+ final ListBuilder.InputRangeBuilder builder = new ListBuilder.InputRangeBuilder()
+ .setTitleItem(icon, ListBuilder.ICON_IMAGE)
+ .setTitle(title)
+ .setPrimaryAction(primarySliceAction)
+ .setInputAction(getSliderInputAction(device.hashCode(), device.getId()))
+ .setMax(device.getMaxVolume())
+ .setValue(device.getCurrentVolume());
+ // Check end item visibility
+ if (device.getDeviceType() == MediaDevice.MediaDeviceType.TYPE_CAST_DEVICE
+ && !getWorker().getSelectableMediaDevice().isEmpty()) {
+ builder.addEndItem(getEndItemSliceAction());
+ }
+ listBuilder.addInputRange(builder);
+ } else {
+ final ListBuilder.RowBuilder builder = getMediaDeviceRow(device);
+ // Check end item visibility
+ if (device.getDeviceType() == MediaDevice.MediaDeviceType.TYPE_CAST_DEVICE
+ && !getWorker().getSelectableMediaDevice().isEmpty()) {
+ builder.addEndItem(getEndItemSliceAction());
+ }
+ listBuilder.addRow(builder);
+ }
+ } else {
+ listBuilder.addRow(getMediaDeviceRow(device));
+ }
+ }
+
private PendingIntent getSliderInputAction(int requestCode, String id) {
final Intent intent = new Intent(getUri().toString())
.setData(getUri())
@@ -141,6 +186,20 @@
return PendingIntent.getBroadcast(mContext, requestCode, intent, 0);
}
+ private SliceAction getEndItemSliceAction() {
+ final Intent intent = new Intent()
+ .setAction(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT_GROUP)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ .putExtra(MediaOutputSliceConstants.EXTRA_PACKAGE_NAME,
+ getWorker().getPackageName());
+
+ return SliceAction.createDeeplink(
+ PendingIntent.getActivity(mContext, 0 /* requestCode */, intent, 0 /* flags */),
+ IconCompat.createWithResource(mContext, R.drawable.ic_add_blue_24dp),
+ ListBuilder.ICON_IMAGE,
+ mContext.getText(R.string.add));
+ }
+
private IconCompat getDeviceIconCompat(MediaDevice device) {
Drawable drawable = device.getIcon();
if (drawable == null) {
@@ -169,14 +228,12 @@
final PendingIntent broadcastAction =
getBroadcastIntent(mContext, device.getId(), device.hashCode());
final IconCompat deviceIcon = getDeviceIconCompat(device);
-
final ListBuilder.RowBuilder rowBuilder = new ListBuilder.RowBuilder()
- .setTitleItem(deviceIcon, ListBuilder.ICON_IMAGE)
- .setPrimaryAction(SliceAction.create(broadcastAction, deviceIcon,
- ListBuilder.ICON_IMAGE, deviceName));
- // Append status to tile only for the disconnected Bluetooth device.
+ .setTitleItem(deviceIcon, ListBuilder.ICON_IMAGE);
+
if (device.getDeviceType() == MediaDevice.MediaDeviceType.TYPE_BLUETOOTH_DEVICE
&& !device.isConnected()) {
+ // Append status to title only for the disconnected Bluetooth device.
final SpannableString spannableTitle = new SpannableString(
mContext.getString(R.string.media_output_disconnected_status, deviceName));
spannableTitle.setSpan(new ForegroundColorSpan(Color.GRAY), deviceName.length(),
@@ -214,19 +271,27 @@
if (TextUtils.isEmpty(id)) {
return;
}
- final MediaDevice device = worker.getMediaDeviceById(id);
- if (device == null) {
- return;
- }
+
final int newPosition = intent.getIntExtra(EXTRA_RANGE_VALUE, NON_SLIDER_VALUE);
- if (newPosition == NON_SLIDER_VALUE) {
- // Intent for device connection
- Log.d(TAG, "onNotifyChange() device name : " + device.getName());
- worker.setIsTouched(true);
- worker.connectDevice(device);
+ if (TextUtils.equals(id, MEDIA_GROUP_DEVICE)) {
+ // Session volume adjustment
+ worker.adjustSessionVolume(newPosition);
} else {
- // Intent for volume adjustment
- worker.adjustVolume(device, newPosition);
+ final MediaDevice device = worker.getMediaDeviceById(id);
+ if (device == null) {
+ Log.d(TAG, "onNotifyChange: Unable to get device " + id);
+ return;
+ }
+
+ if (newPosition == NON_SLIDER_VALUE) {
+ // Intent for device connection
+ Log.d(TAG, "onNotifyChange: Switch to " + device.getName());
+ worker.setIsTouched(true);
+ worker.connectDevice(device);
+ } else {
+ // Single device volume adjustment
+ worker.adjustVolume(device, newPosition);
+ }
}
}
diff --git a/src/com/android/settings/panel/PanelFeatureProviderImpl.java b/src/com/android/settings/panel/PanelFeatureProviderImpl.java
index 04d3095..93c6025 100644
--- a/src/com/android/settings/panel/PanelFeatureProviderImpl.java
+++ b/src/com/android/settings/panel/PanelFeatureProviderImpl.java
@@ -17,6 +17,7 @@
package com.android.settings.panel;
import static com.android.settingslib.media.MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT;
+import static com.android.settingslib.media.MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT_GROUP;
import android.content.Context;
import android.os.Bundle;
@@ -46,6 +47,8 @@
return WifiPanel.create(context);
case Settings.Panel.ACTION_VOLUME:
return VolumePanel.create(context);
+ case ACTION_MEDIA_OUTPUT_GROUP:
+ return MediaOutputGroupPanel.create(context, mediaPackageName);
}
throw new IllegalStateException("No matching panel for: " + panelType);
diff --git a/tests/robotests/src/com/android/settings/media/MediaOutputSliceTest.java b/tests/robotests/src/com/android/settings/media/MediaOutputSliceTest.java
index c01c9b0..03d85b2 100644
--- a/tests/robotests/src/com/android/settings/media/MediaOutputSliceTest.java
+++ b/tests/robotests/src/com/android/settings/media/MediaOutputSliceTest.java
@@ -36,6 +36,7 @@
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
+import android.text.TextUtils;
import androidx.slice.Slice;
import androidx.slice.SliceMetadata;
@@ -67,7 +68,9 @@
public class MediaOutputSliceTest {
private static final String TEST_DEVICE_1_ID = "test_device_1_id";
+ private static final String TEST_DEVICE_2_ID = "test_device_2_id";
private static final String TEST_DEVICE_1_NAME = "test_device_1_name";
+ private static final String TEST_DEVICE_2_NAME = "test_device_2_name";
private static final int TEST_DEVICE_1_ICON =
com.android.internal.R.drawable.ic_bt_headphones_a2dp;
@@ -98,7 +101,8 @@
mShadowBluetoothAdapter.setEnabled(true);
mMediaOutputSlice = new MediaOutputSlice(mContext);
- mMediaDeviceUpdateWorker = new MediaDeviceUpdateWorker(mContext, MEDIA_OUTPUT_SLICE_URI);
+ mMediaDeviceUpdateWorker = new MediaDeviceUpdateWorker(mContext,
+ MEDIA_OUTPUT_SLICE_URI);
mMediaDeviceUpdateWorker.onDeviceListUpdate(mDevices);
mMediaDeviceUpdateWorker.mLocalMediaManager = mLocalMediaManager;
mMediaOutputSlice.init(mMediaDeviceUpdateWorker);
@@ -147,6 +151,19 @@
when(device.getName()).thenReturn(TEST_DEVICE_1_NAME);
when(device.getIcon()).thenReturn(mTestDrawable);
when(device.getMaxVolume()).thenReturn(100);
+ when(device.isConnected()).thenReturn(true);
+ when(device.getDeviceType()).thenReturn(MediaDevice.MediaDeviceType.TYPE_CAST_DEVICE);
+ when(device.getId()).thenReturn(TEST_DEVICE_1_ID);
+ final MediaDevice device2 = mock(MediaDevice.class);
+ when(device2.getName()).thenReturn(TEST_DEVICE_2_NAME);
+ when(device2.getIcon()).thenReturn(mTestDrawable);
+ when(device2.getMaxVolume()).thenReturn(100);
+ when(device2.isConnected()).thenReturn(false);
+ when(device2.getDeviceType()).thenReturn(MediaDevice.MediaDeviceType.TYPE_CAST_DEVICE);
+ when(device2.getId()).thenReturn(TEST_DEVICE_2_ID);
+ mDevices.add(device);
+ mDevices.add(device2);
+ mMediaDeviceUpdateWorker.onDeviceListUpdate(mDevices);
when(mLocalMediaManager.getCurrentConnectedDevice()).thenReturn(device);
final Slice mediaSlice = mMediaOutputSlice.getSlice();
@@ -165,8 +182,16 @@
when(device.getMaxVolume()).thenReturn(100);
when(device.isConnected()).thenReturn(false);
when(device.getDeviceType()).thenReturn(MediaDevice.MediaDeviceType.TYPE_BLUETOOTH_DEVICE);
-
+ when(device.getId()).thenReturn(TEST_DEVICE_1_ID);
+ final MediaDevice device2 = mock(MediaDevice.class);
+ when(device2.getName()).thenReturn(TEST_DEVICE_2_NAME);
+ when(device2.getIcon()).thenReturn(mTestDrawable);
+ when(device2.getMaxVolume()).thenReturn(100);
+ when(device2.isConnected()).thenReturn(false);
+ when(device2.getDeviceType()).thenReturn(MediaDevice.MediaDeviceType.TYPE_BLUETOOTH_DEVICE);
+ when(device2.getId()).thenReturn(TEST_DEVICE_2_ID);
mDevices.add(device);
+ mDevices.add(device2);
mMediaDeviceUpdateWorker.onDeviceListUpdate(mDevices);
final Slice mediaSlice = mMediaOutputSlice.getSlice();
@@ -178,6 +203,139 @@
}
@Test
+ public void getSlice_inGroupState_checkSliceSize() {
+ final List<MediaDevice> mSelectedDevices = new ArrayList<>();
+ final List<MediaDevice> mSelectableDevices = new ArrayList<>();
+ mDevices.clear();
+ final MediaDevice device = mock(MediaDevice.class);
+ when(device.getName()).thenReturn(TEST_DEVICE_1_NAME);
+ when(device.getIcon()).thenReturn(mTestDrawable);
+ when(device.getMaxVolume()).thenReturn(100);
+ when(device.isConnected()).thenReturn(true);
+ when(device.getDeviceType()).thenReturn(MediaDevice.MediaDeviceType.TYPE_CAST_DEVICE);
+ when(device.getId()).thenReturn(TEST_DEVICE_1_ID);
+ final MediaDevice device2 = mock(MediaDevice.class);
+ when(device2.getName()).thenReturn(TEST_DEVICE_2_NAME);
+ when(device2.getIcon()).thenReturn(mTestDrawable);
+ when(device2.getMaxVolume()).thenReturn(100);
+ when(device2.isConnected()).thenReturn(true);
+ when(device2.getDeviceType()).thenReturn(MediaDevice.MediaDeviceType.TYPE_CAST_DEVICE);
+ when(device2.getId()).thenReturn(TEST_DEVICE_2_ID);
+ mSelectedDevices.add(device);
+ mSelectedDevices.add(device2);
+ when(mLocalMediaManager.getCurrentConnectedDevice()).thenReturn(device);
+ mDevices.add(device);
+ mDevices.add(device2);
+ when(mLocalMediaManager.getSelectedMediaDevice()).thenReturn(mSelectedDevices);
+ when(mLocalMediaManager.getSelectableMediaDevice()).thenReturn(mSelectableDevices);
+ when(mMediaDeviceUpdateWorker.getSessionVolumeMax()).thenReturn(100);
+ mMediaDeviceUpdateWorker.onDeviceListUpdate(mDevices);
+
+ final Slice mediaSlice = mMediaOutputSlice.getSlice();
+
+ assertThat(SliceQuery.findAll(mediaSlice, FORMAT_SLICE, HINT_LIST_ITEM, null).size())
+ .isEqualTo(mDevices.size() + 1);
+ }
+
+ @Test
+ public void getSlice_notInGroupState_checkSliceSize() {
+ final List<MediaDevice> mSelectedDevices = new ArrayList<>();
+ final List<MediaDevice> mSelectableDevices = new ArrayList<>();
+ mDevices.clear();
+ final MediaDevice device = mock(MediaDevice.class);
+ when(device.getName()).thenReturn(TEST_DEVICE_1_NAME);
+ when(device.getIcon()).thenReturn(mTestDrawable);
+ when(device.getMaxVolume()).thenReturn(100);
+ when(device.isConnected()).thenReturn(true);
+ when(device.getDeviceType()).thenReturn(MediaDevice.MediaDeviceType.TYPE_CAST_DEVICE);
+ when(device.getId()).thenReturn(TEST_DEVICE_1_ID);
+ final MediaDevice device2 = mock(MediaDevice.class);
+ when(device2.getName()).thenReturn(TEST_DEVICE_2_NAME);
+ when(device2.getIcon()).thenReturn(mTestDrawable);
+ when(device2.getMaxVolume()).thenReturn(100);
+ when(device2.isConnected()).thenReturn(true);
+ when(device2.getDeviceType()).thenReturn(MediaDevice.MediaDeviceType.TYPE_CAST_DEVICE);
+ when(device2.getId()).thenReturn(TEST_DEVICE_2_ID);
+ mSelectedDevices.add(device);
+ mSelectableDevices.add(device2);
+ when(mLocalMediaManager.getCurrentConnectedDevice()).thenReturn(device);
+ mDevices.add(device);
+ mDevices.add(device2);
+ when(mLocalMediaManager.getSelectedMediaDevice()).thenReturn(mSelectedDevices);
+ when(mLocalMediaManager.getSelectableMediaDevice()).thenReturn(mSelectableDevices);
+ mMediaDeviceUpdateWorker.onDeviceListUpdate(mDevices);
+
+ final Slice mediaSlice = mMediaOutputSlice.getSlice();
+
+ assertThat(SliceQuery.findAll(mediaSlice, FORMAT_SLICE, HINT_LIST_ITEM, null).size())
+ .isEqualTo(mDevices.size());
+ }
+
+ @Test
+ public void getSlice_singleCastDevice_notContainGroupIconText() {
+ final List<MediaDevice> mSelectedDevices = new ArrayList<>();
+ final List<MediaDevice> mSelectableDevices = new ArrayList<>();
+ mDevices.clear();
+ final MediaDevice device = mock(MediaDevice.class);
+ when(device.getName()).thenReturn(TEST_DEVICE_1_NAME);
+ when(device.getIcon()).thenReturn(mTestDrawable);
+ when(device.getMaxVolume()).thenReturn(100);
+ when(device.isConnected()).thenReturn(true);
+ when(device.getDeviceType()).thenReturn(MediaDevice.MediaDeviceType.TYPE_CAST_DEVICE);
+ when(device.getId()).thenReturn(TEST_DEVICE_1_ID);
+ when(mLocalMediaManager.getSelectedMediaDevice()).thenReturn(mDevices);
+ when(mLocalMediaManager.getSelectableMediaDevice()).thenReturn(null);
+ mSelectedDevices.add(device);
+ when(mLocalMediaManager.getCurrentConnectedDevice()).thenReturn(device);
+ mDevices.add(device);
+ when(mLocalMediaManager.getSelectedMediaDevice()).thenReturn(mSelectedDevices);
+ when(mLocalMediaManager.getSelectableMediaDevice()).thenReturn(mSelectableDevices);
+ mMediaDeviceUpdateWorker.onDeviceListUpdate(mDevices);
+
+ final Slice mediaSlice = mMediaOutputSlice.getSlice();
+
+ final String sliceInfo = SliceQuery.findAll(mediaSlice, FORMAT_SLICE, HINT_LIST_ITEM,
+ null).toString();
+
+ assertThat(TextUtils.indexOf(sliceInfo, mContext.getText(R.string.add))).isEqualTo(-1);
+ }
+
+ @Test
+ public void getSlice_multipleCastDevices_containGroupIconText() {
+ final List<MediaDevice> mSelectedDevices = new ArrayList<>();
+ final List<MediaDevice> mSelectableDevices = new ArrayList<>();
+ mDevices.clear();
+ final MediaDevice device = mock(MediaDevice.class);
+ when(device.getName()).thenReturn(TEST_DEVICE_1_NAME);
+ when(device.getIcon()).thenReturn(mTestDrawable);
+ when(device.getMaxVolume()).thenReturn(100);
+ when(device.isConnected()).thenReturn(true);
+ when(device.getDeviceType()).thenReturn(MediaDevice.MediaDeviceType.TYPE_CAST_DEVICE);
+ when(device.getId()).thenReturn(TEST_DEVICE_1_ID);
+ final MediaDevice device2 = mock(MediaDevice.class);
+ when(device2.getName()).thenReturn(TEST_DEVICE_2_NAME);
+ when(device2.getIcon()).thenReturn(mTestDrawable);
+ when(device2.getMaxVolume()).thenReturn(100);
+ when(device2.isConnected()).thenReturn(true);
+ when(device2.getDeviceType()).thenReturn(MediaDevice.MediaDeviceType.TYPE_CAST_DEVICE);
+ when(device2.getId()).thenReturn(TEST_DEVICE_2_ID);
+ mSelectedDevices.add(device);
+ mSelectableDevices.add(device2);
+ when(mLocalMediaManager.getCurrentConnectedDevice()).thenReturn(device);
+ mDevices.add(device);
+ mDevices.add(device2);
+ when(mLocalMediaManager.getSelectedMediaDevice()).thenReturn(mSelectedDevices);
+ when(mLocalMediaManager.getSelectableMediaDevice()).thenReturn(mSelectableDevices);
+ mMediaDeviceUpdateWorker.onDeviceListUpdate(mDevices);
+
+ final Slice mediaSlice = mMediaOutputSlice.getSlice();
+ String sliceInfo = SliceQuery.findAll(mediaSlice, FORMAT_SLICE, HINT_LIST_ITEM,
+ null).toString();
+
+ assertThat(TextUtils.indexOf(sliceInfo, mContext.getText(R.string.add))).isNotEqualTo(-1);
+ }
+
+ @Test
public void onNotifyChange_foundMediaDevice_connect() {
mDevices.clear();
final MediaDevice device = mock(MediaDevice.class);