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

Commit 634abfaf authored by timhypeng's avatar timhypeng Committed by tim peng
Browse files

Add dynamic group operation in output switcher

-Add MediaOutputGroupAdapter for device view layout
-Add MediaOutputGroupDialog for dialog header and buttom
-Add test cases

Bug: 155822415
Test: atest MediaOutputAdapterTest MediaOutputControllerTest MediaOutputBaseDialogTest MediaOutputDialogTest MediaOutputGroupAdapterTest MediaOutputGroupDialogTest
Merged-In: I82b52485229b7aa8b80a6ef13fc9aac14af87446
Change-Id: I82b52485229b7aa8b80a6ef13fc9aac14af87446
parent 3de24ae2
Loading
Loading
Loading
Loading
+220 −0
Original line number Diff line number Diff line
/*
 * 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;
        }
    }
}
+88 −0
Original line number Diff line number Diff line
/*
 * 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();
    }
}
+248 −0
Original line number Diff line number Diff line
/*
 * 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);
    }
}
+104 −0

File added.

Preview size limit exceeded, changes collapsed.