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

Commit a355ff4d authored by Cecilia Hong's avatar Cecilia Hong Committed by Automerger Merge Worker
Browse files

Merge "Update Smartspace media recommendation card based on Droidfood's...

Merge "Update Smartspace media recommendation card based on Droidfood's feedbacks." into sc-dev am: c45de709

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

Change-Id: I58df46836594dcabaf226d5ec6ca984b71cdf33a
parents dec2e4ae c45de709
Loading
Loading
Loading
Loading
+83 −47
Original line number Diff line number Diff line
@@ -63,65 +63,101 @@
        android:breakStrategy="balanced"
        android:hyphenationFrequency="none"/>

    <ImageView
        android:id="@+id/media_cover1"
    <FrameLayout
        android:id="@+id/media_cover1_container"
        android:layout_width="0dp"
        android:layout_height="@dimen/qs_aa_media_rec_album_size_collapsed"
        android:background="@drawable/qs_media_light_source">
        <ImageView
            android:id="@+id/media_cover1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:adjustViewBounds="true"
            android:background="@drawable/bg_smartspace_media_item"
            style="@style/MediaPlayer.Album"
            android:clipToOutline="true"
            android:scaleType="centerCrop"/>
    </FrameLayout>

    <ImageView
        android:id="@+id/media_cover2"
    <FrameLayout
        android:id="@+id/media_cover2_container"
        android:layout_width="0dp"
        android:layout_height="@dimen/qs_aa_media_rec_album_size_collapsed"
        android:background="@drawable/qs_media_light_source">
        <ImageView
            android:id="@+id/media_cover2"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:adjustViewBounds="true"
            android:background="@drawable/bg_smartspace_media_item"
            style="@style/MediaPlayer.Album"
            android:clipToOutline="true"
            android:scaleType="centerCrop"/>
    </FrameLayout>

    <ImageView
        android:id="@+id/media_cover3"
    <FrameLayout
        android:id="@+id/media_cover3_container"
        android:layout_width="0dp"
        android:layout_height="@dimen/qs_aa_media_rec_album_size_collapsed"
        android:background="@drawable/qs_media_light_source">
        <ImageView
            android:id="@+id/media_cover3"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:adjustViewBounds="true"
            android:background="@drawable/bg_smartspace_media_item"
            style="@style/MediaPlayer.Album"
            android:clipToOutline="true"
            android:scaleType="centerCrop"/>
    </FrameLayout>

    <ImageView
        android:id="@+id/media_cover4"
    <FrameLayout
        android:id="@+id/media_cover4_container"
        android:layout_width="0dp"
        android:layout_height="@dimen/qs_aa_media_rec_album_size_collapsed"
        android:background="@drawable/qs_media_light_source">
        <ImageView
            android:id="@+id/media_cover4"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:adjustViewBounds="true"
            android:background="@drawable/bg_smartspace_media_item"
            style="@style/MediaPlayer.Album"
            android:clipToOutline="true"
            android:scaleType="centerCrop"/>
    </FrameLayout>

    <ImageView
        android:id="@+id/media_cover5"
    <FrameLayout
        android:id="@+id/media_cover5_container"
        android:layout_width="0dp"
        android:layout_height="@dimen/qs_aa_media_rec_album_size_collapsed"
        android:background="@drawable/qs_media_light_source">
        <ImageView
            android:id="@+id/media_cover5"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:adjustViewBounds="true"
            android:background="@drawable/bg_smartspace_media_item"
            style="@style/MediaPlayer.Album"
            android:clipToOutline="true"
            android:scaleType="centerCrop"/>
    </FrameLayout>

    <ImageView
        android:id="@+id/media_cover6"
    <FrameLayout
        android:id="@+id/media_cover6_container"
        android:layout_width="0dp"
        android:layout_height="@dimen/qs_aa_media_rec_album_size_collapsed"
        android:background="@drawable/qs_media_light_source">
        <ImageView
            android:id="@+id/media_cover6"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:adjustViewBounds="true"
            android:background="@drawable/bg_smartspace_media_item"
            style="@style/MediaPlayer.Album"
            android:clipToOutline="true"
            android:scaleType="centerCrop"/>
    </FrameLayout>

    <!-- Long press menu -->
    <TextView
+17 −17
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@
        app:layout_constraintHorizontal_bias="0" />

    <Constraint
        android:id="@+id/media_cover1"
        android:id="@+id/media_cover1_container"
        android:layout_width="0dp"
        android:layout_height="@dimen/qs_aa_media_rec_album_size_collapsed"
        app:layout_constraintWidth_max="@dimen/qs_aa_media_rec_album_size_collapsed"
@@ -48,13 +48,13 @@
        android:layout_marginBottom="@dimen/qs_media_padding"
        android:layout_marginEnd="@dimen/qs_aa_media_rec_album_margin"
        app:layout_constraintStart_toEndOf="@id/media_vertical_start_guideline"
        app:layout_constraintEnd_toStartOf="@id/media_cover2"
        app:layout_constraintEnd_toStartOf="@id/media_cover2_container"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintHorizontal_bias="1"
        android:visibility="gone" />

    <Constraint
        android:id="@+id/media_cover2"
        android:id="@+id/media_cover2_container"
        android:layout_width="0dp"
        android:layout_height="@dimen/qs_aa_media_rec_album_size_collapsed"
        app:layout_constraintWidth_max="@dimen/qs_aa_media_rec_album_size_collapsed"
@@ -63,14 +63,14 @@
        android:layout_marginEnd="@dimen/qs_aa_media_rec_album_margin"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toEndOf="@id/media_cover1"
        app:layout_constraintEnd_toStartOf="@id/media_cover3"
        app:layout_constraintStart_toEndOf="@id/media_cover1_container"
        app:layout_constraintEnd_toStartOf="@id/media_cover3_container"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintHorizontal_bias="1"
        android:visibility="gone" />

    <Constraint
        android:id="@+id/media_cover3"
        android:id="@+id/media_cover3_container"
        android:layout_width="0dp"
        android:layout_height="@dimen/qs_aa_media_rec_album_size_collapsed"
        app:layout_constraintWidth_max="@dimen/qs_aa_media_rec_album_size_collapsed"
@@ -78,45 +78,45 @@
        android:layout_marginBottom="@dimen/qs_media_padding"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toEndOf="@id/media_cover2"
        app:layout_constraintStart_toEndOf="@id/media_cover2_container"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintHorizontal_bias="1"
        android:visibility="gone" />

    <Constraint
        android:id="@+id/media_cover4"
        android:id="@+id/media_cover4_container"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginEnd="@dimen/qs_aa_media_rec_album_margin"
        app:layout_constraintTop_toBottomOf="@+id/media_cover1"
        app:layout_constraintTop_toBottomOf="@+id/media_cover1_container"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toEndOf="@id/media_vertical_start_guideline"
        app:layout_constraintEnd_toStartOf="@id/media_cover5"
        app:layout_constraintEnd_toStartOf="@id/media_cover5_container"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintHorizontal_bias="1"
        android:visibility="gone" />

    <Constraint
        android:id="@+id/media_cover5"
        android:id="@+id/media_cover5_container"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginEnd="@dimen/qs_aa_media_rec_album_margin"
        app:layout_constraintTop_toBottomOf="@+id/media_cover2"
        app:layout_constraintTop_toBottomOf="@+id/media_cover2_container"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toEndOf="@+id/media_cover4"
        app:layout_constraintEnd_toStartOf="@+id/media_cover6"
        app:layout_constraintStart_toEndOf="@+id/media_cover4_container"
        app:layout_constraintEnd_toStartOf="@+id/media_cover6_container"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintHorizontal_bias="1"
        android:visibility="gone" />

    <Constraint
        android:id="@+id/media_cover6"
        android:id="@+id/media_cover6_container"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintTop_toBottomOf="@id/media_cover3"
        app:layout_constraintTop_toBottomOf="@id/media_cover3_container"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toEndOf="@id/media_cover5"
        app:layout_constraintStart_toEndOf="@id/media_cover5_container"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintHorizontal_bias="1"
+14 −14
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@
        app:layout_constraintHorizontal_bias="0" />

    <Constraint
        android:id="@+id/media_cover1"
        android:id="@+id/media_cover1_container"
        android:layout_width="0dp"
        android:layout_height="@dimen/qs_aa_media_rec_album_size_expanded"
        app:layout_constraintWidth_max="@dimen/qs_aa_media_rec_album_size_expanded"
@@ -48,7 +48,7 @@
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@+id/media_horizontal_center_guideline"
        app:layout_constraintStart_toEndOf="@id/media_vertical_start_guideline"
        app:layout_constraintEnd_toStartOf="@id/media_cover2"
        app:layout_constraintEnd_toStartOf="@id/media_cover2_container"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintHorizontal_bias="1"
        app:layout_constraintVertical_chainStyle="packed"
@@ -56,7 +56,7 @@
        android:visibility="gone" />

    <Constraint
        android:id="@+id/media_cover2"
        android:id="@+id/media_cover2_container"
        android:layout_width="0dp"
        android:layout_height="@dimen/qs_aa_media_rec_album_size_expanded"
        app:layout_constraintWidth_max="@dimen/qs_aa_media_rec_album_size_expanded"
@@ -65,8 +65,8 @@
        android:layout_marginEnd="@dimen/qs_aa_media_rec_album_margin"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@+id/media_horizontal_center_guideline"
        app:layout_constraintStart_toEndOf="@id/media_cover1"
        app:layout_constraintEnd_toStartOf="@id/media_cover3"
        app:layout_constraintStart_toEndOf="@id/media_cover1_container"
        app:layout_constraintEnd_toStartOf="@id/media_cover3_container"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintHorizontal_bias="1"
        app:layout_constraintVertical_chainStyle="packed"
@@ -74,7 +74,7 @@
        android:visibility="gone" />

    <Constraint
        android:id="@+id/media_cover3"
        android:id="@+id/media_cover3_container"
        android:layout_width="0dp"
        android:layout_height="@dimen/qs_aa_media_rec_album_size_expanded"
        app:layout_constraintWidth_max="@dimen/qs_aa_media_rec_album_size_expanded"
@@ -82,7 +82,7 @@
        android:layout_marginBottom="@dimen/qs_aa_media_rec_album_margin"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@+id/media_horizontal_center_guideline"
        app:layout_constraintStart_toEndOf="@id/media_cover2"
        app:layout_constraintStart_toEndOf="@id/media_cover2_container"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintHorizontal_bias="1"
@@ -91,7 +91,7 @@
        android:visibility="gone" />

    <Constraint
        android:id="@+id/media_cover4"
        android:id="@+id/media_cover4_container"
        android:layout_width="0dp"
        android:layout_height="@dimen/qs_aa_media_rec_album_size_expanded"
        app:layout_constraintWidth_max="@dimen/qs_aa_media_rec_album_size_expanded"
@@ -101,7 +101,7 @@
        app:layout_constraintTop_toBottomOf="@+id/media_horizontal_center_guideline"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toEndOf="@id/media_vertical_start_guideline"
        app:layout_constraintEnd_toStartOf="@id/media_cover5"
        app:layout_constraintEnd_toStartOf="@id/media_cover5_container"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintHorizontal_bias="1"
        app:layout_constraintVertical_chainStyle="packed"
@@ -109,7 +109,7 @@
        android:visibility="gone" />

    <Constraint
        android:id="@+id/media_cover5"
        android:id="@+id/media_cover5_container"
        android:layout_width="0dp"
        android:layout_height="@dimen/qs_aa_media_rec_album_size_expanded"
        app:layout_constraintWidth_max="@dimen/qs_aa_media_rec_album_size_expanded"
@@ -118,8 +118,8 @@
        android:layout_marginEnd="@dimen/qs_aa_media_rec_album_margin"
        app:layout_constraintTop_toBottomOf="@+id/media_horizontal_center_guideline"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toEndOf="@+id/media_cover4"
        app:layout_constraintEnd_toStartOf="@+id/media_cover6"
        app:layout_constraintStart_toEndOf="@+id/media_cover4_container"
        app:layout_constraintEnd_toStartOf="@+id/media_cover6_container"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintHorizontal_bias="1"
        app:layout_constraintVertical_chainStyle="packed"
@@ -127,7 +127,7 @@
        android:visibility="gone" />

    <Constraint
        android:id="@+id/media_cover6"
        android:id="@+id/media_cover6_container"
        android:layout_width="0dp"
        android:layout_height="@dimen/qs_aa_media_rec_album_size_expanded"
        app:layout_constraintWidth_max="@dimen/qs_aa_media_rec_album_size_expanded"
@@ -135,7 +135,7 @@
        android:layout_marginBottom="@dimen/qs_media_padding"
        app:layout_constraintTop_toBottomOf="@id/media_horizontal_center_guideline"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toEndOf="@id/media_cover5"
        app:layout_constraintStart_toEndOf="@id/media_cover5_container"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintHorizontal_bias="1"
+23 −13
Original line number Diff line number Diff line
@@ -171,7 +171,7 @@ class MediaCarouselController @Inject constructor(
        visualStabilityCallback = VisualStabilityManager.Callback {
            if (needsReordering) {
                needsReordering = false
                reorderAllPlayers()
                reorderAllPlayers(previousVisiblePlayerKey = null)
            }

            keysNeedRemoval.forEach { removePlayer(it) }
@@ -285,7 +285,7 @@ class MediaCarouselController @Inject constructor(
        return mediaCarousel
    }

    private fun reorderAllPlayers() {
    private fun reorderAllPlayers(previousVisiblePlayerKey: MediaPlayerData.MediaSortKey?) {
        mediaContent.removeAllViews()
        for (mediaPlayer in MediaPlayerData.players()) {
            mediaPlayer.playerViewHolder?.let {
@@ -299,9 +299,16 @@ class MediaCarouselController @Inject constructor(
        // Automatically scroll to the active player if needed
        if (shouldScrollToActivePlayer) {
            shouldScrollToActivePlayer = false
            val activeMediaIndex = MediaPlayerData.activeMediaIndex()
            val activeMediaIndex = MediaPlayerData.firstActiveMediaIndex()
            if (activeMediaIndex != -1) {
                mediaCarouselScrollHandler.scrollToActivePlayer(activeMediaIndex)
                previousVisiblePlayerKey?.let {
                    val previousVisibleIndex = MediaPlayerData.playerKeys()
                        .indexOfFirst { key -> it == key }
                    mediaCarouselScrollHandler
                        .scrollToPlayer(previousVisibleIndex, activeMediaIndex)
                } ?: {
                    mediaCarouselScrollHandler.scrollToPlayer(destIndex = activeMediaIndex)
                }
            }
        }
    }
@@ -310,6 +317,8 @@ class MediaCarouselController @Inject constructor(
    private fun addOrUpdatePlayer(key: String, oldKey: String?, data: MediaData): Boolean {
        val dataCopy = data.copy(backgroundColor = bgColor)
        val existingPlayer = MediaPlayerData.getMediaPlayer(key, oldKey)
        val curVisibleMediaKey = MediaPlayerData.playerKeys()
            .elementAtOrNull(mediaCarouselScrollHandler.visibleMediaIndex)
        if (existingPlayer == null) {
            var newPlayer = mediaControlPanelFactory.get()
            newPlayer.attachPlayer(
@@ -322,12 +331,12 @@ class MediaCarouselController @Inject constructor(
            newPlayer.setListening(currentlyExpanded)
            MediaPlayerData.addMediaPlayer(key, dataCopy, newPlayer)
            updatePlayerToState(newPlayer, noAnimation = true)
            reorderAllPlayers()
            reorderAllPlayers(curVisibleMediaKey)
        } else {
            existingPlayer.bindPlayer(dataCopy, key)
            MediaPlayerData.addMediaPlayer(key, dataCopy, existingPlayer)
            if (visualStabilityManager.isReorderingAllowed || shouldScrollToActivePlayer) {
                reorderAllPlayers()
                reorderAllPlayers(curVisibleMediaKey)
            } else {
                needsReordering = true
            }
@@ -367,9 +376,11 @@ class MediaCarouselController @Inject constructor(
            ViewGroup.LayoutParams.WRAP_CONTENT)
        newRecs.recommendationViewHolder?.recommendations?.setLayoutParams(lp)
        newRecs.bindRecommendation(data.copy(backgroundColor = bgColor))
        val curVisibleMediaKey = MediaPlayerData.playerKeys()
            .elementAtOrNull(mediaCarouselScrollHandler.visibleMediaIndex)
        MediaPlayerData.addMediaRecommendation(key, data, newRecs, shouldPrioritize)
        updatePlayerToState(newRecs, noAnimation = true)
        reorderAllPlayers()
        reorderAllPlayers(curVisibleMediaKey)
        updatePageIndicator()
        mediaCarousel.requiresRemeasuring = true
        // Check postcondition: mediaContent should have the same number of children as there are
@@ -719,9 +730,8 @@ internal object MediaPlayerData {
    )

    private val comparator =
        compareByDescending<MediaSortKey>
            { if (shouldPrioritizeSs) it.isSsMediaRec else !it.isSsMediaRec }
            .thenByDescending { it.data.isPlaying }
        compareByDescending<MediaSortKey> { it.data.isPlaying }
            .thenByDescending { if (shouldPrioritizeSs) it.isSsMediaRec else !it.isSsMediaRec }
            .thenByDescending { it.data.isLocalSession }
            .thenByDescending { !it.data.resumption }
            .thenByDescending { it.updateTime }
@@ -771,8 +781,10 @@ internal object MediaPlayerData {

    fun players() = mediaPlayers.values

    fun playerKeys() = mediaPlayers.keys

    /** Returns the index of the first non-timeout media. */
    fun activeMediaIndex(): Int {
    fun firstActiveMediaIndex(): Int {
        mediaPlayers.entries.forEachIndexed { index, e ->
            if (!e.key.isSsMediaRec && e.key.data.active) {
                return index
@@ -791,8 +803,6 @@ internal object MediaPlayerData {
        return null
    }

    fun playerKeys() = mediaPlayers.keys

    @VisibleForTesting
    fun clear() {
        mediaData.clear()
+11 −2
Original line number Diff line number Diff line
@@ -559,8 +559,17 @@ class MediaCarouselScrollHandler(
        scrollView.relativeScrollX = 0
    }

    fun scrollToActivePlayer(activePlayerIndex: Int) {
        val destIndex = Math.min(mediaContent.getChildCount() - 1, activePlayerIndex)
    /**
     * Smooth scroll to the destination player.
     *
     * @param sourceIndex optional source index to indicate where the scroll should begin.
     * @param destIndex destination index to indicate where the scroll should end.
     */
    fun scrollToPlayer(sourceIndex: Int = -1, destIndex: Int) {
        if (sourceIndex >= 0 && sourceIndex < mediaContent.childCount) {
            scrollView.relativeScrollX = sourceIndex * playerWidthPlusPadding
        }
        val destIndex = Math.min(mediaContent.getChildCount() - 1, destIndex)
        val view = mediaContent.getChildAt(destIndex)
        // We need to post this to wait for the active player becomes visible.
        mainExecutor.executeDelayed({
Loading