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:
@@ -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()
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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 =
|
||||
|
||||
Reference in New Issue
Block a user