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

Commit 785595b2 authored by Sherry Zhou's avatar Sherry Zhou Committed by Automerger Merge Worker
Browse files

Merge "Make UMO squishy and add motion to widgets only for split shade" into...

Merge "Make UMO squishy and add motion to widgets only for split shade" into tm-qpr-dev am: 7b25799b

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



Change-Id: Ibdd5b1bd1511e710aecd19cd9211b0c2a30fc9da
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 624112a0 7b25799b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -16,6 +16,6 @@
  -->

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    <solid android:color="@android:color/white" />
    <solid android:color="@android:color/transparent" />
    <corners android:radius="@dimen/qs_media_album_radius" />
</shape>
 No newline at end of file
+34 −4
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ import android.util.MathUtils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.PathInterpolator
import android.widget.LinearLayout
import androidx.annotation.VisibleForTesting
import com.android.internal.logging.InstanceId
@@ -95,7 +96,8 @@ class MediaCarouselController @Inject constructor(
     * finished
     */
    @MediaLocation
    private var currentEndLocation: Int = -1
    @VisibleForTesting
    var currentEndLocation: Int = -1

    /**
     * The ending location of the view where it ends when all animations and transitions have
@@ -126,7 +128,8 @@ class MediaCarouselController @Inject constructor(
    lateinit var settingsButton: View
        private set
    private val mediaContent: ViewGroup
    private val pageIndicator: PageIndicator
    @VisibleForTesting
    val pageIndicator: PageIndicator
    private val visualStabilityCallback: OnReorderingAllowedListener
    private var needsReordering: Boolean = false
    private var keysNeedRemoval = mutableSetOf<String>()
@@ -149,6 +152,27 @@ class MediaCarouselController @Inject constructor(
                }
            }
        }

    companion object {
        const val ANIMATION_BASE_DURATION = 2200f
        const val DURATION = 167f
        const val DETAILS_DELAY = 1067f
        const val CONTROLS_DELAY = 1400f
        const val PAGINATION_DELAY = 1900f
        const val MEDIATITLES_DELAY = 1000f
        const val MEDIACONTAINERS_DELAY = 967f
        val TRANSFORM_BEZIER = PathInterpolator (0.68F, 0F, 0F, 1F)
        val REVERSE_BEZIER = PathInterpolator (0F, 0.68F, 1F, 0F)

        fun calculateAlpha(squishinessFraction: Float, delay: Float, duration: Float): Float {
            val transformStartFraction = delay / ANIMATION_BASE_DURATION
            val transformDurationFraction = duration / ANIMATION_BASE_DURATION
            val squishinessToTime = REVERSE_BEZIER.getInterpolation(squishinessFraction)
            return MathUtils.constrain((squishinessToTime - transformStartFraction) /
                    transformDurationFraction, 0F, 1F)
        }
    }

    private val configListener = object : ConfigurationController.ConfigurationListener {
        override fun onDensityOrFontScaleChanged() {
            // System font changes should only happen when UMO is offscreen or a flicker may occur
@@ -633,12 +657,17 @@ class MediaCarouselController @Inject constructor(
        }
    }

    private fun updatePageIndicatorAlpha() {
    @VisibleForTesting
    fun updatePageIndicatorAlpha() {
        val hostStates = mediaHostStatesManager.mediaHostStates
        val endIsVisible = hostStates[currentEndLocation]?.visible ?: false
        val startIsVisible = hostStates[currentStartLocation]?.visible ?: false
        val startAlpha = if (startIsVisible) 1.0f else 0.0f
        val endAlpha = if (endIsVisible) 1.0f else 0.0f
        // when squishing in split shade, only use endState, which keeps changing
        // to provide squishFraction
        val squishFraction = hostStates[currentEndLocation]?.squishFraction ?: 1.0F
        val endAlpha = (if (endIsVisible) 1.0f else 0.0f) *
                calculateAlpha(squishFraction, PAGINATION_DELAY, DURATION)
        var alpha = 1.0f
        if (!endIsVisible || !startIsVisible) {
            var progress = currentTransitionProgress
@@ -687,6 +716,7 @@ class MediaCarouselController @Inject constructor(
            mediaCarouselScrollHandler.setCarouselBounds(
                    currentCarouselWidth, currentCarouselHeight)
            updatePageIndicatorLocation()
            updatePageIndicatorAlpha()
        }
    }

+18 −0
Original line number Diff line number Diff line
@@ -203,6 +203,14 @@ class MediaHost constructor(
                }
            }

        override var squishFraction: Float = 1.0f
            set(value) {
                if (!value.equals(field)) {
                    field = value
                    changedListener?.invoke()
                }
            }

        override var showsOnlyActiveMedia: Boolean = false
            set(value) {
                if (!value.equals(field)) {
@@ -253,6 +261,7 @@ class MediaHost constructor(
        override fun copy(): MediaHostState {
            val mediaHostState = MediaHostStateHolder()
            mediaHostState.expansion = expansion
            mediaHostState.squishFraction = squishFraction
            mediaHostState.showsOnlyActiveMedia = showsOnlyActiveMedia
            mediaHostState.measurementInput = measurementInput?.copy()
            mediaHostState.visible = visible
@@ -271,6 +280,9 @@ class MediaHost constructor(
            if (expansion != other.expansion) {
                return false
            }
            if (squishFraction != other.squishFraction) {
                return false
            }
            if (showsOnlyActiveMedia != other.showsOnlyActiveMedia) {
                return false
            }
@@ -289,6 +301,7 @@ class MediaHost constructor(
        override fun hashCode(): Int {
            var result = measurementInput?.hashCode() ?: 0
            result = 31 * result + expansion.hashCode()
            result = 31 * result + squishFraction.hashCode()
            result = 31 * result + falsingProtectionNeeded.hashCode()
            result = 31 * result + showsOnlyActiveMedia.hashCode()
            result = 31 * result + if (visible) 1 else 2
@@ -328,6 +341,11 @@ interface MediaHostState {
     */
    var expansion: Float

    /**
     * Fraction of the height animation.
     */
    var squishFraction: Float

    /**
     * Is this host only showing active media or is it showing all of them including resumption?
     */
+97 −29
Original line number Diff line number Diff line
@@ -18,8 +18,15 @@ package com.android.systemui.media

import android.content.Context
import android.content.res.Configuration
import androidx.annotation.VisibleForTesting
import androidx.constraintlayout.widget.ConstraintSet
import com.android.systemui.R
import com.android.systemui.media.MediaCarouselController.Companion.CONTROLS_DELAY
import com.android.systemui.media.MediaCarouselController.Companion.DETAILS_DELAY
import com.android.systemui.media.MediaCarouselController.Companion.DURATION
import com.android.systemui.media.MediaCarouselController.Companion.MEDIACONTAINERS_DELAY
import com.android.systemui.media.MediaCarouselController.Companion.MEDIATITLES_DELAY
import com.android.systemui.media.MediaCarouselController.Companion.calculateAlpha
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.animation.MeasurementOutput
import com.android.systemui.util.animation.TransitionLayout
@@ -50,6 +57,24 @@ class MediaViewController @Inject constructor(
    companion object {
        @JvmField
        val GUTS_ANIMATION_DURATION = 500L
        val controlIds = setOf(
                R.id.media_progress_bar,
                R.id.actionNext,
                R.id.actionPrev,
                R.id.action0,
                R.id.action1,
                R.id.action2,
                R.id.action3,
                R.id.action4,
                R.id.media_scrubbing_elapsed_time,
                R.id.media_scrubbing_total_time
        )

        val detailIds = setOf(
                R.id.header_title,
                R.id.header_artist,
                R.id.actionPlayPause,
        )
    }

    /**
@@ -57,6 +82,7 @@ class MediaViewController @Inject constructor(
     */
    lateinit var sizeChangedListener: () -> Unit
    private var firstRefresh: Boolean = true
    @VisibleForTesting
    private var transitionLayout: TransitionLayout? = null
    private val layoutController = TransitionLayoutController()
    private var animationDelay: Long = 0
@@ -278,11 +304,48 @@ class MediaViewController @Inject constructor(
        }
    }

    /**
     * Apply squishFraction to a copy of viewState such that the cached version is untouched.
    */
    internal fun squishViewState(
        viewState: TransitionViewState,
        squishFraction: Float
    ): TransitionViewState {
        val squishedViewState = viewState.copy()
        squishedViewState.height = (squishedViewState.height * squishFraction).toInt()
        controlIds.forEach { id ->
            squishedViewState.widgetStates.get(id)?.let { state ->
                state.alpha = calculateAlpha(squishFraction, CONTROLS_DELAY, DURATION)
            }
        }

        detailIds.forEach { id ->
            squishedViewState.widgetStates.get(id)?.let { state ->
                state.alpha = calculateAlpha(squishFraction, DETAILS_DELAY, DURATION)
            }
        }

        RecommendationViewHolder.mediaContainersIds.forEach { id ->
            squishedViewState.widgetStates.get(id)?.let { state ->
                state.alpha = calculateAlpha(squishFraction, MEDIACONTAINERS_DELAY, DURATION)
            }
        }

        RecommendationViewHolder.mediaTitlesAndSubtitlesIds.forEach { id ->
            squishedViewState.widgetStates.get(id)?.let { state ->
                state.alpha = calculateAlpha(squishFraction, MEDIATITLES_DELAY, DURATION)
            }
        }

        return squishedViewState
    }

    /**
     * Obtain a new viewState for a given media state. This usually returns a cached state, but if
     * it's not available, it will recreate one by measuring, which may be expensive.
     */
    private fun obtainViewState(state: MediaHostState?): TransitionViewState? {
     @VisibleForTesting
     fun obtainViewState(state: MediaHostState?): TransitionViewState? {
        if (state == null || state.measurementInput == null) {
            return null
        }
@@ -291,13 +354,18 @@ class MediaViewController @Inject constructor(
        val viewState = viewStates[cacheKey]
        if (viewState != null) {
            // we already have cached this measurement, let's continue
            if (state.squishFraction <= 1f) {
                return squishViewState(viewState, state.squishFraction)
            }
            return viewState
        }
        // Copy the key since this might call recursively into it and we're using tmpKey
        cacheKey = cacheKey.copy()
        val result: TransitionViewState?

        if (transitionLayout != null) {
        if (transitionLayout == null) {
            return null
        }
        // Let's create a new measurement
        if (state.expansion == 0.0f || state.expansion == 1.0f) {
            result = transitionLayout!!.calculateViewState(
@@ -324,8 +392,8 @@ class MediaViewController @Inject constructor(
                    endViewState,
                    state.expansion)
        }
        } else {
            result = null
        if (state.squishFraction <= 1f) {
            return squishViewState(result, state.squishFraction)
        }
        return result
    }
+15 −0
Original line number Diff line number Diff line
@@ -106,5 +106,20 @@ class RecommendationViewHolder private constructor(itemView: View) {
            R.id.media_subtitle2,
            R.id.media_subtitle3
        )

        val mediaTitlesAndSubtitlesIds = setOf(
            R.id.media_title1,
            R.id.media_title2,
            R.id.media_title3,
            R.id.media_subtitle1,
            R.id.media_subtitle2,
            R.id.media_subtitle3
        )

        val mediaContainersIds = setOf(
            R.id.media_cover1_container,
            R.id.media_cover2_container,
            R.id.media_cover3_container
        )
    }
}
Loading