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

Commit 323a2139 authored by Ale Nijamkin's avatar Ale Nijamkin
Browse files

[flexiglass] Don't show bouncer when lockscreen is clicked on mobile

We don't want this behaviour on mobile but we still want it on desktop.

Fix: 433950243
Test: manually verified that clicking on the background of the
lockscreen scene doesn't bring up the bouncer anymore. Tested with
flexiglass on as well as off.
Flag: NONE this is a very simple change and the non-flexi codepath isn't
flag protected

Change-Id: I2ce55660a14622b46b1bdc524c42817b0d7b4521
parent 748f1058
Loading
Loading
Loading
Loading
+166 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.keyguard.domain.interactor

import android.platform.test.flag.junit.FlagsParameterization
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.deviceentry.shared.FaceAuthUiEvent
import com.android.systemui.flags.andSceneContainer
import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository
import com.android.systemui.kosmos.collectLastValue
import com.android.systemui.kosmos.runCurrent
import com.android.systemui.kosmos.runTest
import com.android.systemui.res.R
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.statusbar.phone.statusBarKeyguardViewManager
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyBoolean
import org.mockito.ArgumentMatchers.anyString
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.kotlin.description
import platform.test.runner.parameterized.ParameterizedAndroidJunit4
import platform.test.runner.parameterized.Parameters

@SmallTest
@RunWith(ParameterizedAndroidJunit4::class)
class KeyguardTouchHandlingInteractorOnClickTest(private val testScenario: TestScenario) :
    SysuiTestCase() {

    private val kosmos = testKosmos()
    private lateinit var underTest: KeyguardTouchHandlingInteractor

    init {
        mSetFlagsRule.setFlagsParameterization(testScenario.flags)
    }

    @Before
    fun setUp() {
        overrideResource(
            R.bool.config_improveLargeScreenInteractionOnLockscreen,
            testScenario.improvedLargeScreenInteraction,
        )
        underTest = kosmos.keyguardTouchHandlingInteractor
    }

    @Test
    fun onClick() =
        kosmos.runTest {
            collectLastValue(underTest.isMenuVisible)
            val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
            runCurrent()
            kosmos.fakeDeviceEntryFaceAuthRepository.canRunFaceAuth.value = testScenario.faceAuth
            if (SceneContainerFlag.isEnabled) {
                assertWithMessage("Unexpectedly, bouncer is a current overlay")
                    .that(currentOverlays)
                    .doesNotContain(Overlays.Bouncer)
            } else {
                verify(
                        kosmos.statusBarKeyguardViewManager,
                        never().description("Unexpectedly requested to show bouncer"),
                    )
                    .showPrimaryBouncer(anyBoolean(), anyString())
            }

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

            if (SceneContainerFlag.isEnabled) {
                if (testScenario.isBouncerNavigationExpected) {
                    assertWithMessage("Bouncer isn't a current overlay")
                        .that(currentOverlays)
                        .contains(Overlays.Bouncer)
                } else {
                    assertWithMessage("Unexpectedly, bouncer is a current overlay")
                        .that(currentOverlays)
                        .doesNotContain(Overlays.Bouncer)
                }
            } else {
                if (testScenario.isBouncerNavigationExpected) {
                    verify(
                            kosmos.statusBarKeyguardViewManager,
                            description("Did not request to show bouncer"),
                        )
                        .showPrimaryBouncer(anyBoolean(), anyString())
                } else {
                    verify(
                            kosmos.statusBarKeyguardViewManager,
                            never().description("Unexpectedly requested to show bouncer"),
                        )
                        .showPrimaryBouncer(anyBoolean(), anyString())
                }
            }

            val runningAuthRequest =
                kosmos.fakeDeviceEntryFaceAuthRepository.runningAuthRequest.value
            if (testScenario.faceAuth) {
                assertThat(runningAuthRequest?.first)
                    .isEqualTo(FaceAuthUiEvent.FACE_AUTH_TRIGGERED_NOTIFICATION_PANEL_CLICKED)
                assertThat(runningAuthRequest?.second).isTrue()
            } else {
                assertThat(runningAuthRequest?.first).isNull()
                assertThat(runningAuthRequest?.second).isNull()
            }
        }

    data class TestScenario(
        val flags: FlagsParameterization,
        val faceAuth: Boolean,
        val improvedLargeScreenInteraction: Boolean,
    ) {
        val isBouncerNavigationExpected: Boolean = !faceAuth && improvedLargeScreenInteraction
    }

    companion object {
        @Parameters(name = "{0}")
        @JvmStatic
        fun testScenarios(): List<TestScenario> {
            return FlagsParameterization.allCombinationsOf().andSceneContainer().flatMap { flags ->
                listOf(
                    TestScenario(
                        flags = flags,
                        faceAuth = false,
                        improvedLargeScreenInteraction = false,
                    ),
                    TestScenario(
                        flags = flags,
                        faceAuth = false,
                        improvedLargeScreenInteraction = true,
                    ),
                    TestScenario(
                        flags = flags,
                        faceAuth = true,
                        improvedLargeScreenInteraction = false,
                    ),
                    TestScenario(
                        flags = flags,
                        faceAuth = true,
                        improvedLargeScreenInteraction = true,
                    ),
                )
            }
        }
    }
}
+2 −87
Original line number Diff line number Diff line
@@ -30,15 +30,12 @@ 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.bouncer.domain.interactor.bouncerInteractor
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
@@ -47,7 +44,6 @@ 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
@@ -68,10 +64,8 @@ import org.junit.After
import org.junit.Before
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
@@ -294,86 +288,6 @@ 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 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)
                .isEqualTo(FaceAuthUiEvent.FACE_AUTH_TRIGGERED_NOTIFICATION_PANEL_CLICKED)
            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 {
@@ -528,6 +442,7 @@ class KeyguardTouchHandlingInteractorTest : SysuiTestCase() {
                secureSettingsRepository = secureSettingsRepository,
                powerManager = powerManager,
                systemClock = kosmos.fakeSystemClock,
                bouncerInteractor = kosmos.bouncerInteractor,
            )
        setUpState()
    }
+3 −1
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.internal.logging.UiEvent
import com.android.internal.logging.UiEventLogger
import com.android.systemui.Flags.doubleTapToSleep
import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
@@ -81,6 +82,7 @@ constructor(
    private val secureSettingsRepository: SecureSettingsRepository,
    private val powerManager: PowerManager,
    private val systemClock: SystemClock,
    private val bouncerInteractor: BouncerInteractor,
) {
    private val _udfpsAccessibilityOverlayBounds: MutableStateFlow<Rect?> = MutableStateFlow(null)

@@ -221,7 +223,7 @@ constructor(
        pulsingGestureListener.onSingleTapUp(x, y)
        if (faceAuthInteractor.canFaceAuthRun()) {
            faceAuthInteractor.onNotificationPanelClicked()
        } else {
        } else if (bouncerInteractor.isImproveLargeScreenInteractionEnabled) {
            attemptDeviceEntry(loggingReason = "Lockscreen clicked")
        }
    }
+2 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.content.applicationContext
import android.os.powerManager
import android.view.accessibility.accessibilityManagerWrapper
import com.android.internal.logging.uiEventLogger
import com.android.systemui.bouncer.domain.interactor.bouncerInteractor
import com.android.systemui.broadcast.broadcastDispatcher
import com.android.systemui.deviceentry.domain.interactor.deviceEntryFaceAuthInteractor
import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
@@ -50,5 +51,6 @@ val Kosmos.keyguardTouchHandlingInteractor by
            secureSettingsRepository = userAwareSecureSettingsRepository,
            powerManager = powerManager,
            systemClock = fakeSystemClock,
            bouncerInteractor = bouncerInteractor,
        )
    }