diff options
14 files changed, 477 insertions, 134 deletions
diff --git a/packages/SystemUI/res/drawable/ic_check_box.xml b/packages/SystemUI/res/drawable/ic_check_box.xml new file mode 100644 index 000000000000..a8d1a652b35b --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_check_box.xml @@ -0,0 +1,26 @@ +<!-- + 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 + --> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item + android:id="@+id/checked" + android:state_checked="true" + android:drawable="@drawable/ic_check_box_blue_24dp" /> + <item + android:id="@+id/unchecked" + android:state_checked="false" + android:drawable="@drawable/ic_check_box_outline_24dp" /> +</selector> diff --git a/packages/SystemUI/res/drawable/ic_check_box_blue_24dp.xml b/packages/SystemUI/res/drawable/ic_check_box_blue_24dp.xml new file mode 100644 index 000000000000..43cae6983981 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_check_box_blue_24dp.xml @@ -0,0 +1,26 @@ +<!-- + 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 + --> + +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:pathData="M19,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.11,0 2,-0.9 2,-2L21,5c0,-1.1 -0.89,-2 -2,-2zM10,17l-5,-5 1.41,-1.41L10,14.17l7.59,-7.59L19,8l-9,9z" + android:fillColor="#4285F4"/> +</vector> + diff --git a/packages/SystemUI/res/drawable/ic_check_box_outline_24dp.xml b/packages/SystemUI/res/drawable/ic_check_box_outline_24dp.xml new file mode 100644 index 000000000000..f6f453af2a26 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_check_box_outline_24dp.xml @@ -0,0 +1,26 @@ +<!-- + 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 + --> + +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:pathData="M19,5v14H5V5h14m0,-2H5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2V5c0,-1.1 -0.9,-2 -2,-2z" + android:fillColor="#757575"/> +</vector> + diff --git a/packages/SystemUI/res/drawable/ic_speaker_group_black_24dp.xml b/packages/SystemUI/res/drawable/ic_speaker_group_black_24dp.xml new file mode 100644 index 000000000000..ae0d56217fd9 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_speaker_group_black_24dp.xml @@ -0,0 +1,31 @@ +<!-- + 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 + --> + +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:pathData="M18.2,1L9.8,1C8.81,1 8,1.81 8,2.8v14.4c0,0.99 0.81,1.79 1.8,1.79l8.4,0.01c0.99,0 1.8,-0.81 1.8,-1.8L20,2.8c0,-0.99 -0.81,-1.8 -1.8,-1.8zM14,3c1.1,0 2,0.89 2,2s-0.9,2 -2,2 -2,-0.89 -2,-2 0.9,-2 2,-2zM14,16.5c-2.21,0 -4,-1.79 -4,-4s1.79,-4 4,-4 4,1.79 4,4 -1.79,4 -4,4z" + android:fillColor="#000000"/> + <path + android:pathData="M14,12.5m-2.5,0a2.5,2.5 0,1 1,5 0a2.5,2.5 0,1 1,-5 0" + android:fillColor="#000000"/> + <path + android:pathData="M6,5H4v16c0,1.1 0.89,2 2,2h10v-2H6V5z" + android:fillColor="#000000"/> +</vector> diff --git a/packages/SystemUI/res/layout/media_output_list_item.xml b/packages/SystemUI/res/layout/media_output_list_item.xml index ac8b7b5812bd..c98c3a0beb65 100644 --- a/packages/SystemUI/res/layout/media_output_list_item.xml +++ b/packages/SystemUI/res/layout/media_output_list_item.xml @@ -15,97 +15,124 @@ ~ limitations under the License. --> -<FrameLayout - android:id="@+id/device_container" +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/device_container" android:layout_width="match_parent" - android:layout_height="64dp"> - + android:layout_height="wrap_content" + android:orientation="vertical"> <FrameLayout - android:layout_width="36dp" - android:layout_height="36dp" - android:layout_gravity="center_vertical" - android:layout_marginStart="16dp"> - <ImageView - android:id="@+id/title_icon" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center"/> - </FrameLayout> + android:layout_width="match_parent" + android:layout_height="64dp"> - <TextView - android:id="@+id/title" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center_vertical" - android:layout_marginStart="68dp" - android:ellipsize="end" - android:maxLines="1" - android:textColor="?android:attr/textColorPrimary" - android:textSize="14sp"/> + <FrameLayout + android:layout_width="36dp" + android:layout_height="36dp" + android:layout_gravity="center_vertical" + android:layout_marginStart="16dp"> + <ImageView + android:id="@+id/title_icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center"/> + </FrameLayout> - <RelativeLayout - android:id="@+id/two_line_layout" - android:layout_width="wrap_content" - android:layout_height="48dp" - android:layout_marginStart="52dp" - android:layout_marginEnd="69dp" - android:layout_marginTop="10dp"> <TextView - android:id="@+id/two_line_title" + android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginStart="16dp" - android:layout_marginEnd="15dp" + android:layout_gravity="center_vertical" + android:layout_marginStart="68dp" android:ellipsize="end" android:maxLines="1" android:textColor="?android:attr/textColorPrimary" android:textSize="14sp"/> - <TextView - android:id="@+id/subtitle" + + <RelativeLayout + android:id="@+id/two_line_layout" android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginStart="16dp" - android:layout_marginEnd="15dp" - android:layout_marginBottom="7dp" - android:layout_alignParentBottom="true" - android:ellipsize="end" - android:maxLines="1" - android:textColor="?android:attr/textColorSecondary" - android:textSize="12sp" - android:fontFamily="roboto-regular" + android:layout_height="48dp" + android:layout_marginStart="52dp" + android:layout_marginEnd="69dp" + android:layout_marginTop="10dp"> + <TextView + android:id="@+id/two_line_title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="16dp" + android:layout_marginEnd="15dp" + android:ellipsize="end" + android:maxLines="1" + android:textColor="?android:attr/textColorPrimary" + android:textSize="14sp"/> + <TextView + android:id="@+id/subtitle" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="16dp" + android:layout_marginEnd="15dp" + android:layout_marginBottom="7dp" + android:layout_alignParentBottom="true" + android:ellipsize="end" + android:maxLines="1" + android:textColor="?android:attr/textColorSecondary" + android:textSize="12sp" + android:fontFamily="roboto-regular" + android:visibility="gone"/> + <SeekBar + android:id="@+id/volume_seekbar" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_alignParentBottom="true"/> + </RelativeLayout> + + <ProgressBar + android:id="@+id/volume_indeterminate_progress" + style="@*android:style/Widget.Material.ProgressBar.Horizontal" + android:layout_width="258dp" + android:layout_height="18dp" + android:layout_marginStart="68dp" + android:layout_marginTop="40dp" + android:indeterminate="true" + android:indeterminateOnly="true" android:visibility="gone"/> - <SeekBar - android:id="@+id/volume_seekbar" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_alignParentBottom="true"/> - </RelativeLayout> - <ProgressBar - android:id="@+id/volume_indeterminate_progress" - style="@*android:style/Widget.Material.ProgressBar.Horizontal" - android:layout_width="258dp" - android:layout_height="18dp" - android:layout_marginStart="68dp" - android:layout_marginTop="40dp" - android:indeterminate="true" - android:indeterminateOnly="true" - android:visibility="gone"/> + <View + android:id="@+id/end_divider" + android:layout_width="1dp" + android:layout_height="36dp" + android:layout_marginEnd="68dp" + android:layout_gravity="right|center_vertical" + android:background="?android:attr/listDivider" + android:visibility="gone"/> + + <ImageView + android:id="@+id/add_icon" + android:layout_width="24dp" + android:layout_height="24dp" + android:layout_gravity="right|center_vertical" + android:layout_marginEnd="24dp" + android:src="@drawable/ic_add" + android:tint="?android:attr/colorAccent" + android:visibility="gone"/> + + <CheckBox + android:id="@+id/check_box" + android:layout_width="24dp" + android:layout_height="24dp" + android:layout_gravity="right|center_vertical" + android:layout_marginEnd="24dp" + android:button="@drawable/ic_check_box" + android:visibility="gone"/> + </FrameLayout> <View - android:layout_width="1dp" - android:layout_height="36dp" - android:layout_marginEnd="68dp" - android:layout_gravity="right|center_vertical" + android:id="@+id/bottom_divider" + android:layout_width="match_parent" + android:layout_height="1dp" + android:layout_marginTop="12dp" + android:layout_marginBottom="12dp" + android:layout_gravity="bottom" android:background="?android:attr/listDivider" android:visibility="gone"/> - - <ImageView - android:id="@+id/end_icon" - android:layout_width="24dp" - android:layout_height="24dp" - android:layout_gravity="right|center_vertical" - android:layout_marginEnd="24dp" - android:visibility="gone"/> -</FrameLayout>
\ No newline at end of file +</LinearLayout>
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java index d1630ebe8dc8..d26f7ab6d78c 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java @@ -109,34 +109,45 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { super.onBind(device, topMargin, bottomMargin); final boolean currentlyConnected = isCurrentlyConnected(device); if (currentlyConnected) { - mConnectedItem = mFrameLayout; + mConnectedItem = mContainerLayout; + } + mBottomDivider.setVisibility(View.GONE); + mCheckBox.setVisibility(View.GONE); + if (currentlyConnected && mController.isActiveRemoteDevice(device)) { + // Init active device layout + mDivider.setVisibility(View.VISIBLE); + mDivider.setTransitionAlpha(1); + mAddIcon.setVisibility(View.VISIBLE); + mAddIcon.setTransitionAlpha(1); + mAddIcon.setOnClickListener(v -> onEndItemClick()); + } else { + // Init non-active device layout + mDivider.setVisibility(View.GONE); + mAddIcon.setVisibility(View.GONE); } if (mController.isTransferring()) { if (device.getState() == MediaDeviceState.STATE_CONNECTING && !mController.hasAdjustVolumeUserRestriction()) { - setTwoLineLayout(device, null /* title */, true /* bFocused */, - false /* showSeekBar*/, true /* showProgressBar */, - false /* showSubtitle */); + setTwoLineLayout(device, true /* bFocused */, false /* showSeekBar*/, + true /* showProgressBar */, false /* showSubtitle */); } else { setSingleLineLayout(getItemTitle(device), false /* bFocused */); } } else { // Set different layout for each device if (device.getState() == MediaDeviceState.STATE_CONNECTING_FAILED) { - setTwoLineLayout(device, null /* title */, false /* bFocused */, - false /* showSeekBar*/, false /* showProgressBar */, + setTwoLineLayout(device, false /* bFocused */, + false /* showSeekBar */, false /* showProgressBar */, true /* showSubtitle */); mSubTitleText.setText(R.string.media_output_dialog_connect_failed); - mFrameLayout.setOnClickListener(v -> onItemClick(v, device)); - } else if (!mController.hasAdjustVolumeUserRestriction() - && currentlyConnected) { - setTwoLineLayout(device, null /* title */, true /* bFocused */, - true /* showSeekBar*/, false /* showProgressBar */, - false /* showSubtitle */); + mContainerLayout.setOnClickListener(v -> onItemClick(v, device)); + } else if (!mController.hasAdjustVolumeUserRestriction() && currentlyConnected) { + setTwoLineLayout(device, true /* bFocused */, true /* showSeekBar */, + false /* showProgressBar */, false /* showSubtitle */); initSeekbar(device); } else { setSingleLineLayout(getItemTitle(device), false /* bFocused */); - mFrameLayout.setOnClickListener(v -> onItemClick(v, device)); + mContainerLayout.setOnClickListener(v -> onItemClick(v, device)); } } } @@ -145,13 +156,17 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { void onBind(int customizedItem, boolean topMargin, boolean bottomMargin) { super.onBind(customizedItem, topMargin, bottomMargin); if (customizedItem == CUSTOMIZED_ITEM_PAIR_NEW) { + mCheckBox.setVisibility(View.GONE); + mDivider.setVisibility(View.GONE); + mAddIcon.setVisibility(View.GONE); + mBottomDivider.setVisibility(View.GONE); setSingleLineLayout(mContext.getText(R.string.media_output_dialog_pairing_new), false /* bFocused */); final Drawable d = mContext.getDrawable(R.drawable.ic_add); d.setColorFilter(new PorterDuffColorFilter( Utils.getColorAccentDefaultColor(mContext), PorterDuff.Mode.SRC_IN)); mTitleIcon.setImageDrawable(d); - mFrameLayout.setOnClickListener(v -> onItemClick(CUSTOMIZED_ITEM_PAIR_NEW)); + mContainerLayout.setOnClickListener(v -> onItemClick(CUSTOMIZED_ITEM_PAIR_NEW)); } } @@ -173,5 +188,9 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { mController.launchBluetoothPairing(); } } + + private void onEndItemClick() { + mController.launchMediaOutputGroupDialog(); + } } } diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java index 2d3e77db1ea3..536b7598ce22 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java @@ -24,8 +24,9 @@ import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.FrameLayout; +import android.widget.CheckBox; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.SeekBar; @@ -44,19 +45,17 @@ import com.android.systemui.R; public abstract class MediaOutputBaseAdapter extends RecyclerView.Adapter<MediaOutputBaseAdapter.MediaDeviceBaseViewHolder> { - private static final String FONT_SELECTED_TITLE = "sans-serif-medium"; - private static final String FONT_TITLE = "sans-serif"; - static final int CUSTOMIZED_ITEM_PAIR_NEW = 1; + static final int CUSTOMIZED_ITEM_GROUP = 2; final MediaOutputController mController; - private boolean mIsDragging; private int mMargin; private boolean mIsAnimating; Context mContext; View mHolderView; + boolean mIsDragging; public MediaOutputBaseAdapter(MediaOutputController controller) { mController = controller; @@ -99,27 +98,33 @@ public abstract class MediaOutputBaseAdapter extends private static final int ANIM_DURATION = 200; - final FrameLayout mFrameLayout; + final LinearLayout mContainerLayout; final TextView mTitleText; final TextView mTwoLineTitleText; final TextView mSubTitleText; final ImageView mTitleIcon; - final ImageView mEndIcon; + final ImageView mAddIcon; final ProgressBar mProgressBar; final SeekBar mSeekBar; final RelativeLayout mTwoLineLayout; + final View mDivider; + final View mBottomDivider; + final CheckBox mCheckBox; MediaDeviceBaseViewHolder(View view) { super(view); - mFrameLayout = view.requireViewById(R.id.device_container); + mContainerLayout = view.requireViewById(R.id.device_container); mTitleText = view.requireViewById(R.id.title); mSubTitleText = view.requireViewById(R.id.subtitle); mTwoLineLayout = view.requireViewById(R.id.two_line_layout); mTwoLineTitleText = view.requireViewById(R.id.two_line_title); mTitleIcon = view.requireViewById(R.id.title_icon); - mEndIcon = view.requireViewById(R.id.end_icon); mProgressBar = view.requireViewById(R.id.volume_indeterminate_progress); mSeekBar = view.requireViewById(R.id.volume_seekbar); + mDivider = view.requireViewById(R.id.end_divider); + mBottomDivider = view.requireViewById(R.id.bottom_divider); + mAddIcon = view.requireViewById(R.id.add_icon); + mCheckBox = view.requireViewById(R.id.check_box); } void onBind(MediaDevice device, boolean topMargin, boolean bottomMargin) { @@ -132,11 +137,11 @@ public abstract class MediaOutputBaseAdapter extends } private void setMargin(boolean topMargin, boolean bottomMargin) { - ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mFrameLayout + ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mContainerLayout .getLayoutParams(); params.topMargin = topMargin ? mMargin : 0; params.bottomMargin = bottomMargin ? mMargin : 0; - mFrameLayout.setLayoutParams(params); + mContainerLayout.setLayoutParams(params); } void setSingleLineLayout(CharSequence title, boolean bFocused) { @@ -146,13 +151,26 @@ public abstract class MediaOutputBaseAdapter extends mTitleText.setTranslationY(0); mTitleText.setText(title); if (bFocused) { - mTitleText.setTypeface(Typeface.create(FONT_SELECTED_TITLE, Typeface.NORMAL)); + mTitleText.setTypeface(Typeface.create(mContext.getString( + com.android.internal.R.string.config_headlineFontFamilyMedium), + Typeface.NORMAL)); } else { - mTitleText.setTypeface(Typeface.create(FONT_TITLE, Typeface.NORMAL)); + mTitleText.setTypeface(Typeface.create(mContext.getString( + com.android.internal.R.string.config_headlineFontFamily), Typeface.NORMAL)); } } - void setTwoLineLayout(MediaDevice device, CharSequence title, boolean bFocused, + void setTwoLineLayout(MediaDevice device, boolean bFocused, boolean showSeekBar, + boolean showProgressBar, boolean showSubtitle) { + setTwoLineLayout(device, null, bFocused, showSeekBar, showProgressBar, showSubtitle); + } + + void setTwoLineLayout(CharSequence title, boolean bFocused, boolean showSeekBar, + boolean showProgressBar, boolean showSubtitle) { + setTwoLineLayout(null, title, bFocused, showSeekBar, showProgressBar, showSubtitle); + } + + private void setTwoLineLayout(MediaDevice device, CharSequence title, boolean bFocused, boolean showSeekBar, boolean showProgressBar, boolean showSubtitle) { mTitleText.setVisibility(View.GONE); mTwoLineLayout.setVisibility(View.VISIBLE); @@ -168,18 +186,21 @@ public abstract class MediaOutputBaseAdapter extends } if (bFocused) { - mTwoLineTitleText.setTypeface(Typeface.create(FONT_SELECTED_TITLE, + mTwoLineTitleText.setTypeface(Typeface.create(mContext.getString( + com.android.internal.R.string.config_headlineFontFamilyMedium), Typeface.NORMAL)); } else { - mTwoLineTitleText.setTypeface(Typeface.create(FONT_TITLE, Typeface.NORMAL)); + mTwoLineTitleText.setTypeface(Typeface.create(mContext.getString( + com.android.internal.R.string.config_headlineFontFamily), Typeface.NORMAL)); } } void initSeekbar(MediaDevice device) { mSeekBar.setMax(device.getMaxVolume()); mSeekBar.setMin(0); - if (mSeekBar.getProgress() != device.getCurrentVolume()) { - mSeekBar.setProgress(device.getCurrentVolume()); + final int currentVolume = device.getCurrentVolume(); + if (mSeekBar.getProgress() != currentVolume) { + mSeekBar.setProgress(currentVolume); } mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override @@ -213,7 +234,9 @@ public abstract class MediaOutputBaseAdapter extends } mIsAnimating = true; // Animation for title text - toTitleText.setTypeface(Typeface.create(FONT_SELECTED_TITLE, Typeface.NORMAL)); + toTitleText.setTypeface(Typeface.create(mContext.getString( + com.android.internal.R.string.config_headlineFontFamilyMedium), + Typeface.NORMAL)); toTitleText.animate() .setDuration(ANIM_DURATION) .translationY(-delta) @@ -234,7 +257,9 @@ public abstract class MediaOutputBaseAdapter extends public void onAnimationEnd(Animator animation) { final TextView fromTitleText = from.requireViewById( R.id.two_line_title); - fromTitleText.setTypeface(Typeface.create(FONT_TITLE, Typeface.NORMAL)); + fromTitleText.setTypeface(Typeface.create(mContext.getString( + com.android.internal.R.string.config_headlineFontFamily), + Typeface.NORMAL)); fromTitleText.animate() .setDuration(ANIM_DURATION) .translationY(delta) diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java index 2faf56a5022c..dd9a808fb35b 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java @@ -119,6 +119,8 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements // Init device list mDevicesRecyclerView.setLayoutManager(mLayoutManager); mDevicesRecyclerView.setAdapter(mAdapter); + // Init header icon + mHeaderIcon.setOnClickListener(v -> onHeaderIconClick()); // Init bottom buttons mDoneButton.setOnClickListener(v -> dismiss()); mStopButton.setOnClickListener(v -> { @@ -218,4 +220,7 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements dismiss(); } } + + void onHeaderIconClick() { + } } diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java index b1f1bda25961..b9fa87252125 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java @@ -71,6 +71,8 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback{ private final MediaSessionManager mMediaSessionManager; private final ShadeController mShadeController; private final ActivityStarter mActivityStarter; + private final List<MediaDevice> mGroupMediaDevices = new CopyOnWriteArrayList<>(); + private final boolean mAboveStatusbar; @VisibleForTesting final List<MediaDevice> mMediaDevices = new CopyOnWriteArrayList<>(); @@ -82,13 +84,14 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback{ @Inject public MediaOutputController(@NonNull Context context, String packageName, - MediaSessionManager mediaSessionManager, LocalBluetoothManager + boolean aboveStatusbar, MediaSessionManager mediaSessionManager, LocalBluetoothManager lbm, ShadeController shadeController, ActivityStarter starter) { mContext = context; mPackageName = packageName; mMediaSessionManager = mediaSessionManager; mShadeController = shadeController; mActivityStarter = starter; + mAboveStatusbar = aboveStatusbar; InfoMediaManager imm = new InfoMediaManager(mContext, packageName, null, lbm); mLocalMediaManager = new LocalMediaManager(mContext, lbm, imm, packageName); } @@ -271,6 +274,42 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback{ mMediaDevices.addAll(targetMediaDevices); } + List<MediaDevice> getGroupMediaDevices() { + final List<MediaDevice> selectedDevices = getSelectedMediaDevice(); + final List<MediaDevice> selectableDevices = getSelectableMediaDevice(); + if (mGroupMediaDevices.isEmpty()) { + mGroupMediaDevices.addAll(selectedDevices); + mGroupMediaDevices.addAll(selectableDevices); + return mGroupMediaDevices; + } + // To keep the same list order + final Collection<MediaDevice> sourceDevices = new ArrayList<>(); + final Collection<MediaDevice> targetMediaDevices = new ArrayList<>(); + sourceDevices.addAll(selectedDevices); + sourceDevices.addAll(selectableDevices); + for (MediaDevice originalDevice : mGroupMediaDevices) { + for (MediaDevice newDevice : sourceDevices) { + if (TextUtils.equals(originalDevice.getId(), newDevice.getId())) { + targetMediaDevices.add(newDevice); + sourceDevices.remove(newDevice); + break; + } + } + } + // Add new devices at the end of list if necessary + if (!sourceDevices.isEmpty()) { + targetMediaDevices.addAll(sourceDevices); + } + mGroupMediaDevices.clear(); + mGroupMediaDevices.addAll(targetMediaDevices); + + return mGroupMediaDevices; + } + + void resetGroupMediaDevices() { + mGroupMediaDevices.clear(); + } + void connectDevice(MediaDevice device) { ThreadUtils.postOnBackgroundThread(() -> { mLocalMediaManager.connectDevice(device); @@ -309,15 +348,6 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback{ return mLocalMediaManager.getDeselectableMediaDevice(); } - boolean isDeviceIncluded(Collection<MediaDevice> deviceCollection, MediaDevice targetDevice) { - for (MediaDevice device : deviceCollection) { - if (TextUtils.equals(device.getId(), targetDevice.getId())) { - return true; - } - } - return false; - } - void adjustSessionVolume(String sessionId, int volume) { mLocalMediaManager.adjustSessionVolume(sessionId, volume); } @@ -407,6 +437,16 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback{ mActivityStarter.dismissKeyguardThenExecute(postKeyguardAction, null, true); } + void launchMediaOutputDialog() { + mCallback.dismissDialog(); + new MediaOutputDialog(mContext, mAboveStatusbar, this); + } + + void launchMediaOutputGroupDialog() { + mCallback.dismissDialog(); + new MediaOutputGroupDialog(mContext, mAboveStatusbar, this); + } + boolean isActiveRemoteDevice(@NonNull MediaDevice device) { final List<String> features = device.getFeatures(); return (features.contains(MediaRoute2Info.FEATURE_REMOTE_PLAYBACK) diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt index 4cdca4cbcf1e..e912b7d1b08f 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt @@ -40,9 +40,8 @@ class MediaOutputDialogFactory @Inject constructor( /** Creates a [MediaOutputDialog] for the given package. */ fun create(packageName: String, aboveStatusBar: Boolean) { mediaOutputDialog?.dismiss() - - mediaOutputDialog = MediaOutputController(context, packageName, mediaSessionManager, lbm, - shadeController, starter).run { + mediaOutputDialog = MediaOutputController(context, packageName, aboveStatusBar, + mediaSessionManager, lbm, shadeController, starter).run { MediaOutputDialog(context, aboveStatusBar, this) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java index 2d460aa0c9c1..521888658d68 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java @@ -25,7 +25,7 @@ import static org.mockito.Mockito.when; import android.graphics.drawable.Icon; import android.testing.AndroidTestingRunner; import android.view.View; -import android.widget.FrameLayout; +import android.widget.LinearLayout; import androidx.core.graphics.drawable.IconCompat; import androidx.test.filters.SmallTest; @@ -66,7 +66,7 @@ public class MediaOutputAdapterTest extends SysuiTestCase { public void setUp() { mMediaOutputAdapter = new MediaOutputAdapter(mMediaOutputController); mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter - .onCreateViewHolder(new FrameLayout(mContext), 0); + .onCreateViewHolder(new LinearLayout(mContext), 0); when(mMediaOutputController.getMediaDevices()).thenReturn(mMediaDevices); when(mMediaOutputController.hasAdjustVolumeUserRestriction()).thenReturn(false); @@ -75,6 +75,7 @@ public class MediaOutputAdapterTest extends SysuiTestCase { when(mMediaOutputController.getDeviceIconCompat(mMediaDevice1)).thenReturn(mIconCompat); when(mMediaOutputController.getDeviceIconCompat(mMediaDevice2)).thenReturn(mIconCompat); when(mMediaOutputController.getCurrentConnectedMediaDevice()).thenReturn(mMediaDevice1); + when(mMediaOutputController.isActiveRemoteDevice(mMediaDevice1)).thenReturn(true); when(mIconCompat.toIcon(mContext)).thenReturn(mIcon); when(mMediaDevice1.getName()).thenReturn(TEST_DEVICE_NAME_1); when(mMediaDevice1.getId()).thenReturn(TEST_DEVICE_ID_1); @@ -107,6 +108,11 @@ public class MediaOutputAdapterTest extends SysuiTestCase { assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.VISIBLE); assertThat(mViewHolder.mTwoLineLayout.getVisibility()).isEqualTo(View.GONE); + assertThat(mViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE); + assertThat(mViewHolder.mDivider.getVisibility()).isEqualTo(View.GONE); + assertThat(mViewHolder.mAddIcon.getVisibility()).isEqualTo(View.GONE); + assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.GONE); + assertThat(mViewHolder.mBottomDivider.getVisibility()).isEqualTo(View.GONE); assertThat(mViewHolder.mTitleText.getText()).isEqualTo(mContext.getText( R.string.media_output_dialog_pairing_new)); } @@ -118,19 +124,41 @@ public class MediaOutputAdapterTest extends SysuiTestCase { assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.GONE); assertThat(mViewHolder.mSubTitleText.getVisibility()).isEqualTo(View.GONE); assertThat(mViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE); + assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.GONE); + assertThat(mViewHolder.mBottomDivider.getVisibility()).isEqualTo(View.GONE); assertThat(mViewHolder.mTwoLineTitleText.getVisibility()).isEqualTo(View.VISIBLE); assertThat(mViewHolder.mSeekBar.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mViewHolder.mDivider.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mViewHolder.mAddIcon.getVisibility()).isEqualTo(View.VISIBLE); assertThat(mViewHolder.mTwoLineTitleText.getText()).isEqualTo(TEST_DEVICE_NAME_1); } @Test + public void onBindViewHolder_bindNonActiveConnectedDevice_verifyView() { + mMediaOutputAdapter.onBindViewHolder(mViewHolder, 1); + + assertThat(mViewHolder.mDivider.getVisibility()).isEqualTo(View.GONE); + assertThat(mViewHolder.mAddIcon.getVisibility()).isEqualTo(View.GONE); + assertThat(mViewHolder.mTwoLineLayout.getVisibility()).isEqualTo(View.GONE); + assertThat(mViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE); + assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.GONE); + assertThat(mViewHolder.mBottomDivider.getVisibility()).isEqualTo(View.GONE); + assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mViewHolder.mTitleText.getText().toString()).isEqualTo(TEST_DEVICE_NAME_2); + } + + @Test public void onBindViewHolder_bindDisconnectedBluetoothDevice_verifyView() { when(mMediaDevice2.getDeviceType()).thenReturn( MediaDevice.MediaDeviceType.TYPE_BLUETOOTH_DEVICE); when(mMediaDevice2.isConnected()).thenReturn(false); mMediaOutputAdapter.onBindViewHolder(mViewHolder, 1); + assertThat(mViewHolder.mDivider.getVisibility()).isEqualTo(View.GONE); + assertThat(mViewHolder.mAddIcon.getVisibility()).isEqualTo(View.GONE); assertThat(mViewHolder.mTwoLineLayout.getVisibility()).isEqualTo(View.GONE); + assertThat(mViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE); + assertThat(mViewHolder.mBottomDivider.getVisibility()).isEqualTo(View.GONE); assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.VISIBLE); assertThat(mViewHolder.mTitleText.getText().toString()).isEqualTo( mContext.getString(R.string.media_output_dialog_disconnected, TEST_DEVICE_NAME_2)); @@ -142,9 +170,13 @@ public class MediaOutputAdapterTest extends SysuiTestCase { LocalMediaManager.MediaDeviceState.STATE_CONNECTING_FAILED); mMediaOutputAdapter.onBindViewHolder(mViewHolder, 1); + assertThat(mViewHolder.mDivider.getVisibility()).isEqualTo(View.GONE); + assertThat(mViewHolder.mAddIcon.getVisibility()).isEqualTo(View.GONE); assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.GONE); assertThat(mViewHolder.mSeekBar.getVisibility()).isEqualTo(View.GONE); assertThat(mViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE); + assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.GONE); + assertThat(mViewHolder.mBottomDivider.getVisibility()).isEqualTo(View.GONE); assertThat(mViewHolder.mSubTitleText.getVisibility()).isEqualTo(View.VISIBLE); assertThat(mViewHolder.mTwoLineTitleText.getVisibility()).isEqualTo(View.VISIBLE); assertThat(mViewHolder.mSubTitleText.getText()).isEqualTo(mContext.getText( @@ -162,7 +194,11 @@ public class MediaOutputAdapterTest extends SysuiTestCase { assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.GONE); assertThat(mViewHolder.mSeekBar.getVisibility()).isEqualTo(View.GONE); assertThat(mViewHolder.mSubTitleText.getVisibility()).isEqualTo(View.GONE); + assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.GONE); + assertThat(mViewHolder.mBottomDivider.getVisibility()).isEqualTo(View.GONE); assertThat(mViewHolder.mProgressBar.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mViewHolder.mDivider.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mViewHolder.mAddIcon.getVisibility()).isEqualTo(View.VISIBLE); assertThat(mViewHolder.mTwoLineTitleText.getVisibility()).isEqualTo(View.VISIBLE); assertThat(mViewHolder.mTwoLineTitleText.getText()).isEqualTo(TEST_DEVICE_NAME_1); } @@ -174,8 +210,13 @@ public class MediaOutputAdapterTest extends SysuiTestCase { LocalMediaManager.MediaDeviceState.STATE_CONNECTING); mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0); - assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.VISIBLE); assertThat(mViewHolder.mTwoLineLayout.getVisibility()).isEqualTo(View.GONE); + assertThat(mViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE); + assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.GONE); + assertThat(mViewHolder.mBottomDivider.getVisibility()).isEqualTo(View.GONE); + assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mViewHolder.mDivider.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mViewHolder.mAddIcon.getVisibility()).isEqualTo(View.VISIBLE); assertThat(mViewHolder.mTitleText.getText()).isEqualTo(TEST_DEVICE_NAME_1); } @@ -183,7 +224,7 @@ public class MediaOutputAdapterTest extends SysuiTestCase { public void onItemClick_clickPairNew_verifyLaunchBluetoothPairing() { when(mMediaOutputController.isZeroMode()).thenReturn(true); mMediaOutputAdapter.onBindViewHolder(mViewHolder, 2); - mViewHolder.mFrameLayout.performClick(); + mViewHolder.mContainerLayout.performClick(); verify(mMediaOutputController).launchBluetoothPairing(); } @@ -194,7 +235,7 @@ public class MediaOutputAdapterTest extends SysuiTestCase { LocalMediaManager.MediaDeviceState.STATE_DISCONNECTED); mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0); mMediaOutputAdapter.onBindViewHolder(mViewHolder, 1); - mViewHolder.mFrameLayout.performClick(); + mViewHolder.mContainerLayout.performClick(); verify(mMediaOutputController).connectDevice(mMediaDevice2); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java index 27b5b7fda684..4639dcbb1685 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java @@ -68,7 +68,7 @@ public class MediaOutputBaseDialogTest extends SysuiTestCase { @Before public void setUp() { - mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE, + mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE, false, mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter); mMediaOutputBaseDialogImpl = new MediaOutputBaseDialogImpl(mContext, mMediaOutputController); diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java index 0dcdecfdaadb..0576667484df 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java @@ -34,6 +34,7 @@ import android.media.RoutingSessionInfo; import android.media.session.MediaController; import android.media.session.MediaSessionManager; import android.testing.AndroidTestingRunner; +import android.text.TextUtils; import androidx.test.filters.SmallTest; @@ -60,6 +61,9 @@ public class MediaOutputControllerTest extends SysuiTestCase { private static final String TEST_PACKAGE_NAME = "com.test.package.name"; 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_3_ID = "test_device_3_id"; + private static final String TEST_DEVICE_4_ID = "test_device_4_id"; + private static final String TEST_DEVICE_5_ID = "test_device_5_id"; private static final String TEST_ARTIST = "test_artist"; private static final String TEST_SONG = "test_song"; private static final String TEST_SESSION_ID = "test_session_id"; @@ -96,7 +100,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { MediaSessionManager.class); when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn( mCachedBluetoothDeviceManager); - mMediaOutputController = new MediaOutputController(mSpyContext, TEST_PACKAGE_NAME, + mMediaOutputController = new MediaOutputController(mSpyContext, TEST_PACKAGE_NAME, false, mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter); mLocalMediaManager = spy(mMediaOutputController.mLocalMediaManager); mMediaOutputController.mLocalMediaManager = mLocalMediaManager; @@ -139,8 +143,8 @@ public class MediaOutputControllerTest extends SysuiTestCase { @Test public void start_withoutPackageName_verifyMediaControllerInit() { - mMediaOutputController = new MediaOutputController(mSpyContext, null, mMediaSessionManager, - mLocalBluetoothManager, mShadeController, mStarter); + mMediaOutputController = new MediaOutputController(mSpyContext, null, false, + mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter); mMediaOutputController.start(mCb); @@ -159,8 +163,8 @@ public class MediaOutputControllerTest extends SysuiTestCase { @Test public void stop_withoutPackageName_verifyMediaControllerDeinit() { - mMediaOutputController = new MediaOutputController(mSpyContext, null, mMediaSessionManager, - mLocalBluetoothManager, mShadeController, mStarter); + mMediaOutputController = new MediaOutputController(mSpyContext, null, false, + mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter); mMediaOutputController.start(mCb); mMediaOutputController.stop(); @@ -345,4 +349,78 @@ public class MediaOutputControllerTest extends SysuiTestCase { assertThat(mMediaOutputController.isZeroMode()).isFalse(); } + + @Test + public void getGroupMediaDevices_differentDeviceOrder_showingSameOrder() { + final MediaDevice selectedMediaDevice1 = mock(MediaDevice.class); + final MediaDevice selectedMediaDevice2 = mock(MediaDevice.class); + final MediaDevice selectableMediaDevice1 = mock(MediaDevice.class); + final MediaDevice selectableMediaDevice2 = mock(MediaDevice.class); + final List<MediaDevice> selectedMediaDevices = new ArrayList<>(); + final List<MediaDevice> selectableMediaDevices = new ArrayList<>(); + when(selectedMediaDevice1.getId()).thenReturn(TEST_DEVICE_1_ID); + when(selectedMediaDevice2.getId()).thenReturn(TEST_DEVICE_2_ID); + when(selectableMediaDevice1.getId()).thenReturn(TEST_DEVICE_3_ID); + when(selectableMediaDevice2.getId()).thenReturn(TEST_DEVICE_4_ID); + selectedMediaDevices.add(selectedMediaDevice1); + selectedMediaDevices.add(selectedMediaDevice2); + selectableMediaDevices.add(selectableMediaDevice1); + selectableMediaDevices.add(selectableMediaDevice2); + doReturn(selectedMediaDevices).when(mLocalMediaManager).getSelectedMediaDevice(); + doReturn(selectableMediaDevices).when(mLocalMediaManager).getSelectableMediaDevice(); + final List<MediaDevice> groupMediaDevices = mMediaOutputController.getGroupMediaDevices(); + // Reset order + selectedMediaDevices.clear(); + selectedMediaDevices.add(selectedMediaDevice2); + selectedMediaDevices.add(selectedMediaDevice1); + selectableMediaDevices.clear(); + selectableMediaDevices.add(selectableMediaDevice2); + selectableMediaDevices.add(selectableMediaDevice1); + final List<MediaDevice> newDevices = mMediaOutputController.getGroupMediaDevices(); + + assertThat(newDevices.size()).isEqualTo(groupMediaDevices.size()); + for (int i = 0; i < groupMediaDevices.size(); i++) { + assertThat(TextUtils.equals(groupMediaDevices.get(i).getId(), + newDevices.get(i).getId())).isTrue(); + } + } + + @Test + public void getGroupMediaDevices_newDevice_verifyDeviceOrder() { + final MediaDevice selectedMediaDevice1 = mock(MediaDevice.class); + final MediaDevice selectedMediaDevice2 = mock(MediaDevice.class); + final MediaDevice selectableMediaDevice1 = mock(MediaDevice.class); + final MediaDevice selectableMediaDevice2 = mock(MediaDevice.class); + final MediaDevice selectableMediaDevice3 = mock(MediaDevice.class); + final List<MediaDevice> selectedMediaDevices = new ArrayList<>(); + final List<MediaDevice> selectableMediaDevices = new ArrayList<>(); + when(selectedMediaDevice1.getId()).thenReturn(TEST_DEVICE_1_ID); + when(selectedMediaDevice2.getId()).thenReturn(TEST_DEVICE_2_ID); + when(selectableMediaDevice1.getId()).thenReturn(TEST_DEVICE_3_ID); + when(selectableMediaDevice2.getId()).thenReturn(TEST_DEVICE_4_ID); + when(selectableMediaDevice3.getId()).thenReturn(TEST_DEVICE_5_ID); + selectedMediaDevices.add(selectedMediaDevice1); + selectedMediaDevices.add(selectedMediaDevice2); + selectableMediaDevices.add(selectableMediaDevice1); + selectableMediaDevices.add(selectableMediaDevice2); + doReturn(selectedMediaDevices).when(mLocalMediaManager).getSelectedMediaDevice(); + doReturn(selectableMediaDevices).when(mLocalMediaManager).getSelectableMediaDevice(); + final List<MediaDevice> groupMediaDevices = mMediaOutputController.getGroupMediaDevices(); + // Reset order + selectedMediaDevices.clear(); + selectedMediaDevices.add(selectedMediaDevice2); + selectedMediaDevices.add(selectedMediaDevice1); + selectableMediaDevices.clear(); + selectableMediaDevices.add(selectableMediaDevice3); + selectableMediaDevices.add(selectableMediaDevice2); + selectableMediaDevices.add(selectableMediaDevice1); + final List<MediaDevice> newDevices = mMediaOutputController.getGroupMediaDevices(); + + assertThat(newDevices.size()).isEqualTo(5); + for (int i = 0; i < groupMediaDevices.size(); i++) { + assertThat(TextUtils.equals(groupMediaDevices.get(i).getId(), + newDevices.get(i).getId())).isTrue(); + } + assertThat(newDevices.get(4).getId()).isEqualTo(TEST_DEVICE_5_ID); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java index ca328fbe44fb..4b00d9eefd9c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java @@ -64,7 +64,7 @@ public class MediaOutputDialogTest extends SysuiTestCase { @Before public void setUp() { - mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE, + mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE, false, mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter); mMediaOutputController.mLocalMediaManager = mLocalMediaManager; mMediaOutputDialog = new MediaOutputDialog(mContext, false, mMediaOutputController); |