Merge "Make power menu animaiton smoother" into rvc-dev am: 4a0651a6d7 am: e01a444e7b

Change-Id: Ieb44ae2fd97a74283de7a6bf37846c61190f1d3c
This commit is contained in:
Lucas Dupin
2020-03-25 01:31:32 +00:00
committed by Automerger Merge Worker
3 changed files with 83 additions and 59 deletions

View File

@@ -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 -> {

View File

@@ -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()
}
}
}
}

View File

@@ -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 {