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

Commit 4a0651a6 authored by Lucas Dupin's avatar Lucas Dupin Committed by Android (Google) Code Review
Browse files

Merge "Make power menu animaiton smoother" into rvc-dev

parents 3b4d9c9f b079daa1
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -1849,7 +1849,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
                    .alpha(1)
                    .translationX(0)
                    .translationY(0)
                    .setDuration(300)
                    .setDuration(450)
                    .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
                    .setUpdateListener(animation -> {
                        float animatedValue = animation.getAnimatedFraction();
@@ -1878,7 +1878,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
                    .alpha(0)
                    .translationX(mGlobalActionsLayout.getAnimationOffsetX())
                    .translationY(mGlobalActionsLayout.getAnimationOffsetY())
                    .setDuration(300)
                    .setDuration(550)
                    .withEndAction(this::completeDismiss)
                    .setInterpolator(new LogAccelerateInterpolator())
                    .setUpdateListener(animation -> {
+68 −49
Original line number Diff line number Diff line
@@ -67,32 +67,9 @@ class NotificationShadeDepthController @Inject constructor(
    private var updateScheduled: Boolean = false
    private var shadeExpansion = 0f
    @VisibleForTesting
    var shadeSpring = SpringAnimation(this, object :
            FloatPropertyCompat<NotificationShadeDepthController>("shadeBlurRadius") {
        override fun setValue(rect: NotificationShadeDepthController?, value: Float) {
            shadeBlurRadius = value.toInt()
        }

        override fun getValue(rect: NotificationShadeDepthController?): Float {
            return shadeBlurRadius.toFloat()
        }
    })
    private val zoomInterpolator = Interpolators.ACCELERATE_DECELERATE

    /**
     * Radius that we're animating to.
     */
    private var pendingShadeBlurRadius = -1

    /**
     * Shade blur radius on the current frame.
     */
    private var shadeBlurRadius = 0
        set(value) {
            if (field == value) return
            field = value
            scheduleUpdate()
        }
    var shadeSpring = DepthAnimation()
    @VisibleForTesting
    var globalActionsSpring = DepthAnimation()

    /**
     * Blur radius of the wake-up animation on this frame.
@@ -103,7 +80,6 @@ class NotificationShadeDepthController @Inject constructor(
            field = value
            scheduleUpdate()
        }
    private var globalDialogVisibility = 0f

    /**
     * Callback that updates the window blur value and is called only once per frame.
@@ -111,12 +87,9 @@ class NotificationShadeDepthController @Inject constructor(
    private val updateBlurCallback = Choreographer.FrameCallback {
        updateScheduled = false

        val blur = max(shadeBlurRadius,
                max(wakeAndUnlockBlurRadius, blurUtils.blurRadiusOfRatio(globalDialogVisibility)))
        val blur = max(max(shadeSpring.radius, wakeAndUnlockBlurRadius), globalActionsSpring.radius)
        blurUtils.applyBlur(blurRoot?.viewRootImpl ?: root.viewRootImpl, blur)
        val rawZoom = max(blurUtils.ratioOfBlurRadius(blur), globalDialogVisibility)
        wallpaperManager.setWallpaperZoomOut(root.windowToken,
                zoomInterpolator.getInterpolation(rawZoom))
        wallpaperManager.setWallpaperZoomOut(root.windowToken, blurUtils.ratioOfBlurRadius(blur))
        notificationShadeWindowController.setBackgroundBlurRadius(blur)
    }

@@ -163,8 +136,9 @@ class NotificationShadeDepthController @Inject constructor(
        }

        override fun onDozingChanged(isDozing: Boolean) {
            if (isDozing && shadeSpring.isRunning) {
                shadeSpring.skipToEnd()
            if (isDozing) {
                shadeSpring.finishIfRunning()
                globalActionsSpring.finishIfRunning()
            }
        }
    }
@@ -174,10 +148,6 @@ class NotificationShadeDepthController @Inject constructor(
        if (WAKE_UP_ANIMATION_ENABLED) {
            keyguardStateController.addCallback(keyguardStateCallback)
        }
        shadeSpring.spring = SpringForce(0.0f)
        shadeSpring.spring.dampingRatio = SpringForce.DAMPING_RATIO_NO_BOUNCY
        shadeSpring.spring.stiffness = SpringForce.STIFFNESS_LOW
        shadeSpring.addEndListener { _, _, _, _ -> pendingShadeBlurRadius = -1 }
        statusBarStateController.addCallback(statusBarStateCallback)
    }

@@ -198,11 +168,7 @@ class NotificationShadeDepthController @Inject constructor(
            newBlur = blurUtils.blurRadiusOfRatio(shadeExpansion)
        }

        if (pendingShadeBlurRadius == newBlur) {
            return
        }
        pendingShadeBlurRadius = newBlur
        shadeSpring.animateToFinalPosition(newBlur.toFloat())
        shadeSpring.animateTo(newBlur)
    }

    private fun scheduleUpdate(viewToBlur: View? = null) {
@@ -215,19 +181,72 @@ class NotificationShadeDepthController @Inject constructor(
    }

    fun updateGlobalDialogVisibility(visibility: Float, dialogView: View) {
        if (visibility == globalDialogVisibility) {
            return
        }
        globalDialogVisibility = visibility
        scheduleUpdate(dialogView)
        globalActionsSpring.animateTo(blurUtils.blurRadiusOfRatio(visibility), dialogView)
    }

    override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
        IndentingPrintWriter(pw, "  ").let {
            it.println("StatusBarWindowBlurController:")
            it.increaseIndent()
            it.println("shadeBlurRadius: $shadeBlurRadius")
            it.println("shadeRadius: ${shadeSpring.radius}")
            it.println("globalActionsRadius: ${globalActionsSpring.radius}")
            it.println("wakeAndUnlockBlur: $wakeAndUnlockBlurRadius")
        }
    }

    /**
     * Animation helper that smoothly animates the depth using a spring and deals with frame
     * invalidation.
     */
    inner class DepthAnimation() {
        /**
         * Blur radius visible on the UI, in pixels.
         */
        var radius = 0
            private set

        /**
         * Radius that we're animating to.
         */
        private var pendingRadius = -1

        /**
         * View on {@link Surface} that wants depth.
         */
        private var view: View? = null

        private var springAnimation = SpringAnimation(this, object :
            FloatPropertyCompat<DepthAnimation>("blurRadius") {
            override fun setValue(rect: DepthAnimation?, value: Float) {
                radius = value.toInt()
                scheduleUpdate(view)
            }

            override fun getValue(rect: DepthAnimation?): Float {
                return radius.toFloat()
            }
        })

        init {
            springAnimation.spring = SpringForce(0.0f)
            springAnimation.spring.dampingRatio = SpringForce.DAMPING_RATIO_NO_BOUNCY
            springAnimation.spring.stiffness = SpringForce.STIFFNESS_MEDIUM
            springAnimation.addEndListener { _, _, _, _ -> pendingRadius = -1 }
        }

        fun animateTo(newRadius: Int, viewToBlur: View? = null) {
            if (pendingRadius == newRadius && view == viewToBlur) {
                return
            }
            view = viewToBlur
            pendingRadius = newRadius
            springAnimation.animateToFinalPosition(newRadius.toFloat())
        }

        fun finishIfRunning() {
            if (springAnimation.isRunning) {
                springAnimation.skipToEnd()
            }
        }
    }
}
+13 −8
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@ import android.testing.TestableLooper.RunWithLooper
import android.view.Choreographer
import android.view.View
import android.view.ViewRootImpl
import androidx.dynamicanimation.animation.SpringAnimation
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
@@ -35,10 +34,14 @@ import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers.any
import org.mockito.ArgumentMatchers.eq
import org.mockito.Mock
import org.mockito.Mockito.*
import org.mockito.Mockito.`when`
import org.mockito.Mockito.any
import org.mockito.Mockito.anyFloat
import org.mockito.Mockito.anyString
import org.mockito.Mockito.clearInvocations
import org.mockito.Mockito.verify
import org.mockito.junit.MockitoJUnit

@RunWith(AndroidTestingRunner::class)
@@ -56,7 +59,8 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() {
    @Mock private lateinit var dumpManager: DumpManager
    @Mock private lateinit var root: View
    @Mock private lateinit var viewRootImpl: ViewRootImpl
    @Mock private lateinit var shadeSpring: SpringAnimation
    @Mock private lateinit var shadeSpring: NotificationShadeDepthController.DepthAnimation
    @Mock private lateinit var globalActionsSpring: NotificationShadeDepthController.DepthAnimation
    @JvmField @Rule val mockitoRule = MockitoJUnit.rule()

    private lateinit var statusBarStateListener: StatusBarStateController.StateListener
@@ -76,6 +80,7 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() {
                keyguardStateController, choreographer, wallpaperManager,
                notificationShadeWindowController, dumpManager)
        notificationShadeDepthController.shadeSpring = shadeSpring
        notificationShadeDepthController.globalActionsSpring = globalActionsSpring
        notificationShadeDepthController.root = root

        val captor = ArgumentCaptor.forClass(StatusBarStateController.StateListener::class.java)
@@ -92,7 +97,7 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() {
    fun onPanelExpansionChanged_apliesBlur_ifShade() {
        notificationShadeDepthController.onPanelExpansionChanged(1f /* expansion */,
                false /* tracking */)
        verify(shadeSpring).animateToFinalPosition(eq(maxBlur.toFloat()))
        verify(shadeSpring).animateTo(eq(maxBlur), any())
    }

    @Test
@@ -102,13 +107,13 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() {

        statusBarState = StatusBarState.KEYGUARD
        statusBarStateListener.onStateChanged(statusBarState)
        verify(shadeSpring).animateToFinalPosition(eq(0f))
        verify(shadeSpring).animateTo(eq(0), any())
    }

    @Test
    fun updateGlobalDialogVisibility_schedulesUpdate() {
    fun updateGlobalDialogVisibility_appliesBlur() {
        notificationShadeDepthController.updateGlobalDialogVisibility(0.5f, root)
        verify(choreographer).postFrameCallback(any())
        verify(globalActionsSpring).animateTo(eq(maxBlur / 2), safeEq(root))
    }

    private fun <T : Any> safeEq(value: T): T {