Merge changes I72eaf3f2,Ibb3c8d9d into tm-dev
* changes:
[Media] Allow output switcher chip to handle larger font sizes without cutting off the test.
[Media Recs] Hide the title / subtitle views if none of the albums have titles / subtitles so that the album art is centered better.
diff --git a/packages/SystemUI/res/layout/media_session_view.xml b/packages/SystemUI/res/layout/media_session_view.xml
index 7962e22..534c80d 100644
--- a/packages/SystemUI/res/layout/media_session_view.xml
+++ b/packages/SystemUI/res/layout/media_session_view.xml
@@ -80,7 +80,7 @@
android:background="@drawable/qs_media_light_source"
android:forceHasOverlappingRendering="false"
android:layout_width="wrap_content"
- android:layout_height="48dp"
+ android:layout_height="@dimen/min_clickable_item_size"
android:layout_marginStart="@dimen/qs_center_guideline_padding"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
@@ -92,8 +92,9 @@
<LinearLayout
android:id="@+id/media_seamless_button"
android:layout_width="wrap_content"
- android:layout_height="@dimen/qs_seamless_height"
+ android:layout_height="wrap_content"
android:minHeight="@dimen/qs_seamless_height"
+ android:maxHeight="@dimen/min_clickable_item_size"
android:theme="@style/MediaPlayer.SolidButton"
android:background="@drawable/qs_media_seamless_background"
android:orientation="horizontal"
diff --git a/packages/SystemUI/res/layout/media_smartspace_recommendations.xml b/packages/SystemUI/res/layout/media_smartspace_recommendations.xml
index 659a578..79ba7ead 100644
--- a/packages/SystemUI/res/layout/media_smartspace_recommendations.xml
+++ b/packages/SystemUI/res/layout/media_smartspace_recommendations.xml
@@ -16,6 +16,8 @@
-->
<!-- Layout for media recommendations inside QSPanel carousel -->
+<!-- See media_recommendation_expanded.xml and media_recommendation_collapsed.xml for the
+ constraints. -->
<com.android.systemui.util.animation.TransitionLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
@@ -46,14 +48,6 @@
<FrameLayout
android:id="@+id/media_cover1_container"
style="@style/MediaPlayer.Recommendation.AlbumContainer"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toTopOf="@+id/media_title1"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toStartOf="@id/media_cover2_container"
- android:layout_marginEnd="@dimen/qs_media_rec_album_side_margin"
- app:layout_constraintHorizontal_chainStyle="packed"
- app:layout_constraintHorizontal_bias="1.0"
- app:layout_constraintVertical_bias="0.5"
>
<ImageView
android:id="@+id/media_cover1"
@@ -71,31 +65,16 @@
<TextView
android:id="@+id/media_title1"
style="@style/MediaPlayer.Recommendation.Text.Title"
- app:layout_constraintStart_toStartOf="@+id/media_cover1_container"
- app:layout_constraintEnd_toEndOf="@+id/media_cover1_container"
- app:layout_constraintTop_toBottomOf="@+id/media_cover1_container"
- app:layout_constraintBottom_toTopOf="@+id/media_subtitle1"
/>
<TextView
android:id="@+id/media_subtitle1"
style="@style/MediaPlayer.Recommendation.Text.Subtitle"
- app:layout_constraintStart_toStartOf="@+id/media_cover1_container"
- app:layout_constraintEnd_toEndOf="@+id/media_cover1_container"
- app:layout_constraintTop_toBottomOf="@+id/media_title1"
- app:layout_constraintBottom_toBottomOf="parent"
- android:layout_marginBottom="@dimen/qs_media_padding"
/>
<FrameLayout
android:id="@+id/media_cover2_container"
style="@style/MediaPlayer.Recommendation.AlbumContainer"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toTopOf="@id/media_title2"
- app:layout_constraintStart_toEndOf="@id/media_cover1_container"
- app:layout_constraintEnd_toStartOf="@id/media_cover3_container"
- android:layout_marginEnd="@dimen/qs_media_rec_album_side_margin"
- app:layout_constraintVertical_bias="0.5"
>
<ImageView
android:id="@+id/media_cover2"
@@ -111,31 +90,16 @@
<TextView
android:id="@+id/media_title2"
style="@style/MediaPlayer.Recommendation.Text.Title"
- app:layout_constraintStart_toStartOf="@+id/media_cover2_container"
- app:layout_constraintEnd_toEndOf="@+id/media_cover2_container"
- app:layout_constraintTop_toBottomOf="@+id/media_cover2_container"
- app:layout_constraintBottom_toTopOf="@+id/media_subtitle2"
/>
<TextView
android:id="@+id/media_subtitle2"
style="@style/MediaPlayer.Recommendation.Text.Subtitle"
- app:layout_constraintStart_toStartOf="@+id/media_cover2_container"
- app:layout_constraintEnd_toEndOf="@+id/media_cover2_container"
- app:layout_constraintTop_toBottomOf="@+id/media_title2"
- app:layout_constraintBottom_toBottomOf="parent"
- android:layout_marginBottom="@dimen/qs_media_padding"
/>
<FrameLayout
android:id="@+id/media_cover3_container"
style="@style/MediaPlayer.Recommendation.AlbumContainer"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toTopOf="@id/media_title3"
- app:layout_constraintStart_toEndOf="@id/media_cover2_container"
- app:layout_constraintEnd_toEndOf="parent"
- android:layout_marginEnd="@dimen/qs_media_padding"
- app:layout_constraintVertical_bias="0.5"
>
<ImageView
android:id="@+id/media_cover3"
@@ -151,20 +115,11 @@
<TextView
android:id="@+id/media_title3"
style="@style/MediaPlayer.Recommendation.Text.Title"
- app:layout_constraintStart_toStartOf="@+id/media_cover3_container"
- app:layout_constraintEnd_toEndOf="@+id/media_cover3_container"
- app:layout_constraintTop_toBottomOf="@+id/media_cover3_container"
- app:layout_constraintBottom_toTopOf="@+id/media_subtitle3"
/>
<TextView
android:id="@+id/media_subtitle3"
style="@style/MediaPlayer.Recommendation.Text.Subtitle"
- app:layout_constraintStart_toStartOf="@+id/media_cover3_container"
- app:layout_constraintEnd_toEndOf="@+id/media_cover3_container"
- app:layout_constraintTop_toBottomOf="@+id/media_title3"
- app:layout_constraintBottom_toBottomOf="parent"
- android:layout_marginBottom="@dimen/qs_media_padding"
/>
<include
diff --git a/packages/SystemUI/res/xml/media_recommendation_collapsed.xml b/packages/SystemUI/res/xml/media_recommendation_collapsed.xml
index a6113473..b7d4b3a 100644
--- a/packages/SystemUI/res/xml/media_recommendation_collapsed.xml
+++ b/packages/SystemUI/res/xml/media_recommendation_collapsed.xml
@@ -25,8 +25,10 @@
/>
<!-- Only the constraintBottom and marginBottom are different. The rest of the constraints are
- the same as the constraints in media_smartspace_recommendations. But due to how
- ConstraintSets work, all the constraints need to be in the same place.
+ the same as the constraints in media_recommendations_expanded.xml. But, due to how
+ ConstraintSets work, all the constraints need to be in the same place. So, the shared
+ constraints can't be put in the shared layout file media_smartspace_recommendations.xml and
+ the constraints are instead duplicated between here and media_recommendations_expanded.xml.
Ditto for the other cover containers. -->
<Constraint
android:id="@+id/media_cover1_container"
diff --git a/packages/SystemUI/res/xml/media_recommendation_expanded.xml b/packages/SystemUI/res/xml/media_recommendation_expanded.xml
index 09ffebb..ce25a7d 100644
--- a/packages/SystemUI/res/xml/media_recommendation_expanded.xml
+++ b/packages/SystemUI/res/xml/media_recommendation_expanded.xml
@@ -15,7 +15,9 @@
~ limitations under the License
-->
<ConstraintSet
- xmlns:android="http://schemas.android.com/apk/res/android" >
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ >
<Constraint
android:id="@+id/sizing_view"
@@ -23,4 +25,99 @@
android:layout_height="@dimen/qs_media_session_height_expanded"
/>
+ <Constraint
+ android:id="@+id/media_cover1_container"
+ style="@style/MediaPlayer.Recommendation.AlbumContainer"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toTopOf="@+id/media_title1"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toStartOf="@id/media_cover2_container"
+ android:layout_marginEnd="@dimen/qs_media_rec_album_side_margin"
+ app:layout_constraintHorizontal_chainStyle="packed"
+ app:layout_constraintVertical_chainStyle="packed"
+ app:layout_constraintHorizontal_bias="1.0"
+ app:layout_constraintVertical_bias="0.4"
+ />
+
+ <Constraint
+ android:id="@+id/media_title1"
+ style="@style/MediaPlayer.Recommendation.Text.Title"
+ app:layout_constraintStart_toStartOf="@+id/media_cover1_container"
+ app:layout_constraintEnd_toEndOf="@+id/media_cover1_container"
+ app:layout_constraintTop_toBottomOf="@+id/media_cover1_container"
+ app:layout_constraintBottom_toTopOf="@+id/media_subtitle1"
+ />
+
+ <Constraint
+ android:id="@+id/media_subtitle1"
+ style="@style/MediaPlayer.Recommendation.Text.Subtitle"
+ app:layout_constraintStart_toStartOf="@+id/media_cover1_container"
+ app:layout_constraintEnd_toEndOf="@+id/media_cover1_container"
+ app:layout_constraintTop_toBottomOf="@+id/media_title1"
+ app:layout_constraintBottom_toBottomOf="parent"
+ android:layout_marginBottom="@dimen/qs_media_padding"
+ />
+
+ <Constraint
+ android:id="@+id/media_cover2_container"
+ style="@style/MediaPlayer.Recommendation.AlbumContainer"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/media_title2"
+ app:layout_constraintStart_toEndOf="@id/media_cover1_container"
+ app:layout_constraintEnd_toStartOf="@id/media_cover3_container"
+ android:layout_marginEnd="@dimen/qs_media_rec_album_side_margin"
+ app:layout_constraintVertical_chainStyle="packed"
+ app:layout_constraintVertical_bias="0.4"
+ />
+
+ <Constraint
+ android:id="@+id/media_title2"
+ style="@style/MediaPlayer.Recommendation.Text.Title"
+ app:layout_constraintStart_toStartOf="@+id/media_cover2_container"
+ app:layout_constraintEnd_toEndOf="@+id/media_cover2_container"
+ app:layout_constraintTop_toBottomOf="@+id/media_cover2_container"
+ app:layout_constraintBottom_toTopOf="@+id/media_subtitle2"
+ />
+
+ <Constraint
+ android:id="@+id/media_subtitle2"
+ style="@style/MediaPlayer.Recommendation.Text.Subtitle"
+ app:layout_constraintStart_toStartOf="@+id/media_cover2_container"
+ app:layout_constraintEnd_toEndOf="@+id/media_cover2_container"
+ app:layout_constraintTop_toBottomOf="@+id/media_title2"
+ app:layout_constraintBottom_toBottomOf="parent"
+ android:layout_marginBottom="@dimen/qs_media_padding"
+ />
+
+ <Constraint
+ android:id="@+id/media_cover3_container"
+ style="@style/MediaPlayer.Recommendation.AlbumContainer"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/media_title3"
+ app:layout_constraintStart_toEndOf="@id/media_cover2_container"
+ app:layout_constraintEnd_toEndOf="parent"
+ android:layout_marginEnd="@dimen/qs_media_padding"
+ app:layout_constraintVertical_chainStyle="packed"
+ app:layout_constraintVertical_bias="0.4"
+ />
+
+ <Constraint
+ android:id="@+id/media_title3"
+ style="@style/MediaPlayer.Recommendation.Text.Title"
+ app:layout_constraintStart_toStartOf="@+id/media_cover3_container"
+ app:layout_constraintEnd_toEndOf="@+id/media_cover3_container"
+ app:layout_constraintTop_toBottomOf="@+id/media_cover3_container"
+ app:layout_constraintBottom_toTopOf="@+id/media_subtitle3"
+ />
+
+ <Constraint
+ android:id="@+id/media_subtitle3"
+ style="@style/MediaPlayer.Recommendation.Text.Subtitle"
+ app:layout_constraintStart_toStartOf="@+id/media_cover3_container"
+ app:layout_constraintEnd_toEndOf="@+id/media_cover3_container"
+ app:layout_constraintTop_toBottomOf="@+id/media_title3"
+ app:layout_constraintBottom_toBottomOf="parent"
+ android:layout_marginBottom="@dimen/qs_media_padding"
+ />
+
</ConstraintSet>
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index af54e96..d2c35bd 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -991,6 +991,9 @@
List<ViewGroup> mediaCoverContainers = mRecommendationViewHolder.getMediaCoverContainers();
int mediaRecommendationNum = Math.min(mediaRecommendationList.size(),
MEDIA_RECOMMENDATION_MAX_NUM);
+
+ boolean hasTitle = false;
+ boolean hasSubtitle = false;
int uiComponentIndex = 0;
for (int itemIndex = 0;
itemIndex < mediaRecommendationNum && uiComponentIndex < mediaRecommendationNum;
@@ -1036,26 +1039,33 @@
// Set up title
CharSequence title = recommendation.getTitle();
+ hasTitle |= !TextUtils.isEmpty(title);
TextView titleView =
mRecommendationViewHolder.getMediaTitles().get(uiComponentIndex);
titleView.setText(title);
- // TODO(b/223603970): If none of them have titles, should we then hide the views?
// Set up subtitle
- CharSequence subtitle = recommendation.getSubtitle();
- TextView subtitleView =
- mRecommendationViewHolder.getMediaSubtitles().get(uiComponentIndex);
// It would look awkward to show a subtitle if we don't have a title.
boolean shouldShowSubtitleText = !TextUtils.isEmpty(title);
- CharSequence subtitleText = shouldShowSubtitleText ? subtitle : "";
- subtitleView.setText(subtitleText);
- // TODO(b/223603970): If none of them have subtitles, should we then hide the views?
+ CharSequence subtitle = shouldShowSubtitleText ? recommendation.getSubtitle() : "";
+ hasSubtitle |= !TextUtils.isEmpty(subtitle);
+ TextView subtitleView =
+ mRecommendationViewHolder.getMediaSubtitles().get(uiComponentIndex);
+ subtitleView.setText(subtitle);
uiComponentIndex++;
}
-
mSmartspaceMediaItemsCount = uiComponentIndex;
+ // If there's no subtitles and/or titles for any of the albums, hide those views.
+ ConstraintSet expandedSet = mMediaViewController.getExpandedLayout();
+ final boolean titlesVisible = hasTitle;
+ final boolean subtitlesVisible = hasSubtitle;
+ mRecommendationViewHolder.getMediaTitles().forEach((titleView) ->
+ setVisibleAndAlpha(expandedSet, titleView.getId(), titlesVisible));
+ mRecommendationViewHolder.getMediaSubtitles().forEach((subtitleView) ->
+ setVisibleAndAlpha(expandedSet, subtitleView.getId(), subtitlesVisible));
+
// Guts
Runnable onDismissClickedRunnable = () -> {
closeGuts();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
index 83fb82c..6a9c3e3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
@@ -1401,22 +1401,23 @@
val subtitle1 = "Subtitle1"
val subtitle2 = "Subtitle2"
val subtitle3 = "Subtitle3"
+ val icon = Icon.createWithResource(context, R.drawable.ic_1x_mobiledata)
val data = smartspaceData.copy(
recommendations = listOf(
SmartspaceAction.Builder("id1", title1)
.setSubtitle(subtitle1)
- .setIcon(Icon.createWithResource(context, R.drawable.ic_1x_mobiledata))
+ .setIcon(icon)
.setExtras(Bundle.EMPTY)
.build(),
SmartspaceAction.Builder("id2", title2)
.setSubtitle(subtitle2)
- .setIcon(Icon.createWithResource(context, R.drawable.ic_alarm))
+ .setIcon(icon)
.setExtras(Bundle.EMPTY)
.build(),
SmartspaceAction.Builder("id3", title3)
.setSubtitle(subtitle3)
- .setIcon(Icon.createWithResource(context, R.drawable.ic_3g_mobiledata))
+ .setIcon(icon)
.setExtras(Bundle.EMPTY)
.build()
)
@@ -1449,6 +1450,135 @@
assertThat(recSubtitle1.text).isEqualTo("")
}
+ @Test
+ fun bindRecommendation_someHaveTitles_allTitleViewsShown() {
+ useRealConstraintSets()
+ player.attachRecommendation(recommendationViewHolder)
+
+ val icon = Icon.createWithResource(context, R.drawable.ic_1x_mobiledata)
+ val data = smartspaceData.copy(
+ recommendations = listOf(
+ SmartspaceAction.Builder("id1", "")
+ .setSubtitle("fake subtitle")
+ .setIcon(icon)
+ .setExtras(Bundle.EMPTY)
+ .build(),
+ SmartspaceAction.Builder("id2", "title2")
+ .setSubtitle("fake subtitle")
+ .setIcon(icon)
+ .setExtras(Bundle.EMPTY)
+ .build(),
+ SmartspaceAction.Builder("id3", "")
+ .setSubtitle("fake subtitle")
+ .setIcon(icon)
+ .setExtras(Bundle.EMPTY)
+ .build()
+ )
+ )
+ player.bindRecommendation(data)
+
+ assertThat(expandedSet.getVisibility(recTitle1.id)).isEqualTo(ConstraintSet.VISIBLE)
+ assertThat(expandedSet.getVisibility(recTitle2.id)).isEqualTo(ConstraintSet.VISIBLE)
+ assertThat(expandedSet.getVisibility(recTitle3.id)).isEqualTo(ConstraintSet.VISIBLE)
+ }
+
+ @Test
+ fun bindRecommendation_someHaveSubtitles_allSubtitleViewsShown() {
+ useRealConstraintSets()
+ player.attachRecommendation(recommendationViewHolder)
+
+ val icon = Icon.createWithResource(context, R.drawable.ic_1x_mobiledata)
+ val data = smartspaceData.copy(
+ recommendations = listOf(
+ SmartspaceAction.Builder("id1", "")
+ .setSubtitle("")
+ .setIcon(icon)
+ .setExtras(Bundle.EMPTY)
+ .build(),
+ SmartspaceAction.Builder("id2", "title2")
+ .setSubtitle("")
+ .setIcon(icon)
+ .setExtras(Bundle.EMPTY)
+ .build(),
+ SmartspaceAction.Builder("id3", "title3")
+ .setSubtitle("subtitle3")
+ .setIcon(icon)
+ .setExtras(Bundle.EMPTY)
+ .build()
+ )
+ )
+ player.bindRecommendation(data)
+
+ assertThat(expandedSet.getVisibility(recSubtitle1.id)).isEqualTo(ConstraintSet.VISIBLE)
+ assertThat(expandedSet.getVisibility(recSubtitle2.id)).isEqualTo(ConstraintSet.VISIBLE)
+ assertThat(expandedSet.getVisibility(recSubtitle3.id)).isEqualTo(ConstraintSet.VISIBLE)
+ }
+
+ @Test
+ fun bindRecommendation_noneHaveSubtitles_subtitleViewsGone() {
+ useRealConstraintSets()
+ player.attachRecommendation(recommendationViewHolder)
+ val data = smartspaceData.copy(
+ recommendations = listOf(
+ SmartspaceAction.Builder("id1", "title1")
+ .setSubtitle("")
+ .setIcon(Icon.createWithResource(context, R.drawable.ic_1x_mobiledata))
+ .setExtras(Bundle.EMPTY)
+ .build(),
+ SmartspaceAction.Builder("id2", "title2")
+ .setSubtitle("")
+ .setIcon(Icon.createWithResource(context, R.drawable.ic_alarm))
+ .setExtras(Bundle.EMPTY)
+ .build(),
+ SmartspaceAction.Builder("id3", "title3")
+ .setSubtitle("")
+ .setIcon(Icon.createWithResource(context, R.drawable.ic_3g_mobiledata))
+ .setExtras(Bundle.EMPTY)
+ .build()
+ )
+ )
+
+ player.bindRecommendation(data)
+
+ assertThat(expandedSet.getVisibility(recSubtitle1.id)).isEqualTo(ConstraintSet.GONE)
+ assertThat(expandedSet.getVisibility(recSubtitle2.id)).isEqualTo(ConstraintSet.GONE)
+ assertThat(expandedSet.getVisibility(recSubtitle3.id)).isEqualTo(ConstraintSet.GONE)
+ }
+
+ @Test
+ fun bindRecommendation_noneHaveTitles_titleAndSubtitleViewsGone() {
+ useRealConstraintSets()
+ player.attachRecommendation(recommendationViewHolder)
+ val data = smartspaceData.copy(
+ recommendations = listOf(
+ SmartspaceAction.Builder("id1", "")
+ .setSubtitle("subtitle1")
+ .setIcon(Icon.createWithResource(context, R.drawable.ic_1x_mobiledata))
+ .setExtras(Bundle.EMPTY)
+ .build(),
+ SmartspaceAction.Builder("id2", "")
+ .setSubtitle("subtitle2")
+ .setIcon(Icon.createWithResource(context, R.drawable.ic_alarm))
+ .setExtras(Bundle.EMPTY)
+ .build(),
+ SmartspaceAction.Builder("id3", "")
+ .setSubtitle("subtitle3")
+ .setIcon(Icon.createWithResource(context, R.drawable.ic_3g_mobiledata))
+ .setExtras(Bundle.EMPTY)
+ .build()
+ )
+ )
+
+ player.bindRecommendation(data)
+
+ assertThat(expandedSet.getVisibility(recTitle1.id)).isEqualTo(ConstraintSet.GONE)
+ assertThat(expandedSet.getVisibility(recTitle2.id)).isEqualTo(ConstraintSet.GONE)
+ assertThat(expandedSet.getVisibility(recTitle3.id)).isEqualTo(ConstraintSet.GONE)
+ assertThat(expandedSet.getVisibility(recSubtitle1.id)).isEqualTo(ConstraintSet.GONE)
+ assertThat(expandedSet.getVisibility(recSubtitle2.id)).isEqualTo(ConstraintSet.GONE)
+ assertThat(expandedSet.getVisibility(recSubtitle3.id)).isEqualTo(ConstraintSet.GONE)
+ }
+
private fun getScrubbingChangeListener(): SeekBarViewModel.ScrubbingChangeListener =
withArgCaptor { verify(seekBarViewModel).setScrubbingChangeListener(capture()) }