summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-01-26 21:39:59 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-01-26 21:39:59 +0000
commit5ce74ca4688558052279299f13ed8cc45d87c2a4 (patch)
treea152eac4176e5d71341d4fea7483bac8c7aa5b7d
parent4e0b08b5c1ab83d01ea08a51409d3b95bc640beb (diff)
parent955d37e6d7f8868d50154d47f12fec340d380ae6 (diff)
downloadbase-5ce74ca4688558052279299f13ed8cc45d87c2a4.tar.gz
Merge cherrypicks of [16691349] into sc-v2-release.
Change-Id: Ic38459ae48b114728380cc232acb7d9082d9be8b
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt22
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt83
2 files changed, 96 insertions, 9 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
index 83ab8cb80b29..4ba794fe8408 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
@@ -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
-
- // Show AOD. That'll cause the KeyguardVisibilityHelper to call #animateInKeyguard.
- statusBar.notificationPanelViewController.showAodUi()
+ // 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()
+ }
}, (ANIMATE_IN_KEYGUARD_DELAY * animatorDurationScale).toLong())
} else {
decidedToAnimateGoingToSleep = false
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt
index a8a33dabf1aa..fb8c9858be0b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt
@@ -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()
+ }
} \ No newline at end of file