Merge "Add progress bar in media recommendation layout." into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
2742fd7482
@@ -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>
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user