From 519deb3adf59f9f31d4d63de5f51840e7bc7a2ae Mon Sep 17 00:00:00 2001 From: Lucas Dupin Date: Thu, 24 Jun 2021 17:15:09 -0700 Subject: [PATCH] Fix issue where window would be marked as opaque When launching an app, we need to keep the window marked as transparent until the animation is over, otherwise the app window won't be visible. Test: manual Test: atest NotificationShadeDepthControllerTest Test: atest ActivityLaunchAnimatorTest Fixes: 191874111 Change-Id: Id075b802c72d99ed457ab6e2f9dd97e1bc46a01a --- .../animation/ActivityLaunchAnimator.kt | 7 ++-- .../keyguard/KeyguardViewMediator.java | 4 +-- .../NotificationShadeDepthController.kt | 18 +++++------ .../systemui/statusbar/phone/StatusBar.java | 4 +-- .../animation/ActivityLaunchAnimatorTest.kt | 32 +++++++------------ .../NotificationShadeDepthControllerTest.kt | 6 ++-- 6 files changed, 32 insertions(+), 39 deletions(-) diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt index 2579e7084e080..ac9298dc9e899 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt @@ -159,7 +159,6 @@ 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. @@ -220,8 +219,8 @@ 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() + /** Enable/disable window blur so they don't overlap with the window launch animation **/ + fun setBlursDisabledForAppLaunch(disabled: Boolean) } /** @@ -491,6 +490,7 @@ class ActivityLaunchAnimator( animator.addListener(object : AnimatorListenerAdapter() { override fun onAnimationStart(animation: Animator?, isReverse: Boolean) { Log.d(TAG, "Animation started") + keyguardHandler.setBlursDisabledForAppLaunch(true) controller.onLaunchAnimationStart(isExpandingFullyAbove) // Add the drawable to the launch container overlay. Overlays always draw @@ -501,6 +501,7 @@ class ActivityLaunchAnimator( override fun onAnimationEnd(animation: Animator?) { Log.d(TAG, "Animation ended") + keyguardHandler.setBlursDisabledForAppLaunch(false) iCallback?.invoke() controller.onLaunchAnimationEnd(isExpandingFullyAbove) launchContainerOverlay.remove(windowBackgroundLayer) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 88e9f69620ed0..c6fd20ebda6e3 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -1677,8 +1677,8 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, * Disable notification shade background blurs until the keyguard is dismissed. * (Used during app launch animations) */ - public void disableBlursUntilHidden() { - mNotificationShadeDepthController.get().setIgnoreShadeBlurUntilHidden(true); + public void setBlursDisabledForAppLaunch(boolean disabled) { + mNotificationShadeDepthController.get().setBlursDisabledForAppLaunch(disabled); } public boolean isSecure() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt index f03a9a8f3589c..65d8c419df75e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt @@ -126,7 +126,7 @@ 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 ignoreShadeBlurUntilHidden: Boolean = false + var blursDisabledForAppLaunch: Boolean = false set(value) { if (field == value) { return @@ -137,6 +137,10 @@ class NotificationShadeDepthController @Inject constructor( if (shadeSpring.radius == 0 && shadeAnimation.radius == 0) { return } + // Do not remove blurs when we're re-enabling them + if (!value) { + return + } shadeSpring.animateTo(0) shadeSpring.finishIfRunning() @@ -178,12 +182,8 @@ class NotificationShadeDepthController @Inject constructor( combinedBlur = max(combinedBlur, blurUtils.blurRadiusOfRatio(transitionToFullShadeProgress)) var shadeRadius = max(combinedBlur, wakeAndUnlockBlurRadius).toFloat() - if (ignoreShadeBlurUntilHidden) { - if (shadeRadius == 0f) { - ignoreShadeBlurUntilHidden = false - } else { - shadeRadius = 0f - } + if (blursDisabledForAppLaunch) { + shadeRadius = 0f } // Home controls have black background, this means that we should not have blur when they @@ -203,7 +203,7 @@ class NotificationShadeDepthController @Inject constructor( // Brightness slider removes blur, but doesn't affect zooms blur = (blur * (1f - brightnessMirrorSpring.ratio)).toInt() - val opaque = scrimsVisible && !ignoreShadeBlurUntilHidden + val opaque = scrimsVisible && !blursDisabledForAppLaunch blurUtils.applyBlur(blurRoot?.viewRootImpl ?: root.viewRootImpl, blur, opaque) try { if (root.isAttachedToWindow && root.windowToken != null) { @@ -440,7 +440,7 @@ class NotificationShadeDepthController @Inject constructor( it.println("globalActionsRadius: ${globalActionsSpring.radius}") it.println("brightnessMirrorRadius: ${brightnessMirrorSpring.radius}") it.println("wakeAndUnlockBlur: $wakeAndUnlockBlurRadius") - it.println("ignoreShadeBlurUntilHidden: $ignoreShadeBlurUntilHidden") + it.println("blursDisabledForAppLaunch: $blursDisabledForAppLaunch") } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 3f07785520cf7..53394c31940e2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -2112,8 +2112,8 @@ public class StatusBar extends SystemUI implements DemoMode, } @Override - public void disableKeyguardBlurs() { - mMainThreadHandler.post(mKeyguardViewMediator::disableBlursUntilHidden); + public void setBlursDisabledForAppLaunch(boolean disabled) { + mKeyguardViewMediator.setBlursDisabledForAppLaunch(disabled); } public boolean isDeviceInVrMode() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt index 2c7d291033b3d..d01cdd45181f6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt @@ -11,7 +11,6 @@ import android.os.Looper import android.testing.AndroidTestingRunner import android.testing.TestableLooper.RunWithLooper import android.view.IRemoteAnimationFinishedCallback -import android.view.IRemoteAnimationRunner import android.view.RemoteAnimationAdapter import android.view.RemoteAnimationTarget import android.view.SurfaceControl @@ -20,19 +19,21 @@ import android.widget.LinearLayout import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.util.mockito.any +import com.android.systemui.util.mockito.eq import junit.framework.Assert.assertFalse import junit.framework.Assert.assertNotNull import junit.framework.Assert.assertNull import junit.framework.Assert.assertTrue import junit.framework.AssertionFailedError +import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentCaptor import org.mockito.ArgumentMatchers.anyBoolean import org.mockito.Mock +import org.mockito.Mockito.`when` import org.mockito.Mockito.never -import org.mockito.Mockito.spy import org.mockito.Mockito.verify import org.mockito.Spy import org.mockito.junit.MockitoJUnit @@ -43,13 +44,18 @@ import kotlin.concurrent.thread @RunWithLooper class ActivityLaunchAnimatorTest : SysuiTestCase() { private val launchContainer = LinearLayout(mContext) - private val keyguardHandler = TestLaunchAnimatorKeyguardHandler(isOnKeyguard = false) + @Mock lateinit var keyguardHandler: ActivityLaunchAnimator.KeyguardHandler @Spy private val controller = TestLaunchAnimatorController(launchContainer) @Mock lateinit var iCallback: IRemoteAnimationFinishedCallback - private val activityLaunchAnimator = ActivityLaunchAnimator(keyguardHandler, mContext) + private lateinit var activityLaunchAnimator: ActivityLaunchAnimator @get:Rule val rule = MockitoJUnit.rule() + @Before + fun setup() { + activityLaunchAnimator = ActivityLaunchAnimator(keyguardHandler, mContext) + } + private fun startIntentWithAnimation( animator: ActivityLaunchAnimator = this.activityLaunchAnimator, controller: ActivityLaunchAnimator.Controller? = this.controller, @@ -110,7 +116,7 @@ class ActivityLaunchAnimatorTest : SysuiTestCase() { @Test fun animatesIfActivityIsAlreadyOpenAndIsOnKeyguard() { - val keyguardHandler = spy(TestLaunchAnimatorKeyguardHandler(isOnKeyguard = true)) + `when`(keyguardHandler.isOnKeyguard()).thenReturn(true) val animator = ActivityLaunchAnimator(keyguardHandler, context) val willAnimateCaptor = ArgumentCaptor.forClass(Boolean::class.java) @@ -123,7 +129,6 @@ class ActivityLaunchAnimatorTest : SysuiTestCase() { waitForIdleSync() verify(controller).onIntentStarted(willAnimateCaptor.capture()) - verify(keyguardHandler).disableKeyguardBlurs() verify(keyguardHandler).hideKeyguardWithAnimation(any()) assertTrue(willAnimateCaptor.value) @@ -166,6 +171,7 @@ class ActivityLaunchAnimatorTest : SysuiTestCase() { val runner = activityLaunchAnimator.createRunner(controller) runner.onAnimationStart(0, arrayOf(fakeWindow()), emptyArray(), emptyArray(), iCallback) waitForIdleSync() + verify(keyguardHandler).setBlursDisabledForAppLaunch(eq(true)) verify(controller).onLaunchAnimationStart(anyBoolean()) } @@ -185,20 +191,6 @@ class ActivityLaunchAnimatorTest : SysuiTestCase() { } } -private class TestLaunchAnimatorKeyguardHandler( - private val isOnKeyguard: Boolean -) : ActivityLaunchAnimator.KeyguardHandler { - override fun isOnKeyguard(): Boolean = isOnKeyguard - - override fun disableKeyguardBlurs() { - // Do nothing - } - - override fun hideKeyguardWithAnimation(runner: IRemoteAnimationRunner) { - // Do nothing. - } -} - /** * A simple implementation of [ActivityLaunchAnimator.Controller] which throws if it is called * outside of the main thread. diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt index 60b38892e7767..045b14b760700 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt @@ -254,7 +254,7 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() { fun updateBlurCallback_ignoreShadeBlurUntilHidden_overridesZoom() { `when`(shadeSpring.radius).thenReturn(maxBlur) `when`(shadeAnimation.radius).thenReturn(maxBlur) - notificationShadeDepthController.ignoreShadeBlurUntilHidden = true + notificationShadeDepthController.blursDisabledForAppLaunch = true notificationShadeDepthController.updateBlurCallback.doFrame(0) verify(blurUtils).applyBlur(any(), eq(0), eq(false)) } @@ -276,7 +276,7 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() { @Test fun ignoreShadeBlurUntilHidden_schedulesFrame() { - notificationShadeDepthController.ignoreShadeBlurUntilHidden = true + notificationShadeDepthController.blursDisabledForAppLaunch = true verify(choreographer).postFrameCallback( eq(notificationShadeDepthController.updateBlurCallback)) } @@ -311,7 +311,7 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() { fun ignoreShadeBlurUntilHidden_whennNull_ignoresIfShadeHasNoBlur() { `when`(shadeSpring.radius).thenReturn(0) `when`(shadeAnimation.radius).thenReturn(0) - notificationShadeDepthController.ignoreShadeBlurUntilHidden = true + notificationShadeDepthController.blursDisabledForAppLaunch = true verify(shadeSpring, never()).animateTo(anyInt(), any()) verify(shadeAnimation, never()).animateTo(anyInt(), any()) }