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

Commit d3e94a87 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Flexiglass, Keyguard: mouse click on empty space should transition to bouncer" into main

parents e476afed a2d51d4a
Loading
Loading
Loading
Loading
+24 −10
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.back.domain.interactor.BackActionInteractor
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
import com.android.systemui.flags.DisableSceneContainer
import com.android.systemui.media.controls.util.MediaSessionLegacyHelperWrapper
import com.android.systemui.plugins.statusbar.StatusBarStateController
@@ -30,6 +31,7 @@ import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
import com.android.systemui.power.domain.interactor.PowerInteractorFactory
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.shade.ShadeController
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
@@ -68,6 +70,7 @@ class KeyguardKeyEventInteractorTest : SysuiTestCase() {
    @Mock private lateinit var mediaSessionLegacyHelperWrapper: MediaSessionLegacyHelperWrapper
    @Mock private lateinit var mediaSessionLegacyHelper: MediaSessionLegacyHelper
    @Mock private lateinit var backActionInteractor: BackActionInteractor
    @Mock private lateinit var deviceEntryInteractor: DeviceEntryInteractor

    private lateinit var underTest: KeyguardKeyEventInteractor

@@ -85,6 +88,7 @@ class KeyguardKeyEventInteractorTest : SysuiTestCase() {
                shadeController,
                mediaSessionLegacyHelperWrapper,
                backActionInteractor,
                deviceEntryInteractor,
                powerInteractor,
                kosmos.keyguardMediaKeyInteractor,
            )
@@ -270,27 +274,36 @@ class KeyguardKeyEventInteractorTest : SysuiTestCase() {
        // action down: does NOT collapse the shade
        val actionDownMenuKeyEvent = KeyEvent(KeyEvent.ACTION_DOWN, keycode)
        assertThat(underTest.dispatchKeyEvent(actionDownMenuKeyEvent)).isFalse()
        if (SceneContainerFlag.isEnabled) {
            verify(deviceEntryInteractor, never()).attemptDeviceEntry()
        } else {
            verify(statusBarKeyguardViewManager, never())
                .showPrimaryBouncer(
                    any(),
                    eq("KeyguardKeyEventInteractor#collapseShadeLockedOrShowPrimaryBouncer"),
                )
        }

        // action up: collapses the shade
        val actionUpMenuKeyEvent = KeyEvent(KeyEvent.ACTION_UP, keycode)
        assertThat(underTest.dispatchKeyEvent(actionUpMenuKeyEvent)).isTrue()
        if (SceneContainerFlag.isEnabled) {
            verify(deviceEntryInteractor).attemptDeviceEntry()
        } else {
            verify(statusBarKeyguardViewManager)
                .showPrimaryBouncer(
                    eq(true),
                    eq("KeyguardKeyEventInteractor#collapseShadeLockedOrShowPrimaryBouncer"),
                )
        }
    }

    private fun verifyActionsDoNothing(keycode: Int) {
        // action down: does nothing
        val actionDownMenuKeyEvent = KeyEvent(KeyEvent.ACTION_DOWN, keycode)
        assertThat(underTest.dispatchKeyEvent(actionDownMenuKeyEvent)).isFalse()
        verify(shadeController, never()).animateCollapseShadeForced()
        verify(deviceEntryInteractor, never()).attemptDeviceEntry()
        verify(statusBarKeyguardViewManager, never())
            .showPrimaryBouncer(
                any(),
@@ -301,6 +314,7 @@ class KeyguardKeyEventInteractorTest : SysuiTestCase() {
        val actionUpMenuKeyEvent = KeyEvent(KeyEvent.ACTION_UP, keycode)
        assertThat(underTest.dispatchKeyEvent(actionUpMenuKeyEvent)).isFalse()
        verify(shadeController, never()).animateCollapseShadeForced()
        verify(deviceEntryInteractor, never()).attemptDeviceEntry()
        verify(statusBarKeyguardViewManager, never())
            .showPrimaryBouncer(
                any(),
+98 −10
Original line number Diff line number Diff line
@@ -21,25 +21,37 @@ import android.content.Intent
import android.os.PowerManager
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.SetFlagsRule
import android.provider.Settings
import android.view.accessibility.accessibilityManagerWrapper
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.logging.UiEventLogger
import com.android.internal.logging.testing.UiEventLoggerFake
import com.android.internal.logging.uiEventLogger
import com.android.systemui.Flags.FLAG_DOUBLE_TAP_TO_SLEEP
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.deviceentry.domain.interactor.deviceEntryFaceAuthInteractor
import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
import com.android.systemui.deviceentry.shared.FaceAuthUiEvent
import com.android.systemui.flags.DisableSceneContainer
import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
import com.android.systemui.keyguard.data.repository.KeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.kosmos.testScope
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.res.R
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.shade.pulsingGestureListener
import com.android.systemui.shared.settings.data.repository.SecureSettingsRepository
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
import com.android.systemui.statusbar.phone.statusBarKeyguardViewManager
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.mock
@@ -48,16 +60,18 @@ import com.android.systemui.util.settings.data.repository.userAwareSecureSetting
import com.android.systemui.util.time.fakeSystemClock
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.advanceTimeBy
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyBoolean
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.anyLong
import org.mockito.ArgumentMatchers.anyString
import org.mockito.Mock
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
@@ -73,20 +87,28 @@ class KeyguardTouchHandlingInteractorTest : SysuiTestCase() {
            this.uiEventLogger = mock<UiEventLoggerFake>()
        }

    @get:Rule val setFlagsRule = SetFlagsRule()

    private lateinit var underTest: KeyguardTouchHandlingInteractor

    private val logger = kosmos.uiEventLogger
    private val testScope = kosmos.testScope
    private val keyguardRepository = kosmos.fakeKeyguardRepository
    private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
    private val secureSettingsRepository = kosmos.userAwareSecureSettingsRepository
    private lateinit var logger: UiEventLogger
    private lateinit var testScope: TestScope
    private lateinit var keyguardRepository: KeyguardRepository
    private lateinit var keyguardTransitionRepository: FakeKeyguardTransitionRepository
    private lateinit var secureSettingsRepository: SecureSettingsRepository
    private lateinit var sceneInteractor: SceneInteractor
    private lateinit var statusBarKeyguardViewManager: StatusBarKeyguardViewManager

    @Mock private lateinit var powerManager: PowerManager

    @Before
    fun setUp() {
        logger = kosmos.uiEventLogger
        testScope = kosmos.testScope
        keyguardRepository = kosmos.fakeKeyguardRepository
        keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
        secureSettingsRepository = kosmos.userAwareSecureSettingsRepository
        sceneInteractor = kosmos.sceneInteractor
        statusBarKeyguardViewManager = kosmos.statusBarKeyguardViewManager

        MockitoAnnotations.initMocks(this)
        overrideResource(R.bool.long_press_keyguard_customize_lockscreen_enabled, true)
        overrideResource(com.android.internal.R.bool.config_supportDoubleTapSleep, true)
@@ -272,16 +294,44 @@ class KeyguardTouchHandlingInteractorTest : SysuiTestCase() {
                .log(KeyguardTouchHandlingInteractor.LogEvents.LOCK_SCREEN_LONG_PRESS_POPUP_CLICKED)
        }

    @DisableSceneContainer
    @Test
    fun triggersFaceAuthWhenLockscreenIsClickedStaysOnKeyguardNoScenes() =
        testScope.runTest {
            collectLastValue(underTest.isMenuVisible)
            val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
            runCurrent()
            kosmos.fakeDeviceEntryFaceAuthRepository.canRunFaceAuth.value = true

            underTest.onClick(100.0f, 100.0f)
            runCurrent()

            verify(kosmos.statusBarKeyguardViewManager, never())
                .showPrimaryBouncer(anyBoolean(), anyString())

            val runningAuthRequest =
                kosmos.fakeDeviceEntryFaceAuthRepository.runningAuthRequest.value
            assertThat(runningAuthRequest?.first)
                .isEqualTo(FaceAuthUiEvent.FACE_AUTH_TRIGGERED_NOTIFICATION_PANEL_CLICKED)
            assertThat(runningAuthRequest?.second).isEqualTo(true)
        }

    @EnableSceneContainer
    @Test
    fun triggersFaceAuthWhenLockscreenIsClicked() =
    fun triggersFaceAuthWhenLockscreenIsClickedStaysOnKeyguard() =
        testScope.runTest {
            collectLastValue(underTest.isMenuVisible)
            val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
            runCurrent()
            kosmos.fakeDeviceEntryFaceAuthRepository.canRunFaceAuth.value = true

            assertThat(currentOverlays).doesNotContain(Overlays.Bouncer)

            underTest.onClick(100.0f, 100.0f)
            runCurrent()

            assertThat(currentOverlays).doesNotContain(Overlays.Bouncer)

            val runningAuthRequest =
                kosmos.fakeDeviceEntryFaceAuthRepository.runningAuthRequest.value
            assertThat(runningAuthRequest?.first)
@@ -289,6 +339,41 @@ class KeyguardTouchHandlingInteractorTest : SysuiTestCase() {
            assertThat(runningAuthRequest?.second).isEqualTo(true)
        }

    @DisableSceneContainer
    @Test
    fun switchesToBouncerWhenLockscreenIsClickedNoFaceAuthNoScenes() =
        testScope.runTest {
            collectLastValue(underTest.isMenuVisible)
            val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)

            runCurrent()
            kosmos.fakeDeviceEntryFaceAuthRepository.canRunFaceAuth.value = false

            underTest.onClick(100.0f, 100.0f)
            runCurrent()

            verify(kosmos.statusBarKeyguardViewManager)
                .showPrimaryBouncer(anyBoolean(), anyString())
        }

    @EnableSceneContainer
    @Test
    fun switchesToBouncerWhenLockscreenIsClickedNoFaceAuth() =
        testScope.runTest {
            collectLastValue(underTest.isMenuVisible)
            val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)

            runCurrent()
            kosmos.fakeDeviceEntryFaceAuthRepository.canRunFaceAuth.value = false

            assertThat(currentOverlays).doesNotContain(Overlays.Bouncer)

            underTest.onClick(100.0f, 100.0f)
            runCurrent()

            assertThat(currentOverlays).contains(Overlays.Bouncer)
        }

    @Test
    fun showMenu_leaveLockscreen_returnToLockscreen_menuNotVisible() =
        testScope.runTest {
@@ -435,8 +520,11 @@ class KeyguardTouchHandlingInteractorTest : SysuiTestCase() {
                logger = logger,
                broadcastDispatcher = fakeBroadcastDispatcher,
                accessibilityManager = kosmos.accessibilityManagerWrapper,
                statusBarKeyguardViewManager = statusBarKeyguardViewManager,
                pulsingGestureListener = kosmos.pulsingGestureListener,
                faceAuthInteractor = kosmos.deviceEntryFaceAuthInteractor,
                deviceEntryInteractor = kosmos.deviceEntryInteractor,
                powerInteractor = kosmos.powerInteractor,
                secureSettingsRepository = secureSettingsRepository,
                powerManager = powerManager,
                systemClock = kosmos.fakeSystemClock,
+10 −4
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.media.AudioManager
import android.view.KeyEvent
import com.android.systemui.back.domain.interactor.BackActionInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
import com.android.systemui.keyevent.domain.interactor.SysUIKeyEventHandler.Companion.handleAction
import com.android.systemui.media.controls.util.MediaSessionLegacyHelperWrapper
import com.android.systemui.plugins.ActivityStarter.OnDismissAction
@@ -44,6 +45,7 @@ constructor(
    private val shadeController: ShadeController,
    private val mediaSessionLegacyHelperWrapper: MediaSessionLegacyHelperWrapper,
    private val backActionInteractor: BackActionInteractor,
    private val deviceEntryInteractor: DeviceEntryInteractor,
    private val powerInteractor: PowerInteractor,
    private val keyguardMediaKeyInteractor: KeyguardMediaKeyInteractor,
) {
@@ -136,10 +138,14 @@ constructor(
                return true
            }
            StatusBarState.KEYGUARD -> {
                if (SceneContainerFlag.isEnabled) {
                    deviceEntryInteractor.attemptDeviceEntry()
                } else {
                    statusBarKeyguardViewManager.showPrimaryBouncer(
                        true,
                        "KeyguardKeyEventInteractor#collapseShadeLockedOrShowPrimaryBouncer",
                    )
                }
                return true
            }
        }
+29 −1
Original line number Diff line number Diff line
@@ -33,12 +33,16 @@ import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryFaceAuthInteractor
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
import com.android.systemui.keyguard.data.repository.KeyguardRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.res.R
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.shade.PulsingGestureListener
import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.shared.settings.data.repository.SecureSettingsRepository
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper
import com.android.systemui.util.time.SystemClock
import javax.inject.Inject
@@ -69,8 +73,11 @@ constructor(
    private val logger: UiEventLogger,
    broadcastDispatcher: BroadcastDispatcher,
    private val accessibilityManager: AccessibilityManagerWrapper,
    private val statusBarKeyguardViewManager: StatusBarKeyguardViewManager,
    private val pulsingGestureListener: PulsingGestureListener,
    private val faceAuthInteractor: DeviceEntryFaceAuthInteractor,
    private val deviceEntryInteractor: DeviceEntryInteractor,
    private val powerInteractor: PowerInteractor,
    private val secureSettingsRepository: SecureSettingsRepository,
    private val powerManager: PowerManager,
    private val systemClock: SystemClock,
@@ -212,7 +219,11 @@ constructor(
    /** Notifies that the lockscreen has been clicked at position [x], [y]. */
    fun onClick(x: Float, y: Float) {
        pulsingGestureListener.onSingleTapUp(x, y)
        if (faceAuthInteractor.canFaceAuthRun()) {
            faceAuthInteractor.onNotificationPanelClicked()
        } else {
            attemptDeviceEntry()
        }
    }

    /** Notifies that the lockscreen has been double clicked. */
@@ -279,6 +290,23 @@ constructor(
            .toLong()
    }

    private fun attemptDeviceEntry() {
        if (isDeviceAwake()) {
            if (SceneContainerFlag.isEnabled) {
                deviceEntryInteractor.attemptDeviceEntry()
            } else {
                statusBarKeyguardViewManager.showPrimaryBouncer(
                    true,
                    "KeyguardTouchHandlingInteractor#attemptDeviceEntry",
                )
            }
        }
    }

    private fun isDeviceAwake(): Boolean {
        return powerInteractor.detailedWakefulness.value.isAwake()
    }

    enum class LogEvents(private val _id: Int) : UiEventLogger.UiEventEnum {
        @UiEvent(doc = "The lock screen was long-pressed and we showed the settings popup menu.")
        LOCK_SCREEN_LONG_PRESS_POPUP_SHOWN(1292),
+6 −0
Original line number Diff line number Diff line
@@ -22,10 +22,13 @@ import android.view.accessibility.accessibilityManagerWrapper
import com.android.internal.logging.uiEventLogger
import com.android.systemui.broadcast.broadcastDispatcher
import com.android.systemui.deviceentry.domain.interactor.deviceEntryFaceAuthInteractor
import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
import com.android.systemui.keyguard.data.repository.keyguardRepository
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.shade.pulsingGestureListener
import com.android.systemui.statusbar.phone.statusBarKeyguardViewManager
import com.android.systemui.util.settings.data.repository.userAwareSecureSettingsRepository
import com.android.systemui.util.time.fakeSystemClock

@@ -39,8 +42,11 @@ val Kosmos.keyguardTouchHandlingInteractor by
            logger = uiEventLogger,
            broadcastDispatcher = broadcastDispatcher,
            accessibilityManager = accessibilityManagerWrapper,
            statusBarKeyguardViewManager = statusBarKeyguardViewManager,
            pulsingGestureListener = pulsingGestureListener,
            faceAuthInteractor = deviceEntryFaceAuthInteractor,
            powerInteractor = powerInteractor,
            deviceEntryInteractor = deviceEntryInteractor,
            secureSettingsRepository = userAwareSecureSettingsRepository,
            powerManager = powerManager,
            systemClock = fakeSystemClock,