Merge cherrypicks of [16691349] into sc-v2-release.

Change-Id: Ic38459ae48b114728380cc232acb7d9082d9be8b
This commit is contained in:
Android Build Coastguard Worker
2022-01-26 21:39:59 +00:00
2 changed files with 95 additions and 8 deletions

View File

@@ -6,6 +6,7 @@ import android.animation.ValueAnimator
import android.content.Context
import android.database.ContentObserver
import android.os.Handler
import android.os.PowerManager
import android.provider.Settings
import android.view.Surface
import android.view.View
@@ -50,9 +51,10 @@ class UnlockedScreenOffAnimationController @Inject constructor(
private val keyguardViewMediatorLazy: dagger.Lazy<KeyguardViewMediator>,
private val keyguardStateController: KeyguardStateController,
private val dozeParameters: dagger.Lazy<DozeParameters>,
private val globalSettings: GlobalSettings
private val globalSettings: GlobalSettings,
private val powerManager: PowerManager,
private val handler: Handler = Handler()
) : WakefulnessLifecycle.Observer {
private val handler = Handler()
private lateinit var statusBar: StatusBar
private lateinit var lightRevealScrim: LightRevealScrim
@@ -205,10 +207,18 @@ class UnlockedScreenOffAnimationController @Inject constructor(
lightRevealAnimationPlaying = true
lightRevealAnimator.start()
handler.postDelayed({
aodUiAnimationPlaying = true
// Only run this callback if the device is sleeping (not interactive). This callback
// is removed in onStartedWakingUp, but since that event is asynchronously
// dispatched, a race condition could make it possible for this callback to be run
// as the device is waking up. That results in the AOD UI being shown while we wake
// up, with unpredictable consequences.
if (!powerManager.isInteractive) {
aodUiAnimationPlaying = true
// Show AOD. That'll cause the KeyguardVisibilityHelper to call #animateInKeyguard.
statusBar.notificationPanelViewController.showAodUi()
// Show AOD. That'll cause the KeyguardVisibilityHelper to call
// #animateInKeyguard.
statusBar.notificationPanelViewController.showAodUi()
}
}, (ANIMATE_IN_KEYGUARD_DELAY * animatorDurationScale).toLong())
} else {
decidedToAnimateGoingToSleep = false

View File

@@ -17,6 +17,8 @@
package com.android.systemui.statusbar.phone
import android.animation.Animator
import android.os.Handler
import android.os.PowerManager
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import android.view.View
@@ -28,13 +30,20 @@ import com.android.systemui.statusbar.LightRevealScrim
import com.android.systemui.statusbar.StatusBarStateControllerImpl
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.settings.GlobalSettings
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.`when`
import org.mockito.Mockito.anyLong
import org.mockito.Mockito.mockingDetails
import org.mockito.Mockito.never
import org.mockito.Mockito.spy
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@SmallTest
@@ -52,13 +61,19 @@ class UnlockedScreenOffAnimationControllerTest : SysuiTestCase() {
@Mock
private lateinit var globalSettings: GlobalSettings
@Mock
private lateinit var statusbar: StatusBar
private lateinit var statusBar: StatusBar
@Mock
private lateinit var notificationPanelViewController: NotificationPanelViewController
@Mock
private lateinit var lightRevealScrim: LightRevealScrim
@Mock
private lateinit var wakefulnessLifecycle: WakefulnessLifecycle
@Mock
private lateinit var statusBarStateController: StatusBarStateControllerImpl
@Mock
private lateinit var powerManager: PowerManager
@Mock
private lateinit var handler: Handler
@Before
fun setUp() {
@@ -71,9 +86,24 @@ class UnlockedScreenOffAnimationControllerTest : SysuiTestCase() {
dagger.Lazy<KeyguardViewMediator> { keyguardViewMediator },
keyguardStateController,
dagger.Lazy<DozeParameters> { dozeParameters },
globalSettings
globalSettings,
powerManager,
handler = handler
)
controller.initialize(statusbar, lightRevealScrim)
controller.initialize(statusBar, lightRevealScrim)
`when`(statusBar.notificationPanelViewController).thenReturn(
notificationPanelViewController)
// Screen off does not run if the panel is expanded, so we should say it's collapsed to test
// screen off.
`when`(notificationPanelViewController.isFullyCollapsed).thenReturn(true)
}
@After
fun cleanUp() {
// Tell the screen off controller to cancel the animations and clean up its state, or
// subsequent tests will act unpredictably as the animator continues running.
controller.onStartedWakingUp()
}
@Test
@@ -89,4 +119,51 @@ class UnlockedScreenOffAnimationControllerTest : SysuiTestCase() {
listener.value.onAnimationEnd(null)
Mockito.verify(animator).setListener(null)
}
/**
* The AOD UI is shown during the screen off animation, after a delay to allow the light reveal
* animation to start. If the device is woken up during the screen off, we should *never* do
* this.
*
* This test confirms that we do show the AOD UI when the device is not woken up
* (PowerManager#isInteractive = false).
*/
@Test
fun testAodUiShownIfNotInteractive() {
`when`(dozeParameters.shouldControlUnlockedScreenOff()).thenReturn(true)
`when`(powerManager.isInteractive).thenReturn(false)
val callbackCaptor = ArgumentCaptor.forClass(Runnable::class.java)
controller.onStartedGoingToSleep()
verify(handler).postDelayed(callbackCaptor.capture(), anyLong())
callbackCaptor.value.run()
verify(notificationPanelViewController, times(1)).showAodUi()
}
/**
* The AOD UI is shown during the screen off animation, after a delay to allow the light reveal
* animation to start. If the device is woken up during the screen off, we should *never* do
* this.
*
* This test confirms that we do not show the AOD UI when the device is woken up during screen
* off (PowerManager#isInteractive = true).
*/
@Test
fun testAodUiNotShownIfInteractive() {
`when`(dozeParameters.shouldControlUnlockedScreenOff()).thenReturn(true)
`when`(powerManager.isInteractive).thenReturn(true)
val callbackCaptor = ArgumentCaptor.forClass(Runnable::class.java)
controller.onStartedGoingToSleep()
mockingDetails(handler).printInvocations()
verify(handler).postDelayed(callbackCaptor.capture(), anyLong())
callbackCaptor.value.run()
verify(notificationPanelViewController, never()).showAodUi()
}
}