Merge "Make power menu animaiton smoother" into rvc-dev am: 4a0651a6d7 am: e01a444e7b
Change-Id: Ieb44ae2fd97a74283de7a6bf37846c61190f1d3c
This commit is contained in:
@@ -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 -> {
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user