Loading packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt +22 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.platform.test.annotations.RequiresFlagsDisabled import android.platform.test.annotations.RequiresFlagsEnabled import android.platform.test.flag.junit.CheckFlagsRule import android.platform.test.flag.junit.DeviceFlagsValueProvider import android.view.IRemoteAnimationFinishedCallback import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase Loading @@ -38,10 +39,13 @@ import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.eq import org.mockito.Mock import org.mockito.Mockito.anyInt import org.mockito.Mockito.mock import org.mockito.Mockito.verify import org.mockito.Mockito.verifyNoMoreInteractions import org.mockito.MockitoAnnotations import org.mockito.kotlin.any import org.mockito.kotlin.mock import org.mockito.kotlin.whenever @SmallTest @RunWith(AndroidJUnit4::class) Loading Loading @@ -222,4 +226,22 @@ class WindowManagerLockscreenVisibilityManagerTest : SysuiTestCase() { underTest.setSurfaceBehindVisibility(false) verify(keyguardTransitions).startKeyguardTransition(eq(true), any()) } @Test fun remoteAnimationInstantlyFinished_ifDismissTransitionNotStarted() { val mockedCallback = mock<IRemoteAnimationFinishedCallback>() whenever(keyguardDismissTransitionInteractor.startDismissKeyguardTransition(any())) .thenReturn(false) underTest.onKeyguardGoingAwayRemoteAnimationStart( transit = 0, apps = emptyArray(), wallpapers = emptyArray(), nonApps = emptyArray(), finishedCallback = mockedCallback, ) verify(mockedCallback).onAnimationFinished() verifyNoMoreInteractions(mockedCallback) } } packages/SystemUI/src/com/android/systemui/keyguard/WindowManagerLockscreenVisibilityManager.kt +33 −13 Original line number Diff line number Diff line Loading @@ -156,6 +156,13 @@ constructor( setWmLockscreenState(lockscreenShowing = lockscreenShown) } /** * Called when the keyguard going away remote animation is started, and we have a * RemoteAnimationTarget to animate. * * This is triggered either by this class calling ATMS#keyguardGoingAway, or by WM directly, * such as when an activity with FLAG_DISMISS_KEYGUARD is launched over a dismissible keyguard. */ fun onKeyguardGoingAwayRemoteAnimationStart( @WindowManager.TransitionOldType transit: Int, apps: Array<RemoteAnimationTarget>, Loading @@ -163,20 +170,33 @@ constructor( nonApps: Array<RemoteAnimationTarget>, finishedCallback: IRemoteAnimationFinishedCallback, ) { // Make sure this is true - we set it true when requesting keyguardGoingAway, but there are // cases where WM starts this transition on its own. isKeyguardGoingAway = true // Ensure that we've started a dismiss keyguard transition. WindowManager can start the // going away animation on its own, if an activity launches and then requests dismissing the // keyguard. In this case, this is the first and only signal we'll receive to start // a transition to GONE. This transition needs to start even if we're not provided an app // animation target - it's possible the app is destroyed on creation, etc. but we'll still // be unlocking. // If we weren't expecting the keyguard to be going away, WM triggered this transition. if (!isKeyguardGoingAway) { // Since WM triggered this, we're likely not transitioning to GONE yet. See if we can // start that transition. val startedDismiss = keyguardDismissTransitionInteractor.startDismissKeyguardTransition( reason = "Going away remote animation started" ) if (!startedDismiss) { // If the transition wasn't started, we're already GONE. This can happen with timing // issues, where the remote animation took a long time to start, and something else // caused us to unlock in the meantime. Since we're already GONE, simply end the // remote animatiom immediately. Log.d( TAG, "onKeyguardGoingAwayRemoteAnimationStart: " + "Dismiss transition was not started; we're already GONE. " + "Ending remote animation.", ) finishedCallback.onAnimationFinished() return } isKeyguardGoingAway = true } if (apps.isNotEmpty()) { goingAwayRemoteAnimationFinishedCallback = finishedCallback keyguardSurfaceBehindAnimator.applyParamsToSurface(apps[0]) Loading Loading @@ -278,6 +298,6 @@ constructor( } companion object { private val TAG = WindowManagerLockscreenVisibilityManager::class.java.simpleName private val TAG = "WindowManagerLsVis" } } packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissTransitionInteractor.kt +14 −4 Original line number Diff line number Diff line Loading @@ -48,9 +48,12 @@ constructor( * * This is called exclusively by sources that can authoritatively say we should be unlocked, * including KeyguardSecurityContainerController and WindowManager. * * Returns [false] if the transition was not started, because we're already GONE or we don't * know how to dismiss keyguard from the current state. */ fun startDismissKeyguardTransition(reason: String = "") { if (SceneContainerFlag.isEnabled) return fun startDismissKeyguardTransition(reason: String = ""): Boolean { if (SceneContainerFlag.isEnabled) return false Log.d(TAG, "#startDismissKeyguardTransition(reason=$reason)") val startedState = if (transitionRaceCondition()) { Loading @@ -65,15 +68,22 @@ constructor( AOD -> fromAodTransitionInteractor.dismissAod() DOZING -> fromDozingTransitionInteractor.dismissFromDozing() KeyguardState.OCCLUDED -> fromOccludedTransitionInteractor.dismissFromOccluded() KeyguardState.GONE -> KeyguardState.GONE -> { Log.i( TAG, "Already transitioning to GONE; ignoring startDismissKeyguardTransition.", ) else -> Log.e(TAG, "We don't know how to dismiss keyguard from state $startedState.") return false } else -> { Log.e(TAG, "We don't know how to dismiss keyguard from state $startedState.") return false } } return true } companion object { private val TAG = KeyguardDismissTransitionInteractor::class.simpleName } Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt +22 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.platform.test.annotations.RequiresFlagsDisabled import android.platform.test.annotations.RequiresFlagsEnabled import android.platform.test.flag.junit.CheckFlagsRule import android.platform.test.flag.junit.DeviceFlagsValueProvider import android.view.IRemoteAnimationFinishedCallback import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase Loading @@ -38,10 +39,13 @@ import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.eq import org.mockito.Mock import org.mockito.Mockito.anyInt import org.mockito.Mockito.mock import org.mockito.Mockito.verify import org.mockito.Mockito.verifyNoMoreInteractions import org.mockito.MockitoAnnotations import org.mockito.kotlin.any import org.mockito.kotlin.mock import org.mockito.kotlin.whenever @SmallTest @RunWith(AndroidJUnit4::class) Loading Loading @@ -222,4 +226,22 @@ class WindowManagerLockscreenVisibilityManagerTest : SysuiTestCase() { underTest.setSurfaceBehindVisibility(false) verify(keyguardTransitions).startKeyguardTransition(eq(true), any()) } @Test fun remoteAnimationInstantlyFinished_ifDismissTransitionNotStarted() { val mockedCallback = mock<IRemoteAnimationFinishedCallback>() whenever(keyguardDismissTransitionInteractor.startDismissKeyguardTransition(any())) .thenReturn(false) underTest.onKeyguardGoingAwayRemoteAnimationStart( transit = 0, apps = emptyArray(), wallpapers = emptyArray(), nonApps = emptyArray(), finishedCallback = mockedCallback, ) verify(mockedCallback).onAnimationFinished() verifyNoMoreInteractions(mockedCallback) } }
packages/SystemUI/src/com/android/systemui/keyguard/WindowManagerLockscreenVisibilityManager.kt +33 −13 Original line number Diff line number Diff line Loading @@ -156,6 +156,13 @@ constructor( setWmLockscreenState(lockscreenShowing = lockscreenShown) } /** * Called when the keyguard going away remote animation is started, and we have a * RemoteAnimationTarget to animate. * * This is triggered either by this class calling ATMS#keyguardGoingAway, or by WM directly, * such as when an activity with FLAG_DISMISS_KEYGUARD is launched over a dismissible keyguard. */ fun onKeyguardGoingAwayRemoteAnimationStart( @WindowManager.TransitionOldType transit: Int, apps: Array<RemoteAnimationTarget>, Loading @@ -163,20 +170,33 @@ constructor( nonApps: Array<RemoteAnimationTarget>, finishedCallback: IRemoteAnimationFinishedCallback, ) { // Make sure this is true - we set it true when requesting keyguardGoingAway, but there are // cases where WM starts this transition on its own. isKeyguardGoingAway = true // Ensure that we've started a dismiss keyguard transition. WindowManager can start the // going away animation on its own, if an activity launches and then requests dismissing the // keyguard. In this case, this is the first and only signal we'll receive to start // a transition to GONE. This transition needs to start even if we're not provided an app // animation target - it's possible the app is destroyed on creation, etc. but we'll still // be unlocking. // If we weren't expecting the keyguard to be going away, WM triggered this transition. if (!isKeyguardGoingAway) { // Since WM triggered this, we're likely not transitioning to GONE yet. See if we can // start that transition. val startedDismiss = keyguardDismissTransitionInteractor.startDismissKeyguardTransition( reason = "Going away remote animation started" ) if (!startedDismiss) { // If the transition wasn't started, we're already GONE. This can happen with timing // issues, where the remote animation took a long time to start, and something else // caused us to unlock in the meantime. Since we're already GONE, simply end the // remote animatiom immediately. Log.d( TAG, "onKeyguardGoingAwayRemoteAnimationStart: " + "Dismiss transition was not started; we're already GONE. " + "Ending remote animation.", ) finishedCallback.onAnimationFinished() return } isKeyguardGoingAway = true } if (apps.isNotEmpty()) { goingAwayRemoteAnimationFinishedCallback = finishedCallback keyguardSurfaceBehindAnimator.applyParamsToSurface(apps[0]) Loading Loading @@ -278,6 +298,6 @@ constructor( } companion object { private val TAG = WindowManagerLockscreenVisibilityManager::class.java.simpleName private val TAG = "WindowManagerLsVis" } }
packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissTransitionInteractor.kt +14 −4 Original line number Diff line number Diff line Loading @@ -48,9 +48,12 @@ constructor( * * This is called exclusively by sources that can authoritatively say we should be unlocked, * including KeyguardSecurityContainerController and WindowManager. * * Returns [false] if the transition was not started, because we're already GONE or we don't * know how to dismiss keyguard from the current state. */ fun startDismissKeyguardTransition(reason: String = "") { if (SceneContainerFlag.isEnabled) return fun startDismissKeyguardTransition(reason: String = ""): Boolean { if (SceneContainerFlag.isEnabled) return false Log.d(TAG, "#startDismissKeyguardTransition(reason=$reason)") val startedState = if (transitionRaceCondition()) { Loading @@ -65,15 +68,22 @@ constructor( AOD -> fromAodTransitionInteractor.dismissAod() DOZING -> fromDozingTransitionInteractor.dismissFromDozing() KeyguardState.OCCLUDED -> fromOccludedTransitionInteractor.dismissFromOccluded() KeyguardState.GONE -> KeyguardState.GONE -> { Log.i( TAG, "Already transitioning to GONE; ignoring startDismissKeyguardTransition.", ) else -> Log.e(TAG, "We don't know how to dismiss keyguard from state $startedState.") return false } else -> { Log.e(TAG, "We don't know how to dismiss keyguard from state $startedState.") return false } } return true } companion object { private val TAG = KeyguardDismissTransitionInteractor::class.simpleName } Loading