diff options
Diffstat (limited to 'packages/SystemUI')
4 files changed, 660 insertions, 0 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupAdapter.java new file mode 100644 index 000000000000..ceb4495bd8e8 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupAdapter.java @@ -0,0 +1,220 @@ +/* + * 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.systemui.media.dialog; + +import android.content.res.ColorStateList; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffColorFilter; +import android.graphics.drawable.Drawable; +import android.text.TextUtils; +import android.util.Log; +import android.util.TypedValue; +import android.view.View; +import android.view.ViewGroup; +import android.widget.SeekBar; + +import androidx.annotation.NonNull; + +import com.android.settingslib.bluetooth.BluetoothUtils; +import com.android.settingslib.media.MediaDevice; +import com.android.systemui.R; + +import java.util.List; + +/** + * Adapter for media output dynamic group dialog. + */ +public class MediaOutputGroupAdapter extends MediaOutputBaseAdapter { + + private static final String TAG = "MediaOutputGroupAdapter"; + private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + + private final List<MediaDevice> mGroupMediaDevices; + + public MediaOutputGroupAdapter(MediaOutputController controller) { + super(controller); + mGroupMediaDevices = controller.getGroupMediaDevices(); + } + + @Override + public MediaDeviceBaseViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, + int viewType) { + super.onCreateViewHolder(viewGroup, viewType); + + return new GroupViewHolder(mHolderView); + } + + @Override + public void onBindViewHolder(@NonNull MediaDeviceBaseViewHolder viewHolder, int position) { + // Add "Group" + if (position == 0) { + viewHolder.onBind(CUSTOMIZED_ITEM_GROUP, true /* topMargin */, + false /* bottomMargin */); + return; + } + // Add available devices + final int newPosition = position - 1; + final int size = mGroupMediaDevices.size(); + if (newPosition < size) { + viewHolder.onBind(mGroupMediaDevices.get(newPosition), false /* topMargin */, + newPosition == (size - 1) /* bottomMargin */); + return; + } + if (DEBUG) { + Log.d(TAG, "Incorrect position: " + position); + } + } + + @Override + public int getItemCount() { + // Require extra item for group volume operation + return mGroupMediaDevices.size() + 1; + } + + @Override + CharSequence getItemTitle(MediaDevice device) { + return super.getItemTitle(device); + } + + class GroupViewHolder extends MediaDeviceBaseViewHolder { + + GroupViewHolder(View view) { + super(view); + } + + @Override + void onBind(MediaDevice device, boolean topMargin, boolean bottomMargin) { + super.onBind(device, topMargin, bottomMargin); + mDivider.setVisibility(View.GONE); + mAddIcon.setVisibility(View.GONE); + mBottomDivider.setVisibility(View.GONE); + mCheckBox.setVisibility(View.VISIBLE); + mCheckBox.setOnCheckedChangeListener((buttonView, isChecked) -> { + onCheckBoxClicked(isChecked, device); + }); + setTwoLineLayout(device, false /* bFocused */, true /* showSeekBar */, + false /* showProgressBar */, false /* showSubtitle*/); + initSeekbar(device); + final List<MediaDevice> selectedDevices = mController.getSelectedMediaDevice(); + if (isDeviceIncluded(mController.getSelectableMediaDevice(), device)) { + mCheckBox.setButtonDrawable(R.drawable.ic_check_box); + mCheckBox.setChecked(false); + mCheckBox.setEnabled(true); + } else if (isDeviceIncluded(selectedDevices, device)) { + if (selectedDevices.size() == 1 || !isDeviceIncluded( + mController.getDeselectableMediaDevice(), device)) { + mCheckBox.setButtonDrawable(getDisabledCheckboxDrawable()); + mCheckBox.setChecked(true); + mCheckBox.setEnabled(false); + } else { + mCheckBox.setButtonDrawable(R.drawable.ic_check_box); + mCheckBox.setChecked(true); + mCheckBox.setEnabled(true); + } + } + } + + @Override + void onBind(int customizedItem, boolean topMargin, boolean bottomMargin) { + super.onBind(customizedItem, topMargin, bottomMargin); + if (customizedItem == CUSTOMIZED_ITEM_GROUP) { + setTwoLineLayout(mContext.getText(R.string.media_output_dialog_group), + true /* bFocused */, true /* showSeekBar */, false /* showProgressBar */, + false /* showSubtitle*/); + mTitleIcon.setImageDrawable(getSpeakerDrawable()); + mBottomDivider.setVisibility(View.VISIBLE); + mCheckBox.setVisibility(View.GONE); + mDivider.setVisibility(View.GONE); + mAddIcon.setVisibility(View.GONE); + initSessionSeekbar(); + } + } + + private void onCheckBoxClicked(boolean isChecked, MediaDevice device) { + if (isChecked && isDeviceIncluded(mController.getSelectableMediaDevice(), device)) { + mController.addDeviceToPlayMedia(device); + } else if (!isChecked && isDeviceIncluded(mController.getDeselectableMediaDevice(), + device)) { + mController.removeDeviceFromPlayMedia(device); + } + } + + private void initSessionSeekbar() { + mSeekBar.setMax(mController.getSessionVolumeMax()); + mSeekBar.setMin(0); + final int currentVolume = mController.getSessionVolume(); + if (mSeekBar.getProgress() != currentVolume) { + mSeekBar.setProgress(currentVolume); + } + mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + if (!fromUser) { + return; + } + mController.adjustSessionVolume(progress); + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + mIsDragging = true; + } + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + mIsDragging = false; + } + }); + } + + private Drawable getDisabledCheckboxDrawable() { + 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); + TypedValue value = new TypedValue(); + mContext.getTheme().resolveAttribute(android.R.attr.disabledAlpha, value, true); + drawable.setAlpha((int) (value.getFloat() * 255)); + drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); + drawable.draw(canvas); + + return drawable; + } + + private Drawable getSpeakerDrawable() { + final Drawable drawable = mContext.getDrawable(R.drawable.ic_speaker_group_black_24dp) + .mutate(); + final ColorStateList list = mContext.getResources().getColorStateList( + R.color.advanced_icon_color, mContext.getTheme()); + drawable.setColorFilter(new PorterDuffColorFilter(list.getDefaultColor(), + PorterDuff.Mode.SRC_IN)); + return BluetoothUtils.buildAdvancedDrawable(mContext, drawable); + } + + private boolean isDeviceIncluded(List<MediaDevice> deviceList, MediaDevice targetDevice) { + for (MediaDevice device : deviceList) { + if (TextUtils.equals(device.getId(), targetDevice.getId())) { + return true; + } + } + return false; + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupDialog.java new file mode 100644 index 000000000000..407930492fbe --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupDialog.java @@ -0,0 +1,88 @@ +/* + * 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.systemui.media.dialog; + +import android.content.Context; +import android.os.Bundle; +import android.view.View; +import android.view.WindowManager; + +import androidx.core.graphics.drawable.IconCompat; + +import com.android.systemui.R; + +/** + * Dialog for media output group. + */ +public class MediaOutputGroupDialog extends MediaOutputBaseDialog { + + MediaOutputGroupDialog(Context context, boolean aboveStatusbar, MediaOutputController + mediaOutputController) { + super(context, mediaOutputController); + mMediaOutputController.resetGroupMediaDevices(); + mAdapter = new MediaOutputGroupAdapter(mMediaOutputController); + if (!aboveStatusbar) { + getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY); + } + show(); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + int getHeaderIconRes() { + return R.drawable.ic_arrow_back; + } + + @Override + IconCompat getHeaderIcon() { + return null; + } + + @Override + int getHeaderIconSize() { + return mContext.getResources().getDimensionPixelSize( + R.dimen.media_output_dialog_header_back_icon_size); + } + + @Override + CharSequence getHeaderText() { + return mContext.getString(R.string.media_output_dialog_add_output); + } + + @Override + CharSequence getHeaderSubtitle() { + final int size = mMediaOutputController.getSelectedMediaDevice().size(); + if (size == 1) { + return mContext.getText(R.string.media_output_dialog_single_device); + } + return mContext.getString(R.string.media_output_dialog_multiple_devices, size); + } + + @Override + int getStopButtonVisibility() { + return View.VISIBLE; + } + + @Override + void onHeaderIconClick() { + mMediaOutputController.launchMediaOutputDialog(); + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputGroupAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputGroupAdapterTest.java new file mode 100644 index 000000000000..1f85112dfb74 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputGroupAdapterTest.java @@ -0,0 +1,248 @@ +/* + * 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.systemui.media.dialog; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.graphics.drawable.Icon; +import android.testing.AndroidTestingRunner; +import android.view.View; +import android.widget.LinearLayout; + +import androidx.core.graphics.drawable.IconCompat; +import androidx.test.filters.SmallTest; + +import com.android.settingslib.media.MediaDevice; +import com.android.systemui.R; +import com.android.systemui.SysuiTestCase; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.ArrayList; +import java.util.List; + +@SmallTest +@RunWith(AndroidTestingRunner.class) +public class MediaOutputGroupAdapterTest extends SysuiTestCase { + + private static final String TEST_DEVICE_NAME_1 = "test_device_name_1"; + private static final String TEST_DEVICE_NAME_2 = "test_device_name_2"; + private static final String TEST_DEVICE_ID_1 = "test_device_id_1"; + private static final String TEST_DEVICE_ID_2 = "test_device_id_2"; + private static final int TEST_VOLUME = 10; + private static final int TEST_MAX_VOLUME = 50; + + // Mock + private MediaOutputController mMediaOutputController = mock(MediaOutputController.class); + private MediaDevice mMediaDevice1 = mock(MediaDevice.class); + private MediaDevice mMediaDevice2 = mock(MediaDevice.class); + private Icon mIcon = mock(Icon.class); + private IconCompat mIconCompat = mock(IconCompat.class); + + private MediaOutputGroupAdapter mGroupAdapter; + private MediaOutputGroupAdapter.GroupViewHolder mGroupViewHolder; + private List<MediaDevice> mGroupMediaDevices = new ArrayList<>(); + private List<MediaDevice> mSelectableMediaDevices = new ArrayList<>(); + private List<MediaDevice> mSelectedMediaDevices = new ArrayList<>(); + private List<MediaDevice> mDeselectableMediaDevices = new ArrayList<>(); + + @Before + public void setUp() { + when(mMediaOutputController.getGroupMediaDevices()).thenReturn(mGroupMediaDevices); + when(mMediaOutputController.getDeviceIconCompat(mMediaDevice1)).thenReturn(mIconCompat); + when(mMediaOutputController.getDeviceIconCompat(mMediaDevice2)).thenReturn(mIconCompat); + when(mMediaOutputController.getSelectableMediaDevice()).thenReturn(mSelectableMediaDevices); + when(mMediaOutputController.getSelectedMediaDevice()).thenReturn(mSelectedMediaDevices); + when(mMediaOutputController.getDeselectableMediaDevice()).thenReturn( + mDeselectableMediaDevices); + when(mIconCompat.toIcon(mContext)).thenReturn(mIcon); + when(mMediaDevice1.getName()).thenReturn(TEST_DEVICE_NAME_1); + when(mMediaDevice1.getId()).thenReturn(TEST_DEVICE_ID_1); + when(mMediaDevice2.getName()).thenReturn(TEST_DEVICE_NAME_2); + when(mMediaDevice2.getId()).thenReturn(TEST_DEVICE_ID_2); + mGroupMediaDevices.add(mMediaDevice1); + mGroupMediaDevices.add(mMediaDevice2); + mSelectedMediaDevices.add(mMediaDevice1); + mSelectableMediaDevices.add(mMediaDevice2); + mDeselectableMediaDevices.add(mMediaDevice1); + + mGroupAdapter = new MediaOutputGroupAdapter(mMediaOutputController); + mGroupViewHolder = (MediaOutputGroupAdapter.GroupViewHolder) mGroupAdapter + .onCreateViewHolder(new LinearLayout(mContext), 0); + } + + @Test + public void onBindViewHolder_verifyGroupItem() { + mGroupAdapter.onBindViewHolder(mGroupViewHolder, 0); + + assertThat(mGroupViewHolder.mTitleText.getVisibility()).isEqualTo(View.GONE); + assertThat(mGroupViewHolder.mCheckBox.getVisibility()).isEqualTo(View.GONE); + assertThat(mGroupViewHolder.mSubTitleText.getVisibility()).isEqualTo(View.GONE); + assertThat(mGroupViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE); + assertThat(mGroupViewHolder.mDivider.getVisibility()).isEqualTo(View.GONE); + assertThat(mGroupViewHolder.mAddIcon.getVisibility()).isEqualTo(View.GONE); + assertThat(mGroupViewHolder.mBottomDivider.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mGroupViewHolder.mSeekBar.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mGroupViewHolder.mTwoLineTitleText.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mGroupViewHolder.mTwoLineTitleText.getText()).isEqualTo(mContext.getText( + R.string.media_output_dialog_group)); + } + + @Test + public void onBindViewHolder_singleSelectedDevice_verifyView() { + mGroupAdapter.onBindViewHolder(mGroupViewHolder, 1); + + assertThat(mGroupViewHolder.mTitleText.getVisibility()).isEqualTo(View.GONE); + assertThat(mGroupViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE); + assertThat(mGroupViewHolder.mDivider.getVisibility()).isEqualTo(View.GONE); + assertThat(mGroupViewHolder.mAddIcon.getVisibility()).isEqualTo(View.GONE); + assertThat(mGroupViewHolder.mBottomDivider.getVisibility()).isEqualTo(View.GONE); + assertThat(mGroupViewHolder.mSubTitleText.getVisibility()).isEqualTo(View.GONE); + assertThat(mGroupViewHolder.mSeekBar.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mGroupViewHolder.mTwoLineTitleText.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mGroupViewHolder.mTwoLineTitleText.getText()).isEqualTo(TEST_DEVICE_NAME_1); + assertThat(mGroupViewHolder.mCheckBox.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mGroupViewHolder.mCheckBox.isChecked()).isTrue(); + // Disabled checkBox + assertThat(mGroupViewHolder.mCheckBox.isEnabled()).isFalse(); + } + + @Test + public void onBindViewHolder_multipleSelectedDevice_verifyView() { + mSelectedMediaDevices.clear(); + mSelectedMediaDevices.add(mMediaDevice1); + mSelectedMediaDevices.add(mMediaDevice2); + mDeselectableMediaDevices.clear(); + mDeselectableMediaDevices.add(mMediaDevice1); + mDeselectableMediaDevices.add(mMediaDevice2); + mSelectableMediaDevices.clear(); + + mGroupAdapter.onBindViewHolder(mGroupViewHolder, 1); + + assertThat(mGroupViewHolder.mTitleText.getVisibility()).isEqualTo(View.GONE); + assertThat(mGroupViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE); + assertThat(mGroupViewHolder.mDivider.getVisibility()).isEqualTo(View.GONE); + assertThat(mGroupViewHolder.mAddIcon.getVisibility()).isEqualTo(View.GONE); + assertThat(mGroupViewHolder.mBottomDivider.getVisibility()).isEqualTo(View.GONE); + assertThat(mGroupViewHolder.mSubTitleText.getVisibility()).isEqualTo(View.GONE); + assertThat(mGroupViewHolder.mSeekBar.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mGroupViewHolder.mTwoLineTitleText.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mGroupViewHolder.mTwoLineTitleText.getText()).isEqualTo(TEST_DEVICE_NAME_1); + assertThat(mGroupViewHolder.mCheckBox.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mGroupViewHolder.mCheckBox.isChecked()).isTrue(); + // Enabled checkBox + assertThat(mGroupViewHolder.mCheckBox.isEnabled()).isTrue(); + } + + @Test + public void onBindViewHolder_notDeselectedDevice_verifyView() { + mSelectedMediaDevices.clear(); + mSelectedMediaDevices.add(mMediaDevice1); + mSelectedMediaDevices.add(mMediaDevice2); + mDeselectableMediaDevices.clear(); + mDeselectableMediaDevices.add(mMediaDevice1); + mSelectableMediaDevices.clear(); + + mGroupAdapter.onBindViewHolder(mGroupViewHolder, 2); + + assertThat(mGroupViewHolder.mTitleText.getVisibility()).isEqualTo(View.GONE); + assertThat(mGroupViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE); + assertThat(mGroupViewHolder.mDivider.getVisibility()).isEqualTo(View.GONE); + assertThat(mGroupViewHolder.mAddIcon.getVisibility()).isEqualTo(View.GONE); + assertThat(mGroupViewHolder.mBottomDivider.getVisibility()).isEqualTo(View.GONE); + assertThat(mGroupViewHolder.mSubTitleText.getVisibility()).isEqualTo(View.GONE); + assertThat(mGroupViewHolder.mSeekBar.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mGroupViewHolder.mTwoLineTitleText.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mGroupViewHolder.mTwoLineTitleText.getText()).isEqualTo(TEST_DEVICE_NAME_2); + assertThat(mGroupViewHolder.mCheckBox.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mGroupViewHolder.mCheckBox.isChecked()).isTrue(); + // Disabled checkBox + assertThat(mGroupViewHolder.mCheckBox.isEnabled()).isFalse(); + } + + @Test + public void onBindViewHolder_selectableDevice_verifyCheckBox() { + mGroupAdapter.onBindViewHolder(mGroupViewHolder, 2); + + assertThat(mGroupViewHolder.mTitleText.getVisibility()).isEqualTo(View.GONE); + assertThat(mGroupViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE); + assertThat(mGroupViewHolder.mDivider.getVisibility()).isEqualTo(View.GONE); + assertThat(mGroupViewHolder.mAddIcon.getVisibility()).isEqualTo(View.GONE); + assertThat(mGroupViewHolder.mBottomDivider.getVisibility()).isEqualTo(View.GONE); + assertThat(mGroupViewHolder.mSubTitleText.getVisibility()).isEqualTo(View.GONE); + assertThat(mGroupViewHolder.mSeekBar.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mGroupViewHolder.mTwoLineTitleText.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mGroupViewHolder.mTwoLineTitleText.getText()).isEqualTo(TEST_DEVICE_NAME_2); + assertThat(mGroupViewHolder.mCheckBox.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mGroupViewHolder.mCheckBox.isChecked()).isFalse(); + // Enabled checkBox + assertThat(mGroupViewHolder.mCheckBox.isEnabled()).isTrue(); + } + + @Test + public void onBindViewHolder_verifySessionVolume() { + when(mMediaOutputController.getSessionVolume()).thenReturn(TEST_VOLUME); + when(mMediaOutputController.getSessionVolumeMax()).thenReturn(TEST_MAX_VOLUME); + + mGroupAdapter.onBindViewHolder(mGroupViewHolder, 0); + + assertThat(mGroupViewHolder.mSeekBar.getProgress()).isEqualTo(TEST_VOLUME); + assertThat(mGroupViewHolder.mSeekBar.getMax()).isEqualTo(TEST_MAX_VOLUME); + } + + @Test + public void onBindViewHolder_verifyDeviceVolume() { + when(mMediaDevice1.getCurrentVolume()).thenReturn(TEST_VOLUME); + when(mMediaDevice1.getMaxVolume()).thenReturn(TEST_MAX_VOLUME); + + mGroupAdapter.onBindViewHolder(mGroupViewHolder, 1); + + assertThat(mGroupViewHolder.mSeekBar.getProgress()).isEqualTo(TEST_VOLUME); + assertThat(mGroupViewHolder.mSeekBar.getMax()).isEqualTo(TEST_MAX_VOLUME); + } + + @Test + public void clickSelectedDevice_verifyRemoveDeviceFromPlayMedia() { + mSelectedMediaDevices.clear(); + mSelectedMediaDevices.add(mMediaDevice1); + mSelectedMediaDevices.add(mMediaDevice2); + mDeselectableMediaDevices.clear(); + mDeselectableMediaDevices.add(mMediaDevice1); + mDeselectableMediaDevices.add(mMediaDevice2); + mSelectableMediaDevices.clear(); + + mGroupAdapter.onBindViewHolder(mGroupViewHolder, 1); + mGroupViewHolder.mCheckBox.performClick(); + + verify(mMediaOutputController).removeDeviceFromPlayMedia(mMediaDevice1); + } + + @Test + public void clickSelectabelDevice_verifyAddDeviceToPlayMedia() { + mGroupAdapter.onBindViewHolder(mGroupViewHolder, 2); + + mGroupViewHolder.mCheckBox.performClick(); + + verify(mMediaOutputController).addDeviceToPlayMedia(mMediaDevice2); + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputGroupDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputGroupDialogTest.java new file mode 100644 index 000000000000..10f2bd5e4699 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputGroupDialogTest.java @@ -0,0 +1,104 @@ +/* + * 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.systemui.media.dialog; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import android.media.session.MediaSessionManager; +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; +import android.view.View; + +import androidx.test.filters.SmallTest; + +import com.android.settingslib.bluetooth.LocalBluetoothManager; +import com.android.settingslib.media.LocalMediaManager; +import com.android.settingslib.media.MediaDevice; +import com.android.systemui.R; +import com.android.systemui.SysuiTestCase; +import com.android.systemui.plugins.ActivityStarter; +import com.android.systemui.statusbar.phone.ShadeController; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.ArrayList; +import java.util.List; + +@SmallTest +@RunWith(AndroidTestingRunner.class) +@TestableLooper.RunWithLooper +public class MediaOutputGroupDialogTest extends SysuiTestCase { + + private static final String TEST_PACKAGE = "test_package"; + + // Mock + private MediaSessionManager mMediaSessionManager = mock(MediaSessionManager.class); + private LocalBluetoothManager mLocalBluetoothManager = mock(LocalBluetoothManager.class); + private ShadeController mShadeController = mock(ShadeController.class); + private ActivityStarter mStarter = mock(ActivityStarter.class); + private LocalMediaManager mLocalMediaManager = mock(LocalMediaManager.class); + private MediaDevice mMediaDevice = mock(MediaDevice.class); + private MediaDevice mMediaDevice1 = mock(MediaDevice.class); + + private MediaOutputGroupDialog mMediaOutputGroupDialog; + private MediaOutputController mMediaOutputController; + private List<MediaDevice> mMediaDevices = new ArrayList<>(); + + @Before + public void setUp() { + mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE, false, + mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter); + mMediaOutputController.mLocalMediaManager = mLocalMediaManager; + mMediaOutputGroupDialog = new MediaOutputGroupDialog(mContext, false, + mMediaOutputController); + when(mLocalMediaManager.getSelectedMediaDevice()).thenReturn(mMediaDevices); + } + + @After + public void tearDown() { + mMediaOutputGroupDialog.dismissDialog(); + } + + @Test + public void getStopButtonVisibility_returnVisible() { + assertThat(mMediaOutputGroupDialog.getStopButtonVisibility()).isEqualTo(View.VISIBLE); + } + + @Test + public void getHeaderSubtitle_singleDevice_verifyTitle() { + mMediaDevices.add(mMediaDevice); + + assertThat(mMediaOutputGroupDialog.getHeaderSubtitle()).isEqualTo( + mContext.getText(R.string.media_output_dialog_single_device)); + } + + @Test + public void getHeaderSubtitle_multipleDevices_verifyTitle() { + mMediaDevices.add(mMediaDevice); + mMediaDevices.add(mMediaDevice1); + + assertThat(mMediaOutputGroupDialog.getHeaderSubtitle()).isEqualTo(mContext.getString( + R.string.media_output_dialog_multiple_devices, mMediaDevices.size())); + } + +} |