Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f7b51341 authored by Michael Mikhail's avatar Michael Mikhail
Browse files

Add progress bar in media recommendation layout.

Bug: 264690666
Test: checked the seekbar style on media controls and it matches the
mock. Screenshot in bug link.

Change-Id: Ia2e3aa6e5313c5b80d1c049668d8226450cc98d5
parent 0f245613
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -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>
 No newline at end of file
+9 −0
Original line number Diff line number Diff line
@@ -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)
        }
+25 −0
Original line number Diff line number Diff line
@@ -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);
    }
+70 −0
Original line number Diff line number Diff line
@@ -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)