Merge changes I72eaf3f2,Ibb3c8d9d into tm-dev am: cfb68860ae

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17885556

Change-Id: I583e1be99ab4ac40b3d07b90a4f0144f609c27d6
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Caitlin Cassidy
2022-04-22 18:01:05 +00:00
committed by Automerger Merge Worker
6 changed files with 258 additions and 63 deletions

View File

@@ -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"

View File

@@ -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

View File

@@ -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"

View File

@@ -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>

View File

@@ -991,6 +991,9 @@ public class MediaControlPanel {
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 @@ 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();

View File

@@ -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()) }