diff --git a/packages/SystemUI/res/layout/media_session_view.xml b/packages/SystemUI/res/layout/media_session_view.xml index 7962e22d6b7ff..534c80de73f44 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 @@ + + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + > + + + + + + + + + + + + + + + + + + diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java index af54e966ed9c2..d2c35bd96d5a9 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 @@ public class MediaControlPanel { List 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 @@ public class MediaControlPanel { // 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 83fb82c1c493e..6a9c3e3495227 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 @@ public class MediaControlPanelTest : SysuiTestCase() { 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 @@ public class MediaControlPanelTest : SysuiTestCase() { 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()) }