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

Commit 0d0e4049 authored by Lucas Dupin's avatar Lucas Dupin
Browse files

Removed strong zoom as shade starts to be pulled

Removed steep animation curve when the shade is being pulled, such as
it's not closer to what exists in other system areas, like all apps
drawer and -1.

It was necessary to convert ints to floats, given that conversion was
causing precision loss, making the wallpaper zoom stutter.

Test: pull down drawer over app or launcher
Test: launch apps from QS
Test: change device brightness from QS
Test: atest NotificationShadeDepthControllerTest
Fixes: 195667456
Change-Id: Ibe778fbe3811434dd5123a471eec0d21db1fd09a
parent d6c3d4d5
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -97,7 +97,7 @@ public class GlobalActionsImpl implements GlobalActions, CommandQueue.Callbacks
                int backgroundAlpha = (int) (ScrimController.BUSY_SCRIM_ALPHA * 255);
                background.setAlpha(backgroundAlpha);
                mBlurUtils.applyBlur(d.getWindow().getDecorView().getViewRootImpl(),
                        mBlurUtils.blurRadiusOfRatio(1), backgroundAlpha == 255);
                        (int) mBlurUtils.blurRadiusOfRatio(1), backgroundAlpha == 255);
            } else {
                float backgroundAlpha = mContext.getResources().getFloat(
                        com.android.systemui.R.dimen.shutdown_scrim_behind_alpha);
+6 −6
Original line number Diff line number Diff line
@@ -54,22 +54,22 @@ open class BlurUtils @Inject constructor(
    /**
     * Translates a ratio from 0 to 1 to a blur radius in pixels.
     */
    fun blurRadiusOfRatio(ratio: Float): Int {
    fun blurRadiusOfRatio(ratio: Float): Float {
        if (ratio == 0f) {
            return 0
            return 0f
        }
        return MathUtils.lerp(minBlurRadius.toFloat(), maxBlurRadius.toFloat(), ratio).toInt()
        return MathUtils.lerp(minBlurRadius.toFloat(), maxBlurRadius.toFloat(), ratio)
    }

    /**
     * Translates a blur radius in pixels to a ratio between 0 to 1.
     */
    fun ratioOfBlurRadius(blur: Int): Float {
        if (blur == 0) {
    fun ratioOfBlurRadius(blur: Float): Float {
        if (blur == 0f) {
            return 0f
        }
        return MathUtils.map(minBlurRadius.toFloat(), maxBlurRadius.toFloat(),
                0f /* maxStart */, 1f /* maxStop */, blur.toFloat())
                0f /* maxStart */, 1f /* maxStop */, blur)
    }

    /**
+26 −30
Original line number Diff line number Diff line
@@ -68,7 +68,7 @@ class NotificationShadeDepthController @Inject constructor(
        private const val VELOCITY_SCALE = 100f
        private const val MAX_VELOCITY = 3000f
        private const val MIN_VELOCITY = -MAX_VELOCITY
        private const val INTERACTION_BLUR_FRACTION = 0.4f
        private const val INTERACTION_BLUR_FRACTION = 0.8f
        private const val ANIMATION_BLUR_FRACTION = 1f - INTERACTION_BLUR_FRACTION
        private const val TAG = "DepthController"
    }
@@ -92,8 +92,6 @@ class NotificationShadeDepthController @Inject constructor(
    // Only for dumpsys
    private var lastAppliedBlur = 0

    @VisibleForTesting
    var shadeSpring = DepthAnimation()
    var shadeAnimation = DepthAnimation()

    @VisibleForTesting
@@ -101,12 +99,16 @@ class NotificationShadeDepthController @Inject constructor(
    var brightnessMirrorVisible: Boolean = false
        set(value) {
            field = value
            brightnessMirrorSpring.animateTo(if (value) blurUtils.blurRadiusOfRatio(1f)
            brightnessMirrorSpring.animateTo(if (value) blurUtils.blurRadiusOfRatio(1f).toInt()
                else 0)
        }

    var qsPanelExpansion = 0f
        set(value) {
            if (value.isNaN()) {
                Log.w(TAG, "Invalid qs expansion")
                return
            }
            if (field == value) return
            field = value
            scheduleUpdate()
@@ -134,15 +136,13 @@ class NotificationShadeDepthController @Inject constructor(
            field = value
            scheduleUpdate()

            if (shadeSpring.radius == 0 && shadeAnimation.radius == 0) {
            if (shadeExpansion == 0f && shadeAnimation.radius == 0f) {
                return
            }
            // Do not remove blurs when we're re-enabling them
            if (!value) {
                return
            }
            shadeSpring.animateTo(0)
            shadeSpring.finishIfRunning()

            shadeAnimation.animateTo(0)
            shadeAnimation.finishIfRunning()
@@ -161,7 +161,7 @@ class NotificationShadeDepthController @Inject constructor(
    /**
     * Blur radius of the wake-up animation on this frame.
     */
    private var wakeAndUnlockBlurRadius = 0
    private var wakeAndUnlockBlurRadius = 0f
        set(value) {
            if (field == value) return
            field = value
@@ -174,26 +174,30 @@ class NotificationShadeDepthController @Inject constructor(
    @VisibleForTesting
    val updateBlurCallback = Choreographer.FrameCallback {
        updateScheduled = false
        val normalizedBlurRadius = MathUtils.constrain(shadeAnimation.radius,
                blurUtils.minBlurRadius, blurUtils.maxBlurRadius)
        var combinedBlur = (shadeSpring.radius * INTERACTION_BLUR_FRACTION +
                normalizedBlurRadius * ANIMATION_BLUR_FRACTION).toInt()
        val animationRadius = MathUtils.constrain(shadeAnimation.radius,
                blurUtils.minBlurRadius.toFloat(), blurUtils.maxBlurRadius.toFloat())
        val expansionRadius = blurUtils.blurRadiusOfRatio(
                Interpolators.getNotificationScrimAlpha(
                        if (shouldApplyShadeBlur()) shadeExpansion else 0f, false))
        var combinedBlur = (expansionRadius * INTERACTION_BLUR_FRACTION +
                animationRadius * ANIMATION_BLUR_FRACTION)
        val qsExpandedRatio = qsPanelExpansion * shadeExpansion
        combinedBlur = max(combinedBlur, blurUtils.blurRadiusOfRatio(qsExpandedRatio))
        combinedBlur = max(combinedBlur, blurUtils.blurRadiusOfRatio(transitionToFullShadeProgress))
        var shadeRadius = max(combinedBlur, wakeAndUnlockBlurRadius).toFloat()
        var shadeRadius = max(combinedBlur, wakeAndUnlockBlurRadius)

        if (blursDisabledForAppLaunch) {
            shadeRadius = 0f
        }

        var zoomOut = MathUtils.saturate(blurUtils.ratioOfBlurRadius(shadeRadius))
        var blur = shadeRadius.toInt()

        // Make blur be 0 if it is necessary to stop blur effect.
        if (scrimsVisible) {
            blur = 0
            zoomOut = 0f
        }
        val zoomOut = blurUtils.ratioOfBlurRadius(blur)

        if (!blurUtils.supportsBlursOnWindows()) {
            blur = 0
@@ -266,12 +270,11 @@ class NotificationShadeDepthController @Inject constructor(
        override fun onStateChanged(newState: Int) {
            updateShadeAnimationBlur(
                    shadeExpansion, prevTracking, prevShadeVelocity, prevShadeDirection)
            updateShadeBlur()
            scheduleUpdate()
        }

        override fun onDozingChanged(isDozing: Boolean) {
            if (isDozing) {
                shadeSpring.finishIfRunning()
                shadeAnimation.finishIfRunning()
                brightnessMirrorSpring.finishIfRunning()
            }
@@ -336,7 +339,7 @@ class NotificationShadeDepthController @Inject constructor(
        prevTracking = tracking
        prevTimestamp = timestamp

        updateShadeBlur()
        scheduleUpdate()
    }

    private fun updateShadeAnimationBlur(
@@ -399,15 +402,7 @@ class NotificationShadeDepthController @Inject constructor(
        }

        shadeAnimation.setStartVelocity(velocity)
        shadeAnimation.animateTo(blurUtils.blurRadiusOfRatio(targetBlurNormalized))
    }

    private fun updateShadeBlur() {
        var newBlur = 0
        if (shouldApplyShadeBlur()) {
            newBlur = blurUtils.blurRadiusOfRatio(shadeExpansion)
        }
        shadeSpring.animateTo(newBlur)
        shadeAnimation.animateTo(blurUtils.blurRadiusOfRatio(targetBlurNormalized).toInt())
    }

    private fun scheduleUpdate(viewToBlur: View? = null) {
@@ -433,7 +428,8 @@ class NotificationShadeDepthController @Inject constructor(
        IndentingPrintWriter(pw, "  ").let {
            it.println("StatusBarWindowBlurController:")
            it.increaseIndent()
            it.println("shadeRadius: ${shadeSpring.radius}")
            it.println("shadeExpansion: $shadeExpansion")
            it.println("shouldApplyShaeBlur: ${shouldApplyShadeBlur()}")
            it.println("shadeAnimation: ${shadeAnimation.radius}")
            it.println("brightnessMirrorRadius: ${brightnessMirrorSpring.radius}")
            it.println("wakeAndUnlockBlur: $wakeAndUnlockBlurRadius")
@@ -452,7 +448,7 @@ class NotificationShadeDepthController @Inject constructor(
        /**
         * Blur radius visible on the UI, in pixels.
         */
        var radius = 0
        var radius = 0f

        /**
         * Depth ratio of the current blur radius.
@@ -473,12 +469,12 @@ class NotificationShadeDepthController @Inject constructor(
        private var springAnimation = SpringAnimation(this, object :
                FloatPropertyCompat<DepthAnimation>("blurRadius") {
            override fun setValue(rect: DepthAnimation?, value: Float) {
                radius = value.toInt()
                radius = value
                scheduleUpdate(view)
            }

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

+15 −22
Original line number Diff line number Diff line
@@ -69,7 +69,6 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() {
    @Mock private lateinit var root: View
    @Mock private lateinit var viewRootImpl: ViewRootImpl
    @Mock private lateinit var windowToken: IBinder
    @Mock private lateinit var shadeSpring: NotificationShadeDepthController.DepthAnimation
    @Mock private lateinit var shadeAnimation: NotificationShadeDepthController.DepthAnimation
    @Mock private lateinit var brightnessSpring: NotificationShadeDepthController.DepthAnimation
    @Mock private lateinit var listener: NotificationShadeDepthController.DepthListener
@@ -89,10 +88,10 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() {
        `when`(root.isAttachedToWindow).thenReturn(true)
        `when`(statusBarStateController.state).then { statusBarState }
        `when`(blurUtils.blurRadiusOfRatio(anyFloat())).then { answer ->
            (answer.arguments[0] as Float * maxBlur).toInt()
            answer.arguments[0] as Float * maxBlur.toFloat()
        }
        `when`(blurUtils.ratioOfBlurRadius(anyInt())).then { answer ->
            answer.arguments[0] as Int / maxBlur.toFloat()
        `when`(blurUtils.ratioOfBlurRadius(anyFloat())).then { answer ->
            answer.arguments[0] as Float / maxBlur.toFloat()
        }
        `when`(blurUtils.supportsBlursOnWindows()).thenReturn(true)
        `when`(blurUtils.maxBlurRadius).thenReturn(maxBlur)
@@ -102,7 +101,6 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() {
                statusBarStateController, blurUtils, biometricUnlockController,
                keyguardStateController, choreographer, wallpaperManager,
                notificationShadeWindowController, dozeParameters, dumpManager)
        notificationShadeDepthController.shadeSpring = shadeSpring
        notificationShadeDepthController.shadeAnimation = shadeAnimation
        notificationShadeDepthController.brightnessMirrorSpring = brightnessSpring
        notificationShadeDepthController.root = root
@@ -123,7 +121,6 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() {
    fun onPanelExpansionChanged_apliesBlur_ifShade() {
        notificationShadeDepthController.onPanelExpansionChanged(1f /* expansion */,
                false /* tracking */)
        verify(shadeSpring).animateTo(eq(maxBlur), any())
        verify(shadeAnimation).animateTo(eq(maxBlur), any())
    }

@@ -172,12 +169,10 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() {
    @Test
    fun onStateChanged_reevalutesBlurs_ifSameRadiusAndNewState() {
        onPanelExpansionChanged_apliesBlur_ifShade()
        clearInvocations(shadeSpring)
        clearInvocations(shadeAnimation)
        clearInvocations(choreographer)

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

@@ -186,7 +181,7 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() {
        notificationShadeDepthController.qsPanelExpansion = 1f
        notificationShadeDepthController.onPanelExpansionChanged(0.5f, tracking = false)
        notificationShadeDepthController.updateBlurCallback.doFrame(0)
        verify(blurUtils).applyBlur(any(), eq(maxBlur / 2), eq(false))
        verify(blurUtils).applyBlur(any(), anyInt(), eq(false))
    }

    @Test
@@ -207,10 +202,10 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() {
    fun setFullShadeTransition_appliesBlur_onlyIfSupported() {
        reset(blurUtils)
        `when`(blurUtils.blurRadiusOfRatio(anyFloat())).then { answer ->
            (answer.arguments[0] as Float * maxBlur).toInt()
            answer.arguments[0] as Float * maxBlur
        }
        `when`(blurUtils.ratioOfBlurRadius(anyInt())).then { answer ->
            answer.arguments[0] as Int / maxBlur.toFloat()
        `when`(blurUtils.ratioOfBlurRadius(anyFloat())).then { answer ->
            answer.arguments[0] as Float / maxBlur.toFloat()
        }
        `when`(blurUtils.maxBlurRadius).thenReturn(maxBlur)
        `when`(blurUtils.maxBlurRadius).thenReturn(maxBlur)
@@ -239,16 +234,16 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() {

    @Test
    fun updateBlurCallback_setsBlur_whenExpanded() {
        `when`(shadeSpring.radius).thenReturn(maxBlur)
        `when`(shadeAnimation.radius).thenReturn(maxBlur)
        notificationShadeDepthController.onPanelExpansionChanged(1f, false)
        `when`(shadeAnimation.radius).thenReturn(maxBlur.toFloat())
        notificationShadeDepthController.updateBlurCallback.doFrame(0)
        verify(blurUtils).applyBlur(any(), eq(maxBlur), eq(false))
    }

    @Test
    fun updateBlurCallback_ignoreShadeBlurUntilHidden_overridesZoom() {
        `when`(shadeSpring.radius).thenReturn(maxBlur)
        `when`(shadeAnimation.radius).thenReturn(maxBlur)
        notificationShadeDepthController.onPanelExpansionChanged(1f, false)
        `when`(shadeAnimation.radius).thenReturn(maxBlur.toFloat())
        notificationShadeDepthController.blursDisabledForAppLaunch = true
        notificationShadeDepthController.updateBlurCallback.doFrame(0)
        verify(blurUtils).applyBlur(any(), eq(0), eq(false))
@@ -293,8 +288,8 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() {
        // Brightness mirror is fully visible
        `when`(brightnessSpring.ratio).thenReturn(1f)
        // And shade is blurred
        `when`(shadeSpring.radius).thenReturn(maxBlur)
        `when`(shadeAnimation.radius).thenReturn(maxBlur)
        notificationShadeDepthController.onPanelExpansionChanged(1f, false)
        `when`(shadeAnimation.radius).thenReturn(maxBlur.toFloat())

        notificationShadeDepthController.updateBlurCallback.doFrame(0)
        verify(notificationShadeWindowController).setBackgroundBlurRadius(eq(0))
@@ -304,10 +299,8 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() {

    @Test
    fun ignoreShadeBlurUntilHidden_whennNull_ignoresIfShadeHasNoBlur() {
        `when`(shadeSpring.radius).thenReturn(0)
        `when`(shadeAnimation.radius).thenReturn(0)
        `when`(shadeAnimation.radius).thenReturn(0f)
        notificationShadeDepthController.blursDisabledForAppLaunch = true
        verify(shadeSpring, never()).animateTo(anyInt(), any())
        verify(shadeAnimation, never()).animateTo(anyInt(), any())
    }
}
 No newline at end of file