diff --git a/src/com/android/settings/media/MediaOutputGroupSlice.java b/src/com/android/settings/media/MediaOutputGroupSlice.java deleted file mode 100644 index 0359ca9b71b..00000000000 --- a/src/com/android/settings/media/MediaOutputGroupSlice.java +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.media; - -import static android.app.slice.Slice.EXTRA_RANGE_VALUE; - -import static com.android.settings.slices.CustomSliceRegistry.MEDIA_OUTPUT_GROUP_SLICE_URI; - -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.text.TextUtils; -import android.util.Log; - -import androidx.annotation.VisibleForTesting; -import androidx.core.graphics.drawable.IconCompat; -import androidx.slice.Slice; -import androidx.slice.builders.ListBuilder; -import androidx.slice.builders.SliceAction; - -import com.android.settings.R; -import com.android.settings.Utils; -import com.android.settings.slices.CustomSliceable; -import com.android.settings.slices.SliceBackgroundWorker; -import com.android.settings.slices.SliceBroadcastReceiver; -import com.android.settingslib.media.MediaDevice; - -import java.util.ArrayList; -import java.util.List; - -/** - * Show the Media device that can be transfer the media. - */ -public class MediaOutputGroupSlice implements CustomSliceable { - - @VisibleForTesting - static final String GROUP_DEVICES = "group_devices"; - @VisibleForTesting - static final String MEDIA_DEVICE_ID = "media_device_id"; - @VisibleForTesting - static final String CUSTOMIZED_ACTION = "customized_action"; - @VisibleForTesting - static final int ACTION_VOLUME_ADJUSTMENT = 1; - @VisibleForTesting - static final int ACTION_MEDIA_SESSION_OPERATION = 2; - @VisibleForTesting - static final int ERROR = -1; - - private static final String TAG = "MediaOutputGroupSlice"; - private static final int COLOR_DISABLED = (int) (255 * 0.3); - - private final Context mContext; - private MediaDeviceUpdateWorker mWorker; - - public MediaOutputGroupSlice(Context context) { - mContext = context; - } - - @Override - public Slice getSlice() { - final ListBuilder listBuilder = new ListBuilder(mContext, getUri(), ListBuilder.INFINITY) - .setAccentColor(COLOR_NOT_TINTED); - // Add "Group" row - final IconCompat titleIcon = IconCompat.createWithResource(mContext, - R.drawable.ic_speaker_group_black_24dp); - final Bitmap emptyBitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); - if (getWorker() == null) { - return listBuilder.build(); - } - final int maxVolume = getWorker().getSessionVolumeMax(); - final String title = mContext.getString(R.string.media_output_group); - final SliceAction primaryAction = SliceAction.createDeeplink( - getBroadcastIntent(GROUP_DEVICES, - GROUP_DEVICES.hashCode(), - ACTION_MEDIA_SESSION_OPERATION), - titleIcon, ListBuilder.ICON_IMAGE, GROUP_DEVICES); - final SliceAction endItemAction = SliceAction.createDeeplink( - getBroadcastIntent(GROUP_DEVICES, - GROUP_DEVICES.hashCode() + ACTION_MEDIA_SESSION_OPERATION, - ACTION_MEDIA_SESSION_OPERATION), - IconCompat.createWithBitmap(emptyBitmap), ListBuilder.ICON_IMAGE, ""); - if (maxVolume > 0 && !getWorker().hasAdjustVolumeUserRestriction()) { - // Add InputRange row - listBuilder.addInputRange(new ListBuilder.InputRangeBuilder() - .setTitleItem(titleIcon, ListBuilder.ICON_IMAGE) - .addEndItem(endItemAction) - .setTitle(title) - .setPrimaryAction(primaryAction) - .setInputAction(getBroadcastIntent(GROUP_DEVICES, - GROUP_DEVICES.hashCode() + ACTION_VOLUME_ADJUSTMENT, - ACTION_VOLUME_ADJUSTMENT)) - .setMax(maxVolume) - .setValue(getWorker().getSessionVolume())); - } else { // No max volume information. Add generic Row - listBuilder.addRow(new ListBuilder.RowBuilder() - .setTitleItem(titleIcon, ListBuilder.ICON_IMAGE) - .setTitle(title) - .setPrimaryAction(primaryAction)); - } - // Add device row - addRow(listBuilder, getWorker().getSelectedMediaDevice(), true); - addRow(listBuilder, getWorker().getSelectableMediaDevice(), false); - return listBuilder.build(); - } - - private void addRow(ListBuilder listBuilder, List mediaDevices, boolean selected) { - final boolean adjustVolumeUserRestriction = getWorker().hasAdjustVolumeUserRestriction(); - List deselectableMediaDevices = new ArrayList<>(); - if (selected) { - deselectableMediaDevices = getWorker().getDeselectableMediaDevice(); - } - for (MediaDevice device : mediaDevices) { - final int maxVolume = device.getMaxVolume(); - final IconCompat titleIcon = Utils.createIconWithDrawable(device.getIcon()); - final String title = device.getName(); - final SliceAction disabledIconSliceAction = SliceAction.createDeeplink( - getBroadcastIntent(null, 0, 0), - getDisabledCheckboxIcon(), ListBuilder.ICON_IMAGE, ""); - final SliceAction enabledIconSliceAction = SliceAction.createToggle( - getBroadcastIntent(device.getId(), - device.hashCode() + ACTION_MEDIA_SESSION_OPERATION, - ACTION_MEDIA_SESSION_OPERATION), - IconCompat.createWithResource(mContext, R.drawable.ic_check_box_anim), - "", - selected); - if (maxVolume > 0 && selected && !adjustVolumeUserRestriction) { - // Add InputRange row - final ListBuilder.InputRangeBuilder builder = new ListBuilder.InputRangeBuilder() - .setTitleItem(titleIcon, ListBuilder.ICON_IMAGE) - .setTitle(title) - .setInputAction(getBroadcastIntent(device.getId(), - device.hashCode() + ACTION_VOLUME_ADJUSTMENT, - ACTION_VOLUME_ADJUSTMENT)) - .setMax(device.getMaxVolume()) - .setValue(device.getCurrentVolume()); - // Add endItem with different icons - if (selected && (!getWorker().isDeviceIncluded(deselectableMediaDevices, device) - || mediaDevices.size() == 1)) { - builder.addEndItem(disabledIconSliceAction); - } else { - builder.addEndItem(enabledIconSliceAction); - } - listBuilder.addInputRange(builder); - } else { // No max volume information. Add generic Row - final ListBuilder.RowBuilder rowBuilder = new ListBuilder.RowBuilder() - .setTitleItem(titleIcon, ListBuilder.ICON_IMAGE) - .setTitle(title); - // Add endItem with different icons - if (selected && (!getWorker().isDeviceIncluded(deselectableMediaDevices, device) - || mediaDevices.size() == 1)) { - rowBuilder.addEndItem(disabledIconSliceAction); - } else { - rowBuilder.addEndItem(enabledIconSliceAction); - } - listBuilder.addRow(rowBuilder); - } - } - } - - private IconCompat getDisabledCheckboxIcon() { - final Drawable drawable = mContext.getDrawable(R.drawable.ic_check_box_blue_24dp).mutate(); - final Bitmap checkbox = Bitmap.createBitmap(drawable.getIntrinsicWidth(), - drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); - final Canvas canvas = new Canvas(checkbox); - drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); - drawable.setAlpha(COLOR_DISABLED); - drawable.draw(canvas); - - return IconCompat.createWithBitmap(checkbox); - } - - private PendingIntent getBroadcastIntent(String id, int requestCode, int action) { - final Intent intent = new Intent(getUri().toString()); - intent.setClass(mContext, SliceBroadcastReceiver.class); - intent.putExtra(MEDIA_DEVICE_ID, id); - intent.putExtra(CUSTOMIZED_ACTION, action); - intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); - return PendingIntent.getBroadcast(mContext, requestCode, intent, - PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); - } - - private MediaDeviceUpdateWorker getWorker() { - if (mWorker == null) { - mWorker = SliceBackgroundWorker.getInstance(getUri()); - } - return mWorker; - } - - @Override - public Uri getUri() { - return MEDIA_OUTPUT_GROUP_SLICE_URI; - } - - @Override - public void onNotifyChange(Intent intent) { - final String id = intent.getStringExtra(MEDIA_DEVICE_ID); - if (TextUtils.isEmpty(id)) { - Log.e(TAG, "Unable to handle notification. The device is unavailable"); - return; - } - final MediaDeviceUpdateWorker worker = getWorker(); - final MediaDevice device = worker.getMediaDeviceById(id); - switch (intent.getIntExtra(CUSTOMIZED_ACTION, ERROR)) { - case ACTION_VOLUME_ADJUSTMENT: - final int newPosition = intent.getIntExtra(EXTRA_RANGE_VALUE, ERROR); - if (newPosition == ERROR) { - Log.e(TAG, "Unable to adjust volume. The volume value is unavailable"); - return; - } - // Group volume adjustment - if (TextUtils.equals(id, GROUP_DEVICES)) { - worker.adjustSessionVolume(newPosition); - } else { - if (device == null) { - Log.e(TAG, "Unable to adjust volume. The device(" + id - + ") is unavailable"); - return; - } - // Single device volume adjustment - worker.adjustVolume(device, newPosition); - } - break; - case ACTION_MEDIA_SESSION_OPERATION: - if (device == null) { - Log.e(TAG, "Unable to adjust session volume. The device(" + id - + ") is unavailable"); - return; - } - if (worker.isDeviceIncluded(worker.getSelectableMediaDevice(), device)) { - worker.addDeviceToPlayMedia(device); - } else if (worker.isDeviceIncluded(worker.getDeselectableMediaDevice(), device)) { - worker.removeDeviceFromPlayMedia(device); - } else { - // Do nothing - Log.d(TAG, device.getName() + " is not selectable nor deselectable"); - } - break; - } - } - - @Override - public Intent getIntent() { - return null; - } - - @Override - public Class getBackgroundWorkerClass() { - return MediaDeviceUpdateWorker.class; - } -} diff --git a/src/com/android/settings/slices/CustomSliceRegistry.java b/src/com/android/settings/slices/CustomSliceRegistry.java index ce98d271830..2068f05c048 100644 --- a/src/com/android/settings/slices/CustomSliceRegistry.java +++ b/src/com/android/settings/slices/CustomSliceRegistry.java @@ -37,7 +37,6 @@ import com.android.settings.homepage.contextualcards.slices.DarkThemeSlice; import com.android.settings.homepage.contextualcards.slices.FaceSetupSlice; import com.android.settings.homepage.contextualcards.slices.LowStorageSlice; import com.android.settings.location.LocationSlice; -import com.android.settings.media.MediaOutputGroupSlice; import com.android.settings.media.MediaOutputIndicatorSlice; import com.android.settings.media.MediaOutputSlice; import com.android.settings.media.RemoteMediaSlice; @@ -345,7 +344,6 @@ public class CustomSliceRegistry { sUriToSlice.put(WIFI_SLICE_URI, WifiSlice.class); sUriToSlice.put(DARK_THEME_SLICE_URI, DarkThemeSlice.class); sUriToSlice.put(REMOTE_MEDIA_SLICE_URI, RemoteMediaSlice.class); - sUriToSlice.put(MEDIA_OUTPUT_GROUP_SLICE_URI, MediaOutputGroupSlice.class); sUriToSlice.put(ALWAYS_ON_SLICE_URI, AlwaysOnDisplaySlice.class); sUriToSlice.put(AIRPLANE_SAFE_NETWORKS_SLICE_URI, AirplaneSafeNetworksSlice.class); } diff --git a/tests/robotests/src/com/android/settings/media/MediaOutputGroupSliceTest.java b/tests/robotests/src/com/android/settings/media/MediaOutputGroupSliceTest.java deleted file mode 100644 index bb0478cc8b7..00000000000 --- a/tests/robotests/src/com/android/settings/media/MediaOutputGroupSliceTest.java +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.media; - -import static android.app.slice.Slice.EXTRA_RANGE_VALUE; -import static android.app.slice.Slice.HINT_LIST_ITEM; -import static android.app.slice.SliceItem.FORMAT_SLICE; - -import static com.android.settings.media.MediaOutputGroupSlice.ACTION_MEDIA_SESSION_OPERATION; -import static com.android.settings.media.MediaOutputGroupSlice.ACTION_VOLUME_ADJUSTMENT; -import static com.android.settings.media.MediaOutputGroupSlice.CUSTOMIZED_ACTION; -import static com.android.settings.media.MediaOutputGroupSlice.GROUP_DEVICES; -import static com.android.settings.media.MediaOutputGroupSlice.MEDIA_DEVICE_ID; -import static com.android.settings.slices.CustomSliceRegistry.MEDIA_OUTPUT_GROUP_SLICE_URI; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.content.Intent; -import android.graphics.drawable.Drawable; -import android.net.Uri; - -import androidx.slice.Slice; -import androidx.slice.SliceMetadata; -import androidx.slice.SliceProvider; -import androidx.slice.core.SliceAction; -import androidx.slice.core.SliceQuery; -import androidx.slice.widget.SliceLiveData; - -import com.android.settings.R; -import com.android.settings.slices.SliceBackgroundWorker; -import com.android.settingslib.media.LocalMediaManager; -import com.android.settingslib.media.MediaDevice; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; -import org.robolectric.annotation.Implementation; -import org.robolectric.annotation.Implements; - -import java.util.ArrayList; -import java.util.List; - -@RunWith(RobolectricTestRunner.class) -@Config(shadows = MediaOutputGroupSliceTest.ShadowSliceBackgroundWorker.class) -public class MediaOutputGroupSliceTest { - - private static final String TEST_PACKAGE_NAME = "com.test.music"; - private static final String TEST_PACKAGE_NAME2 = "com.test.music2"; - private static final String TEST_DEVICE_1_ID = "test_device_1_id"; - private static final String TEST_DEVICE_1_NAME = "test_device_1_name"; - private static final String TEST_DEVICE_2_ID = "test_device_2_id"; - private static final String TEST_DEVICE_2_NAME = "test_device_2_name"; - private static final int TEST_VOLUME = 3; - - private static MediaDeviceUpdateWorker sMediaDeviceUpdateWorker; - - @Mock - private LocalMediaManager mLocalMediaManager; - @Mock - private MediaDevice mDevice1; - @Mock - private MediaDevice mDevice2; - - private final List mSelectableDevices = new ArrayList<>(); - private final List mSelectedDevices = new ArrayList<>(); - private final List mDeselectableDevices = new ArrayList<>(); - - private Context mContext; - private MediaOutputGroupSlice mMediaOutputGroupSlice; - private Drawable mDrawable; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - mContext = spy(RuntimeEnvironment.application); - - // Set-up specs for SliceMetadata. - SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS); - - mMediaOutputGroupSlice = new MediaOutputGroupSlice(mContext); - sMediaDeviceUpdateWorker = spy(new MediaDeviceUpdateWorker(mContext, - MEDIA_OUTPUT_GROUP_SLICE_URI)); - sMediaDeviceUpdateWorker.mLocalMediaManager = mLocalMediaManager; - when(sMediaDeviceUpdateWorker.getPackageName()).thenReturn(TEST_PACKAGE_NAME); - mDrawable = mContext.getDrawable(R.drawable.ic_check_box_blue_24dp); - when(sMediaDeviceUpdateWorker.getSelectableMediaDevice()).thenReturn(mSelectableDevices); - doReturn(false).when(sMediaDeviceUpdateWorker).hasAdjustVolumeUserRestriction(); - when(mDevice1.getId()).thenReturn(TEST_DEVICE_1_ID); - when(mDevice1.getIcon()).thenReturn(mDrawable); - when(mDevice1.getName()).thenReturn(TEST_DEVICE_1_NAME); - when(mDevice1.getMaxVolume()).thenReturn(100); - when(mDevice1.getCurrentVolume()).thenReturn(10); - when(mDevice1.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME); - when(mDevice2.getId()).thenReturn(TEST_DEVICE_2_ID); - when(mDevice2.getIcon()).thenReturn(mDrawable); - when(mDevice2.getName()).thenReturn(TEST_DEVICE_2_NAME); - when(mDevice2.getMaxVolume()).thenReturn(100); - when(mDevice2.getCurrentVolume()).thenReturn(20); - } - - @Test - public void getSlice_noMatchedDevice_doNothing() { - mSelectableDevices.add(mDevice1); - mSelectedDevices.add(mDevice1); - when(mLocalMediaManager.getMediaDeviceById(mSelectableDevices, TEST_DEVICE_1_ID)) - .thenReturn(mDevice1); - sMediaDeviceUpdateWorker.onDeviceListUpdate(mSelectableDevices); - when(sMediaDeviceUpdateWorker.getSelectedMediaDevice()).thenReturn(mSelectedDevices); - final Intent intent = new Intent(); - intent.putExtra(EXTRA_RANGE_VALUE, TEST_VOLUME); - intent.putExtra(MEDIA_DEVICE_ID, TEST_DEVICE_2_ID); - intent.putExtra(CUSTOMIZED_ACTION, ACTION_VOLUME_ADJUSTMENT); - - mMediaOutputGroupSlice.onNotifyChange(intent); - - verify(sMediaDeviceUpdateWorker, never()).adjustSessionVolume(anyInt()); - verify(mDevice1, never()).requestSetVolume(TEST_VOLUME); - } - - @Test - public void getSlice_withOneSelectableDevice_checkRowNumber() { - mSelectableDevices.add(mDevice1); - mSelectedDevices.add(mDevice2); - when(sMediaDeviceUpdateWorker.getSelectedMediaDevice()).thenReturn(mSelectedDevices); - when(sMediaDeviceUpdateWorker.getSelectableMediaDevice()).thenReturn(mSelectableDevices); - final Slice slice = mMediaOutputGroupSlice.getSlice(); - final int rows = SliceQuery.findAll(slice, FORMAT_SLICE, HINT_LIST_ITEM, null).size(); - - // Group item and 2 * InputRange - assertThat(rows).isEqualTo(3); - } - - @Test - public void getSlice_nullWorker_noException() { - sMediaDeviceUpdateWorker = null; - mMediaOutputGroupSlice.getSlice(); - } - - @Test - public void getSlice_withOneSelectableDevice_checkTitle() { - mSelectableDevices.add(mDevice1); - mSelectedDevices.add(mDevice1); - sMediaDeviceUpdateWorker.onDeviceListUpdate(mSelectableDevices); - when(sMediaDeviceUpdateWorker.getSelectedMediaDevice()).thenReturn(mSelectedDevices); - final Slice slice = mMediaOutputGroupSlice.getSlice(); - final SliceMetadata metadata = SliceMetadata.from(mContext, slice); - final SliceAction primaryAction = metadata.getPrimaryAction(); - - assertThat(primaryAction.getTitle().toString()).isEqualTo(GROUP_DEVICES); - } - - @Test - public void onNotifyChange_verifyAdjustDeviceVolume() { - mSelectableDevices.add(mDevice1); - mSelectedDevices.add(mDevice1); - when(mLocalMediaManager.getMediaDeviceById(mSelectableDevices, TEST_DEVICE_1_ID)) - .thenReturn(mDevice1); - sMediaDeviceUpdateWorker.onDeviceListUpdate(mSelectableDevices); - when(sMediaDeviceUpdateWorker.getSelectedMediaDevice()).thenReturn(mSelectedDevices); - final Intent intent = new Intent(); - intent.putExtra(EXTRA_RANGE_VALUE, TEST_VOLUME); - intent.putExtra(MEDIA_DEVICE_ID, TEST_DEVICE_1_ID); - intent.putExtra(CUSTOMIZED_ACTION, ACTION_VOLUME_ADJUSTMENT); - - mMediaOutputGroupSlice.onNotifyChange(intent); - - verify(mDevice1).requestSetVolume(TEST_VOLUME); - } - - @Test - public void onNotifyChange_verifyAdjustGroupVolume() { - mSelectableDevices.add(mDevice1); - mSelectedDevices.add(mDevice1); - when(mLocalMediaManager.getMediaDeviceById(mSelectableDevices, TEST_DEVICE_1_ID)) - .thenReturn(mDevice1); - sMediaDeviceUpdateWorker.onDeviceListUpdate(mSelectableDevices); - when(sMediaDeviceUpdateWorker.getSelectedMediaDevice()).thenReturn(mSelectedDevices); - final Intent intent = new Intent(); - intent.putExtra(EXTRA_RANGE_VALUE, TEST_VOLUME); - intent.putExtra(MEDIA_DEVICE_ID, GROUP_DEVICES); - intent.putExtra(CUSTOMIZED_ACTION, ACTION_VOLUME_ADJUSTMENT); - - mMediaOutputGroupSlice.onNotifyChange(intent); - - verify(sMediaDeviceUpdateWorker).adjustSessionVolume(TEST_VOLUME); - } - - @Test - public void onNotifyChange_sendSelectableDevice_verifyAddSession() { - mSelectableDevices.add(mDevice2); - mSelectedDevices.add(mDevice1); - when(mLocalMediaManager.getMediaDeviceById(mSelectableDevices, TEST_DEVICE_2_ID)) - .thenReturn(mDevice2); - sMediaDeviceUpdateWorker.onDeviceListUpdate(mSelectableDevices); - when(sMediaDeviceUpdateWorker.getSelectedMediaDevice()).thenReturn(mSelectedDevices); - final Intent intent = new Intent(); - intent.putExtra(MEDIA_DEVICE_ID, TEST_DEVICE_2_ID); - intent.putExtra(CUSTOMIZED_ACTION, ACTION_MEDIA_SESSION_OPERATION); - - mMediaOutputGroupSlice.onNotifyChange(intent); - - verify(sMediaDeviceUpdateWorker).addDeviceToPlayMedia(mDevice2); - } - - @Test - public void onNotifyChange_sendDeselectableDevice_verifyRemoveSession() { - mSelectedDevices.add(mDevice1); - mSelectedDevices.add(mDevice2); - mDeselectableDevices.add(mDevice1); - mDeselectableDevices.add(mDevice2); - when(mLocalMediaManager.getMediaDeviceById(mSelectedDevices, TEST_DEVICE_2_ID)) - .thenReturn(mDevice2); - sMediaDeviceUpdateWorker.onDeviceListUpdate(mSelectedDevices); - when(sMediaDeviceUpdateWorker.getSelectedMediaDevice()).thenReturn(mSelectedDevices); - when(sMediaDeviceUpdateWorker.getDeselectableMediaDevice()).thenReturn( - mDeselectableDevices); - final Intent intent = new Intent(); - intent.putExtra(MEDIA_DEVICE_ID, TEST_DEVICE_2_ID); - intent.putExtra(CUSTOMIZED_ACTION, ACTION_MEDIA_SESSION_OPERATION); - - mMediaOutputGroupSlice.onNotifyChange(intent); - - verify(sMediaDeviceUpdateWorker).removeDeviceFromPlayMedia(mDevice2); - } - - @Test - public void onNotifyChange_sendNonDeselectableDevice_notRemoveSession() { - mSelectedDevices.add(mDevice1); - mSelectedDevices.add(mDevice2); - mDeselectableDevices.add(mDevice1); - when(mLocalMediaManager.getMediaDeviceById(mSelectedDevices, TEST_DEVICE_2_ID)) - .thenReturn(mDevice2); - sMediaDeviceUpdateWorker.onDeviceListUpdate(mSelectedDevices); - when(sMediaDeviceUpdateWorker.getSelectedMediaDevice()).thenReturn(mSelectedDevices); - when(sMediaDeviceUpdateWorker.getDeselectableMediaDevice()).thenReturn( - mDeselectableDevices); - final Intent intent = new Intent(); - intent.putExtra(MEDIA_DEVICE_ID, TEST_DEVICE_2_ID); - intent.putExtra(CUSTOMIZED_ACTION, ACTION_MEDIA_SESSION_OPERATION); - - mMediaOutputGroupSlice.onNotifyChange(intent); - - verify(sMediaDeviceUpdateWorker, never()).removeDeviceFromPlayMedia(mDevice2); - } - - @Test - public void onNotifyChange_noId_doNothing() { - mSelectableDevices.add(mDevice1); - mSelectedDevices.add(mDevice1); - when(mLocalMediaManager.getMediaDeviceById(mSelectableDevices, TEST_DEVICE_1_ID)) - .thenReturn(mDevice1); - sMediaDeviceUpdateWorker.onDeviceListUpdate(mSelectableDevices); - when(sMediaDeviceUpdateWorker.getSelectedMediaDevice()).thenReturn(mSelectedDevices); - final Intent intent = new Intent(); - intent.putExtra(EXTRA_RANGE_VALUE, TEST_VOLUME); - intent.putExtra(CUSTOMIZED_ACTION, ACTION_VOLUME_ADJUSTMENT); - - mMediaOutputGroupSlice.onNotifyChange(intent); - - verify(sMediaDeviceUpdateWorker, never()).adjustSessionVolume(anyInt()); - verify(mDevice1, never()).requestSetVolume(TEST_VOLUME); - } - - @Implements(SliceBackgroundWorker.class) - public static class ShadowSliceBackgroundWorker { - - @Implementation - public static SliceBackgroundWorker getInstance(Uri uri) { - return sMediaDeviceUpdateWorker; - } - } -}