Merge "Add progress bar in media recommendation layout." into tm-qpr-dev

This commit is contained in:
Michael Mikhail
2023-01-31 23:08:17 +00:00
committed by Android (Google) Code Review
4 changed files with 124 additions and 0 deletions

View File

@@ -62,4 +62,24 @@
android:textSize="11sp"
android:gravity="center_vertical"
android:layout_gravity="bottom"/>
<!-- Seek Bar -->
<SeekBar
android:id="@+id/media_progress_bar"
android:layout_width="match_parent"
android:layout_height="12dp"
android:layout_gravity="bottom"
android:maxHeight="@dimen/qs_media_enabled_seekbar_height"
android:thumb="@android:color/transparent"
android:splitTrack="false"
android:clickable="false"
android:progressTint="?android:attr/textColorPrimary"
android:progressBackgroundTint="?android:attr/textColorTertiary"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:paddingStart="0dp"
android:paddingEnd="0dp"
android:layout_marginEnd="@dimen/qs_media_info_spacing"
android:layout_marginStart="@dimen/qs_media_info_spacing"
android:layout_marginBottom="@dimen/qs_media_info_spacing"/>
</merge>

View File

@@ -20,6 +20,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.SeekBar
import android.widget.TextView
import com.android.internal.widget.CachingIconView
import com.android.systemui.R
@@ -37,6 +38,7 @@ class RecommendationViewHolder private constructor(itemView: View, updatedView:
// Recommendation screen
lateinit var cardIcon: ImageView
lateinit var mediaAppIcons: List<CachingIconView>
lateinit var mediaProgressBars: List<SeekBar>
lateinit var cardTitle: TextView
val mediaCoverContainers =
@@ -82,6 +84,13 @@ class RecommendationViewHolder private constructor(itemView: View, updatedView:
if (updatedView) {
mediaAppIcons = mediaCoverContainers.map { it.requireViewById(R.id.media_rec_app_icon) }
cardTitle = itemView.requireViewById(R.id.media_rec_title)
mediaProgressBars =
mediaCoverContainers.map {
it.requireViewById<SeekBar?>(R.id.media_progress_bar).apply {
// Media playback is in the direction of tape, not time, so it stays LTR
layoutDirection = View.LAYOUT_DIRECTION_LTR
}
}
} else {
cardIcon = itemView.requireViewById<ImageView>(R.id.recommendation_card_icon)
}

View File

@@ -56,6 +56,7 @@ import android.view.ViewGroup;
import android.view.animation.Interpolator;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
@@ -1366,6 +1367,24 @@ public class MediaControlPanel {
hasSubtitle |= !TextUtils.isEmpty(subtitle);
TextView subtitleView = mRecommendationViewHolder.getMediaSubtitles().get(itemIndex);
subtitleView.setText(subtitle);
// Set up progress bar
if (mFeatureFlags.isEnabled(Flags.MEDIA_RECOMMENDATION_CARD_UPDATE)) {
SeekBar mediaProgressBar =
mRecommendationViewHolder.getMediaProgressBars().get(itemIndex);
TextView mediaSubtitle =
mRecommendationViewHolder.getMediaSubtitles().get(itemIndex);
// show progress bar if the recommended album is played.
Double progress = MediaDataUtils.getDescriptionProgress(recommendation.getExtras());
if (progress == null || progress <= 0.0) {
mediaProgressBar.setVisibility(View.GONE);
mediaSubtitle.setVisibility(View.VISIBLE);
} else {
mediaProgressBar.setProgress((int) (progress * 100));
mediaProgressBar.setVisibility(View.VISIBLE);
mediaSubtitle.setVisibility(View.GONE);
}
}
}
mSmartspaceMediaItemsCount = NUM_REQUIRED_RECOMMENDATIONS;
@@ -1440,6 +1459,12 @@ public class MediaControlPanel {
(title) -> title.setTextColor(textPrimaryColor));
mRecommendationViewHolder.getMediaSubtitles().forEach(
(subtitle) -> subtitle.setTextColor(textSecondaryColor));
if (mFeatureFlags.isEnabled(Flags.MEDIA_RECOMMENDATION_CARD_UPDATE)) {
mRecommendationViewHolder.getMediaProgressBars().forEach(
(progressBar) -> progressBar.setProgressTintList(
ColorStateList.valueOf(textPrimaryColor))
);
}
mRecommendationViewHolder.getGutsViewHolder().setColors(colorScheme);
}

View File

@@ -52,6 +52,7 @@ import android.widget.TextView
import androidx.constraintlayout.widget.Barrier
import androidx.constraintlayout.widget.ConstraintSet
import androidx.lifecycle.LiveData
import androidx.media.utils.MediaConstants
import androidx.test.filters.SmallTest
import com.android.internal.logging.InstanceId
import com.android.internal.widget.CachingIconView
@@ -206,6 +207,12 @@ public class MediaControlPanelTest : SysuiTestCase() {
@Mock private lateinit var coverContainer3: ViewGroup
@Mock private lateinit var recAppIconItem: CachingIconView
@Mock private lateinit var recCardTitle: TextView
@Mock private lateinit var recProgressBar1: SeekBar
@Mock private lateinit var recProgressBar2: SeekBar
@Mock private lateinit var recProgressBar3: SeekBar
@Mock private lateinit var recSubtitleMock1: TextView
@Mock private lateinit var recSubtitleMock2: TextView
@Mock private lateinit var recSubtitleMock3: TextView
@Mock private lateinit var coverItem: ImageView
private lateinit var coverItem1: ImageView
private lateinit var coverItem2: ImageView
@@ -2081,6 +2088,10 @@ public class MediaControlPanelTest : SysuiTestCase() {
whenever(recommendationViewHolder.cardTitle).thenReturn(recCardTitle)
whenever(recommendationViewHolder.mediaCoverItems)
.thenReturn(listOf(coverItem, coverItem, coverItem))
whenever(recommendationViewHolder.mediaProgressBars)
.thenReturn(listOf(recProgressBar1, recProgressBar2, recProgressBar3))
whenever(recommendationViewHolder.mediaSubtitles)
.thenReturn(listOf(recSubtitleMock1, recSubtitleMock2, recSubtitleMock3))
val bmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bmp)
@@ -2118,6 +2129,65 @@ public class MediaControlPanelTest : SysuiTestCase() {
verify(coverItem, times(3)).setImageDrawable(any(Drawable::class.java))
}
@Test
fun bindRecommendationWithProgressBars() {
fakeFeatureFlag.set(Flags.MEDIA_RECOMMENDATION_CARD_UPDATE, true)
whenever(recommendationViewHolder.mediaAppIcons)
.thenReturn(listOf(recAppIconItem, recAppIconItem, recAppIconItem))
whenever(recommendationViewHolder.cardTitle).thenReturn(recCardTitle)
whenever(recommendationViewHolder.mediaCoverItems)
.thenReturn(listOf(coverItem, coverItem, coverItem))
whenever(recommendationViewHolder.mediaProgressBars)
.thenReturn(listOf(recProgressBar1, recProgressBar2, recProgressBar3))
whenever(recommendationViewHolder.mediaSubtitles)
.thenReturn(listOf(recSubtitleMock1, recSubtitleMock2, recSubtitleMock3))
val bmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bmp)
canvas.drawColor(Color.RED)
val albumArt = Icon.createWithBitmap(bmp)
val bundle =
Bundle().apply {
putInt(
MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS,
MediaConstants.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_PARTIALLY_PLAYED
)
putDouble(MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE, 0.5)
}
val data =
smartspaceData.copy(
recommendations =
listOf(
SmartspaceAction.Builder("id1", "title1")
.setSubtitle("subtitle1")
.setIcon(albumArt)
.setExtras(bundle)
.build(),
SmartspaceAction.Builder("id2", "title2")
.setSubtitle("subtitle1")
.setIcon(albumArt)
.setExtras(Bundle.EMPTY)
.build(),
SmartspaceAction.Builder("id3", "title3")
.setSubtitle("subtitle1")
.setIcon(albumArt)
.setExtras(Bundle.EMPTY)
.build()
)
)
player.attachRecommendation(recommendationViewHolder)
player.bindRecommendation(data)
verify(recProgressBar1).setProgress(50)
verify(recProgressBar1).visibility = View.VISIBLE
verify(recProgressBar2).visibility = View.GONE
verify(recProgressBar3).visibility = View.GONE
verify(recSubtitleMock1).visibility = View.GONE
verify(recSubtitleMock2).visibility = View.VISIBLE
verify(recSubtitleMock3).visibility = View.VISIBLE
}
@Test
fun onButtonClick_touchRippleFlagEnabled_playsTouchRipple() {
fakeFeatureFlag.set(Flags.UMO_SURFACE_RIPPLE, true)