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
This commit is contained in:
Lucas Dupin
2021-06-24 17:15:09 -07:00
parent 598f0602e2
commit 519deb3adf
6 changed files with 32 additions and 39 deletions

View File

@@ -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)

View File

@@ -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() {

View File

@@ -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")
}
}

View File

@@ -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() {

View File

@@ -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.

View File

@@ -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())
}