Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 34e29db6 authored by Josh Tsuji's avatar Josh Tsuji Committed by Android (Google) Code Review
Browse files

Merge "Check that PowerManager#isInteractive is false before showing the AOD...

Merge "Check that PowerManager#isInteractive is false before showing the AOD UI for screen off." into sc-v2-dev
parents dcca7075 7ecf6bb7
Loading
Loading
Loading
Loading
+16 −6
Original line number Diff line number Diff line
@@ -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({
                // 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.
                    // Show AOD. That'll cause the KeyguardVisibilityHelper to call
                    // #animateInKeyguard.
                    statusBar.notificationPanelViewController.showAodUi()
                }
            }, (ANIMATE_IN_KEYGUARD_DELAY * animatorDurationScale).toLong())
        } else {
            decidedToAnimateGoingToSleep = false
+80 −3
Original line number Diff line number Diff line
@@ -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