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

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

Merge "Slide transition from the media reco card to the active media player...

Merge "Slide transition from the media reco card to the active media player after a media reco is tapped." into sc-dev am: 8494eaaf

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

Change-Id: I4f99011c3ce189f600a9a4f255fece2f90780a63
parents e2915429 8494eaaf
Loading
Loading
Loading
Loading
+24 −4
Original line number Original line Diff line number Diff line
@@ -115,6 +115,7 @@ class MediaCarouselController @Inject constructor(
    private var needsReordering: Boolean = false
    private var needsReordering: Boolean = false
    private var keysNeedRemoval = mutableSetOf<String>()
    private var keysNeedRemoval = mutableSetOf<String>()
    private var bgColor = getBackgroundColor()
    private var bgColor = getBackgroundColor()
    private var shouldScrollToActivePlayer: Boolean = false
    private var isRtl: Boolean = false
    private var isRtl: Boolean = false
        set(value) {
        set(value) {
            if (value != field) {
            if (value != field) {
@@ -271,6 +272,15 @@ class MediaCarouselController @Inject constructor(
            }
            }
        }
        }
        mediaCarouselScrollHandler.onPlayersChanged()
        mediaCarouselScrollHandler.onPlayersChanged()

        // Automatically scroll to the active player if needed
        if (shouldScrollToActivePlayer) {
            shouldScrollToActivePlayer = false
            val activeMediaIndex = MediaPlayerData.getActiveMediaIndex()
            if (activeMediaIndex != -1) {
                mediaCarouselScrollHandler.scrollToActivePlayer(activeMediaIndex)
            }
        }
    }
    }


    private fun addOrUpdatePlayer(key: String, oldKey: String?, data: MediaData) {
    private fun addOrUpdatePlayer(key: String, oldKey: String?, data: MediaData) {
@@ -322,8 +332,8 @@ class MediaCarouselController @Inject constructor(
        val lp = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
        val lp = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.WRAP_CONTENT)
            ViewGroup.LayoutParams.WRAP_CONTENT)
        newRecs.recommendationViewHolder?.recommendations?.setLayoutParams(lp)
        newRecs.recommendationViewHolder?.recommendations?.setLayoutParams(lp)
        newRecs.bindRecommendation(data, bgColor)
        newRecs.bindRecommendation(data, bgColor, { v -> shouldScrollToActivePlayer = true })
        MediaPlayerData.addMediaPlayer(key, newRecs)
        MediaPlayerData.addMediaRecommendation(key, newRecs)
        updatePlayerToState(newRecs, noAnimation = true)
        updatePlayerToState(newRecs, noAnimation = true)
        reorderAllPlayers()
        reorderAllPlayers()
        updatePageIndicator()
        updatePageIndicator()
@@ -593,7 +603,7 @@ class MediaCarouselController @Inject constructor(
@VisibleForTesting
@VisibleForTesting
internal object MediaPlayerData {
internal object MediaPlayerData {
    private val EMPTY = MediaData(-1, false, 0, null, null, null, null, null,
    private val EMPTY = MediaData(-1, false, 0, null, null, null, null, null,
        emptyList(), emptyList(), "INVALID", null, null, null, true, null)
        emptyList(), emptyList(), "INVALID", null, null, null, false, null)


    private data class MediaSortKey(
    private data class MediaSortKey(
        // Is Smartspace media recommendation. When the Smartspace media is present, it should
        // Is Smartspace media recommendation. When the Smartspace media is present, it should
@@ -620,7 +630,7 @@ internal object MediaPlayerData {
        mediaPlayers.put(sortKey, player)
        mediaPlayers.put(sortKey, player)
    }
    }


    fun addMediaPlayer(key: String, player: MediaControlPanel) {
    fun addMediaRecommendation(key: String, player: MediaControlPanel) {
        removeMediaPlayer(key)
        removeMediaPlayer(key)
        val sortKey = MediaSortKey(isSsMediaRec = true, EMPTY, System.currentTimeMillis())
        val sortKey = MediaSortKey(isSsMediaRec = true, EMPTY, System.currentTimeMillis())
        mediaData.put(key, sortKey)
        mediaData.put(key, sortKey)
@@ -643,6 +653,16 @@ internal object MediaPlayerData {


    fun players() = mediaPlayers.values
    fun players() = mediaPlayers.values


    /** Returns the index of the first non-timeout media. */
    fun getActiveMediaIndex(): Int {
        mediaPlayers.entries.forEachIndexed { index, e ->
            if (e.key.data.active) {
                return index
            }
        }
        return -1
    }

    @VisibleForTesting
    @VisibleForTesting
    fun clear() {
    fun clear() {
        mediaData.clear()
        mediaData.clear()
+23 −10
Original line number Original line Diff line number Diff line
@@ -38,6 +38,7 @@ import com.android.systemui.util.concurrency.DelayableExecutor


private const val FLING_SLOP = 1000000
private const val FLING_SLOP = 1000000
private const val DISMISS_DELAY = 100L
private const val DISMISS_DELAY = 100L
private const val SCROLL_DELAY = 100L
private const val RUBBERBAND_FACTOR = 0.2f
private const val RUBBERBAND_FACTOR = 0.2f
private const val SETTINGS_BUTTON_TRANSLATION_FRACTION = 0.3f
private const val SETTINGS_BUTTON_TRANSLATION_FRACTION = 0.3f


@@ -100,10 +101,11 @@ class MediaCarouselScrollHandler(
    private lateinit var settingsButton: View
    private lateinit var settingsButton: View


    /**
    /**
     * What's the currently active player index?
     * What's the currently visible player index?
     */
     */
    var activeMediaIndex: Int = 0
    var visibleMediaIndex: Int = 0
        private set
        private set

    /**
    /**
     * How much are we scrolled into the current media?
     * How much are we scrolled into the current media?
     */
     */
@@ -129,7 +131,7 @@ class MediaCarouselScrollHandler(
            field = value
            field = value
            // The player width has changed, let's update the scroll position to make sure
            // The player width has changed, let's update the scroll position to make sure
            // it's still at the same place
            // it's still at the same place
            var newRelativeScroll = activeMediaIndex * playerWidthPlusPadding
            var newRelativeScroll = visibleMediaIndex * playerWidthPlusPadding
            if (scrollIntoCurrentMedia > playerWidthPlusPadding) {
            if (scrollIntoCurrentMedia > playerWidthPlusPadding) {
                newRelativeScroll += playerWidthPlusPadding -
                newRelativeScroll += playerWidthPlusPadding -
                        (scrollIntoCurrentMedia - playerWidthPlusPadding)
                        (scrollIntoCurrentMedia - playerWidthPlusPadding)
@@ -457,12 +459,12 @@ class MediaCarouselScrollHandler(
        val wasScrolledIn = scrollIntoCurrentMedia != 0
        val wasScrolledIn = scrollIntoCurrentMedia != 0
        scrollIntoCurrentMedia = scrollInAmount
        scrollIntoCurrentMedia = scrollInAmount
        val nowScrolledIn = scrollIntoCurrentMedia != 0
        val nowScrolledIn = scrollIntoCurrentMedia != 0
        if (newIndex != activeMediaIndex || wasScrolledIn != nowScrolledIn) {
        if (newIndex != visibleMediaIndex || wasScrolledIn != nowScrolledIn) {
            activeMediaIndex = newIndex
            visibleMediaIndex = newIndex
            closeGuts()
            closeGuts()
            updatePlayerVisibilities()
            updatePlayerVisibilities()
        }
        }
        val relativeLocation = activeMediaIndex.toFloat() + if (playerWidthPlusPadding > 0)
        val relativeLocation = visibleMediaIndex.toFloat() + if (playerWidthPlusPadding > 0)
            scrollInAmount.toFloat() / playerWidthPlusPadding else 0f
            scrollInAmount.toFloat() / playerWidthPlusPadding else 0f
        // Fix the location, because PageIndicator does not handle RTL internally
        // Fix the location, because PageIndicator does not handle RTL internally
        val location = if (isRtl) {
        val location = if (isRtl) {
@@ -500,7 +502,7 @@ class MediaCarouselScrollHandler(
        val scrolledIn = scrollIntoCurrentMedia != 0
        val scrolledIn = scrollIntoCurrentMedia != 0
        for (i in 0 until mediaContent.childCount) {
        for (i in 0 until mediaContent.childCount) {
            val view = mediaContent.getChildAt(i)
            val view = mediaContent.getChildAt(i)
            val visible = (i == activeMediaIndex) || ((i == (activeMediaIndex + 1)) && scrolledIn)
            val visible = (i == visibleMediaIndex) || ((i == (visibleMediaIndex + 1)) && scrolledIn)
            view.visibility = if (visible) View.VISIBLE else View.INVISIBLE
            view.visibility = if (visible) View.VISIBLE else View.INVISIBLE
        }
        }
    }
    }
@@ -511,12 +513,12 @@ class MediaCarouselScrollHandler(
     */
     */
    fun onPrePlayerRemoved(removed: MediaControlPanel) {
    fun onPrePlayerRemoved(removed: MediaControlPanel) {
        val removedIndex = mediaContent.indexOfChild(removed.playerViewHolder?.player)
        val removedIndex = mediaContent.indexOfChild(removed.playerViewHolder?.player)
        // If the removed index is less than the activeMediaIndex, then we need to decrement it.
        // If the removed index is less than the visibleMediaIndex, then we need to decrement it.
        // RTL has no effect on this, because indices are always relative (start-to-end).
        // RTL has no effect on this, because indices are always relative (start-to-end).
        // Update the index 'manually' since we won't always get a call to onMediaScrollingChanged
        // Update the index 'manually' since we won't always get a call to onMediaScrollingChanged
        val beforeActive = removedIndex <= activeMediaIndex
        val beforeActive = removedIndex <= visibleMediaIndex
        if (beforeActive) {
        if (beforeActive) {
            activeMediaIndex = Math.max(0, activeMediaIndex - 1)
            visibleMediaIndex = Math.max(0, visibleMediaIndex - 1)
        }
        }
        // If the removed media item is "left of" the active one (in an absolute sense), we need to
        // If the removed media item is "left of" the active one (in an absolute sense), we need to
        // scroll the view to keep that player in view.  This is because scroll position is always
        // scroll the view to keep that player in view.  This is because scroll position is always
@@ -545,6 +547,17 @@ class MediaCarouselScrollHandler(
        scrollView.relativeScrollX = 0
        scrollView.relativeScrollX = 0
    }
    }


    fun scrollToActivePlayer(activePlayerIndex: Int) {
        var destIndex = activePlayerIndex
        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({
            visibleMediaIndex = activePlayerIndex
            scrollView.smoothScrollTo(view.left, scrollView.scrollY)
        }, SCROLL_DELAY)
    }

    companion object {
    companion object {
        private val CONTENT_TRANSLATION = object : FloatPropertyCompat<MediaCarouselScrollHandler>(
        private val CONTENT_TRANSLATION = object : FloatPropertyCompat<MediaCarouselScrollHandler>(
                "contentTranslation") {
                "contentTranslation") {
+3 −2
Original line number Original line Diff line number Diff line
@@ -462,7 +462,8 @@ public class MediaControlPanel {
    /** Bind this recommendation view based on the data given. */
    /** Bind this recommendation view based on the data given. */
    public void bindRecommendation(
    public void bindRecommendation(
            @NonNull SmartspaceTarget target,
            @NonNull SmartspaceTarget target,
            @NonNull int backgroundColor) {
            @NonNull int backgroundColor,
            @Nullable View.OnClickListener callback) {
        if (mRecommendationViewHolder == null) {
        if (mRecommendationViewHolder == null) {
            return;
            return;
        }
        }
@@ -526,7 +527,7 @@ public class MediaControlPanel {
            setSmartspaceRecItemOnClickListener(
            setSmartspaceRecItemOnClickListener(
                    mediaCoverImageView,
                    mediaCoverImageView,
                    recommendation,
                    recommendation,
                    null);
                    callback);


            if (uiComponentIndex < MEDIA_RECOMMENDATION_ITEMS_PER_ROW) {
            if (uiComponentIndex < MEDIA_RECOMMENDATION_ITEMS_PER_ROW) {
                setVisibleAndAlpha(collapsedSet,
                setVisibleAndAlpha(collapsedSet,