Enhancement for group operation in output switcher
-Add new group components in xml layout and assets
-Adjust view objects in adapter for new layout
-Add aboveStatusbar in MediaOutputControllter to keep the dialog style
when switching
-Add getGroupMediaDevices() in MediaOutputController to provide available
device list for group operation
-Update test cases
Bug: 155822415
Test: atest MediaOutputAdapterTest MediaOutputControllerTest MediaOutputBaseDialogTest MediaOutputDialogTest
Merged-In: If74bf2efb89a8ece61f4e0cf13e4dcfa30cb0a8a
Change-Id: If74bf2efb89a8ece61f4e0cf13e4dcfa30cb0a8a
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 0000000..a8d1a65
--- /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 0000000..43cae69
--- /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 0000000..f6f453a
--- /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 0000000..ae0d562
--- /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 ac8b7b5..c98c3a0 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"
- 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"/>
+ <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: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"/>
+
+ <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 d1630eb..d26f7ab 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 @@
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 @@
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 @@
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 2d3e77d..536b759 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.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 @@
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 @@
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 @@
}
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 @@
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 @@
}
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 @@
}
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 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 2faf56a..dd9a808 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 @@
// 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 @@
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 b1f1bda..b9fa872 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 @@
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 @@
@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 @@
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 @@
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 @@
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 4cdca4c..e912b7d 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 @@
/** 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 2d460aa..5218886 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 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 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 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 @@
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 27b5b7f..4639dcb 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 @@
@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 0dcdecf..0576667484d 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.session.MediaController;
import android.media.session.MediaSessionManager;
import android.testing.AndroidTestingRunner;
+import android.text.TextUtils;
import androidx.test.filters.SmallTest;
@@ -60,6 +61,9 @@
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 @@
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 @@
@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 @@
@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 @@
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 ca328fb..4b00d9e 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 @@
@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);