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
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user