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

Commit c45de709 authored by Cecilia Hong's avatar Cecilia Hong Committed by Android (Google) Code Review
Browse files

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

parents c4399d63 c00205a3
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