Don't blur during app launch animations

During app launch, we might poke a hole into the shade window to reveal
the app. We should not blur what's behind the shade, otherwise the app
window would also be blurred.

Also, even when dismissing the shade sliding it, the blur spring would
create an unpleasant feeling.

Test: manual
Test: atest NotificationShadeDepthControllerTest
Test: atest ActivityLaunchAnimatorTest
Test: atest KeyguardViewMediatorTest
Test: atest StatusBarNotificationActivityStarterTest
Fixes: 190086066
Change-Id: Ie5e5df7496eca74ca2715d2df8467636198c60f8
This commit is contained in:
Lucas Dupin
2021-06-03 13:47:56 -07:00
parent d1c9c0785c
commit a48422c324
10 changed files with 47 additions and 37 deletions

View File

@@ -159,6 +159,7 @@ class ActivityLaunchAnimator(
// If we expect an animation, post a timeout to cancel it in case the remote animation is
// never started.
if (willAnimate) {
keyguardHandler.disableKeyguardBlurs()
runner.postTimeout()
// Hide the keyguard using the launch animation instead of the default unlock animation.
@@ -218,6 +219,9 @@ class ActivityLaunchAnimator(
/** Hide the keyguard and animate using [runner]. */
fun hideKeyguardWithAnimation(runner: IRemoteAnimationRunner)
/** Disable window blur so they don't overlap with the window launch animation **/
fun disableKeyguardBlurs()
}
/**

View File

@@ -107,6 +107,7 @@ import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.phone.BiometricUnlockController;
import com.android.systemui.statusbar.phone.DozeParameters;
@@ -237,6 +238,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable,
private final SysuiStatusBarStateController mStatusBarStateController;
private final Executor mUiBgExecutor;
private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
private final Lazy<NotificationShadeDepthController> mNotificationShadeDepthController;
private boolean mSystemReady;
private boolean mBootCompleted;
@@ -807,13 +809,15 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable,
SysuiStatusBarStateController statusBarStateController,
KeyguardStateController keyguardStateController,
Lazy<KeyguardUnlockAnimationController> keyguardUnlockAnimationControllerLazy,
UnlockedScreenOffAnimationController unlockedScreenOffAnimationController) {
UnlockedScreenOffAnimationController unlockedScreenOffAnimationController,
Lazy<NotificationShadeDepthController> notificationShadeDepthController) {
super(context);
mFalsingCollector = falsingCollector;
mLockPatternUtils = lockPatternUtils;
mBroadcastDispatcher = broadcastDispatcher;
mKeyguardViewControllerLazy = statusBarKeyguardViewManagerLazy;
mDismissCallbackRegistry = dismissCallbackRegistry;
mNotificationShadeDepthController = notificationShadeDepthController;
mUiBgExecutor = uiBgExecutor;
mUpdateMonitor = keyguardUpdateMonitor;
mPM = powerManager;
@@ -1654,6 +1658,14 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable,
hideLocked();
}
/**
* Disable notification shade background blurs until the keyguard is dismissed.
* (Used during app launch animations)
*/
public void disableBlursUntilHidden() {
mNotificationShadeDepthController.get().setIgnoreShadeBlurUntilHidden(true);
}
public boolean isSecure() {
return isSecure(KeyguardUpdateMonitor.getCurrentUser());
}

View File

@@ -46,6 +46,7 @@ import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.phone.DozeParameters;
@@ -99,7 +100,8 @@ public class KeyguardModule {
SysuiStatusBarStateController statusBarStateController,
KeyguardStateController keyguardStateController,
Lazy<KeyguardUnlockAnimationController> keyguardUnlockAnimationController,
UnlockedScreenOffAnimationController unlockedScreenOffAnimationController) {
UnlockedScreenOffAnimationController unlockedScreenOffAnimationController,
Lazy<NotificationShadeDepthController> notificationShadeDepthController) {
return new KeyguardViewMediator(
context,
falsingCollector,
@@ -119,7 +121,8 @@ public class KeyguardModule {
statusBarStateController,
keyguardStateController,
keyguardUnlockAnimationController,
unlockedScreenOffAnimationController
unlockedScreenOffAnimationController,
notificationShadeDepthController
);
}

View File

@@ -35,7 +35,6 @@ import com.android.systemui.animation.Interpolators
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.notification.ExpandAnimationParameters
import com.android.systemui.statusbar.phone.BiometricUnlockController
import com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK
import com.android.systemui.statusbar.phone.DozeParameters
@@ -79,7 +78,6 @@ class NotificationShadeDepthController @Inject constructor(
private var notificationAnimator: Animator? = null
private var updateScheduled: Boolean = false
private var shadeExpansion = 0f
private var ignoreShadeBlurUntilHidden: Boolean = false
private var isClosed: Boolean = true
private var isOpen: Boolean = false
private var isBlurred: Boolean = false
@@ -109,18 +107,17 @@ class NotificationShadeDepthController @Inject constructor(
* When launching an app from the shade, the animations progress should affect how blurry the
* shade is, overriding the expansion amount.
*/
var notificationLaunchAnimationParams: ExpandAnimationParameters? = null
var ignoreShadeBlurUntilHidden: Boolean = false
set(value) {
field = value
if (value != null) {
scheduleUpdate()
if (field == value) {
return
}
field = value
scheduleUpdate()
if (shadeSpring.radius == 0 && shadeAnimation.radius == 0) {
return
}
ignoreShadeBlurUntilHidden = true
shadeSpring.animateTo(0)
shadeSpring.finishIfRunning()
@@ -160,8 +157,6 @@ class NotificationShadeDepthController @Inject constructor(
normalizedBlurRadius * ANIMATION_BLUR_FRACTION).toInt()
combinedBlur = max(combinedBlur, blurUtils.blurRadiusOfRatio(qsPanelExpansion))
var shadeRadius = max(combinedBlur, wakeAndUnlockBlurRadius).toFloat()
val launchProgress = notificationLaunchAnimationParams?.linearProgress ?: 0f
shadeRadius *= (1f - launchProgress) * (1f - launchProgress)
if (ignoreShadeBlurUntilHidden) {
if (shadeRadius == 0f) {
@@ -184,7 +179,8 @@ class NotificationShadeDepthController @Inject constructor(
blur = 0
}
blurUtils.applyBlur(blurRoot?.viewRootImpl ?: root.viewRootImpl, blur, scrimsVisible)
val opaque = scrimsVisible && !ignoreShadeBlurUntilHidden
blurUtils.applyBlur(blurRoot?.viewRootImpl ?: root.viewRootImpl, blur, opaque)
val zoomOut = blurUtils.ratioOfBlurRadius(blur)
try {
if (root.isAttachedToWindow && root.windowToken != null) {
@@ -415,8 +411,6 @@ class NotificationShadeDepthController @Inject constructor(
it.println("shadeAnimation: ${shadeAnimation.radius}")
it.println("globalActionsRadius: ${globalActionsSpring.radius}")
it.println("wakeAndUnlockBlur: $wakeAndUnlockBlurRadius")
it.println("notificationLaunchAnimationProgress: " +
"${notificationLaunchAnimationParams?.linearProgress}")
it.println("ignoreShadeBlurUntilHidden: $ignoreShadeBlurUntilHidden")
}
}

View File

@@ -3,7 +3,6 @@ package com.android.systemui.statusbar.notification
import android.view.ViewGroup
import com.android.internal.jank.InteractionJankMonitor
import com.android.systemui.animation.ActivityLaunchAnimator
import com.android.systemui.statusbar.NotificationShadeDepthController
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.stack.NotificationListContainer
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone
@@ -15,7 +14,6 @@ import kotlin.math.max
class NotificationLaunchAnimatorControllerProvider(
private val notificationShadeWindowViewController: NotificationShadeWindowViewController,
private val notificationListContainer: NotificationListContainer,
private val depthController: NotificationShadeDepthController,
private val headsUpManager: HeadsUpManagerPhone
) {
fun getAnimatorController(
@@ -24,7 +22,6 @@ class NotificationLaunchAnimatorControllerProvider(
return NotificationLaunchAnimatorController(
notificationShadeWindowViewController,
notificationListContainer,
depthController,
notification,
headsUpManager
)
@@ -39,7 +36,6 @@ class NotificationLaunchAnimatorControllerProvider(
class NotificationLaunchAnimatorController(
private val notificationShadeWindowViewController: NotificationShadeWindowViewController,
private val notificationListContainer: NotificationListContainer,
private val depthController: NotificationShadeDepthController,
private val notification: ExpandableNotificationRow,
private val headsUpManager: HeadsUpManagerPhone
) : ActivityLaunchAnimator.Controller {
@@ -128,7 +124,6 @@ class NotificationLaunchAnimatorController(
private fun applyParams(params: ExpandAnimationParameters?) {
notification.applyExpandAnimationParams(params)
notificationListContainer.applyExpandAnimationParams(params)
depthController.notificationLaunchAnimationParams = params
}
override fun onLaunchAnimationProgress(

View File

@@ -1424,7 +1424,6 @@ public class StatusBar extends SystemUI implements DemoMode,
mNotificationAnimationProvider = new NotificationLaunchAnimatorControllerProvider(
mNotificationShadeWindowViewController,
mStackScrollerController.getNotificationListContainer(),
mNotificationShadeDepthControllerLazy.get(),
mHeadsUpManager
);
@@ -2122,6 +2121,11 @@ public class StatusBar extends SystemUI implements DemoMode,
mKeyguardViewMediator.hideWithAnimation(runner);
}
@Override
public void disableKeyguardBlurs() {
mMainThreadHandler.post(mKeyguardViewMediator::disableBlursUntilHidden);
}
public boolean isDeviceInVrMode() {
return mPresenter.isDeviceInVrMode();
}

View File

@@ -123,6 +123,7 @@ class ActivityLaunchAnimatorTest : SysuiTestCase() {
waitForIdleSync()
verify(controller).onIntentStarted(willAnimateCaptor.capture())
verify(keyguardHandler).disableKeyguardBlurs()
verify(keyguardHandler).hideKeyguardWithAnimation(any())
assertTrue(willAnimateCaptor.value)
@@ -189,6 +190,10 @@ private class TestLaunchAnimatorKeyguardHandler(
) : ActivityLaunchAnimator.KeyguardHandler {
override fun isOnKeyguard(): Boolean = isOnKeyguard
override fun disableKeyguardBlurs() {
// Do nothing
}
override fun hideKeyguardWithAnimation(runner: IRemoteAnimationRunner) {
// Do nothing.
}

View File

@@ -46,6 +46,7 @@ import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.classifier.FalsingCollectorFake;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -82,6 +83,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
private @Mock DozeParameters mDozeParameters;
private @Mock SysuiStatusBarStateController mStatusBarStateController;
private @Mock KeyguardStateController mKeyguardStateController;
private @Mock NotificationShadeDepthController mNotificationShadeDepthController;
private @Mock KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
private @Mock UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
private DeviceConfigProxy mDeviceConfig = new DeviceConfigProxyFake();
@@ -104,7 +106,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
mPowerManager, mTrustManager, mDeviceConfig, mNavigationModeController,
mKeyguardDisplayManager, mDozeParameters, mStatusBarStateController,
mKeyguardStateController, () -> mKeyguardUnlockAnimationController,
mUnlockedScreenOffAnimationController);
mUnlockedScreenOffAnimationController, () -> mNotificationShadeDepthController);
mViewMediator.start();
}

View File

@@ -27,7 +27,6 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.notification.ExpandAnimationParameters
import com.android.systemui.statusbar.phone.BiometricUnlockController
import com.android.systemui.statusbar.phone.DozeParameters
import com.android.systemui.statusbar.phone.ScrimController
@@ -230,12 +229,10 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() {
}
@Test
fun updateBlurCallback_appLaunchAnimation_overridesZoom() {
fun updateBlurCallback_ignoreShadeBlurUntilHidden_overridesZoom() {
`when`(shadeSpring.radius).thenReturn(maxBlur)
`when`(shadeAnimation.radius).thenReturn(maxBlur)
val animProgress = ExpandAnimationParameters()
animProgress.linearProgress = 1f
notificationShadeDepthController.notificationLaunchAnimationParams = animProgress
notificationShadeDepthController.ignoreShadeBlurUntilHidden = true
notificationShadeDepthController.updateBlurCallback.doFrame(0)
verify(blurUtils).applyBlur(any(), eq(0), eq(false))
}
@@ -256,21 +253,17 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() {
}
@Test
fun setNotificationLaunchAnimationParams_schedulesFrame() {
val animProgress = ExpandAnimationParameters()
animProgress.linearProgress = 0.5f
notificationShadeDepthController.notificationLaunchAnimationParams = animProgress
fun ignoreShadeBlurUntilHidden_schedulesFrame() {
notificationShadeDepthController.ignoreShadeBlurUntilHidden = true
verify(choreographer).postFrameCallback(
eq(notificationShadeDepthController.updateBlurCallback))
}
@Test
fun setNotificationLaunchAnimationParams_whennNull_ignoresIfShadeHasNoBlur() {
val animProgress = ExpandAnimationParameters()
animProgress.linearProgress = 0.5f
fun ignoreShadeBlurUntilHidden_whennNull_ignoresIfShadeHasNoBlur() {
`when`(shadeSpring.radius).thenReturn(0)
`when`(shadeAnimation.radius).thenReturn(0)
notificationShadeDepthController.notificationLaunchAnimationParams = animProgress
notificationShadeDepthController.ignoreShadeBlurUntilHidden = true
verify(shadeSpring, never()).animateTo(anyInt(), any())
verify(shadeAnimation, never()).animateTo(anyInt(), any())
}

View File

@@ -61,7 +61,6 @@ import com.android.systemui.statusbar.NotificationClickNotifier;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.RemoteInputController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
@@ -191,7 +190,6 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
new NotificationLaunchAnimatorControllerProvider(
mock(NotificationShadeWindowViewController.class), mock(
NotificationListContainer.class),
mock(NotificationShadeDepthController.class),
headsUpManager);
mNotificationActivityStarter =