diff options
4 files changed, 167 insertions, 21 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractor.kt index e017129bd5c5..bf1f07479f34 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractor.kt @@ -26,6 +26,9 @@ import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor import com.android.systemui.keyguard.data.repository.BiometricType import com.android.systemui.keyguard.data.repository.DeviceEntryFingerprintAuthRepository import com.android.systemui.res.R +import com.android.systemui.scene.domain.interactor.SceneInteractor +import com.android.systemui.scene.shared.flag.SceneContainerFlags +import com.android.systemui.scene.shared.model.Scenes import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow @@ -33,6 +36,7 @@ import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filterNotNull +import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.merge import kotlinx.coroutines.launch @@ -48,6 +52,8 @@ constructor( @Application private val applicationScope: CoroutineScope, @Application private val context: Context, deviceEntryFingerprintAuthRepository: DeviceEntryFingerprintAuthRepository, + private val sceneContainerFlags: SceneContainerFlags, + private val sceneInteractor: SceneInteractor, private val primaryBouncerInteractor: PrimaryBouncerInteractor, alternateBouncerInteractor: AlternateBouncerInteractor, private val keyguardUpdateMonitor: KeyguardUpdateMonitor, @@ -65,16 +71,35 @@ constructor( } } + private val isSideFpsIndicatorOnPrimaryBouncerEnabled: Boolean + get() = context.resources.getBoolean(R.bool.config_show_sidefps_hint_on_bouncer) + + private val isBouncerSceneActive: Flow<Boolean> = + if (sceneContainerFlags.isEnabled()) { + sceneInteractor.currentScene.map { it == Scenes.Bouncer }.distinctUntilChanged() + } else { + flowOf(false) + } + private val showIndicatorForPrimaryBouncer: Flow<Boolean> = merge( + // Legacy bouncer visibility changes. primaryBouncerInteractor.isShowing, primaryBouncerInteractor.startingToHide, primaryBouncerInteractor.startingDisappearAnimation.filterNotNull(), + // Bouncer scene visibility changes. + isBouncerSceneActive, deviceEntryFingerprintAuthRepository.shouldUpdateIndicatorVisibility.filter { it } ) - .map { shouldShowIndicatorForPrimaryBouncer() } + .map { + isBouncerActive() && + isSideFpsIndicatorOnPrimaryBouncerEnabled && + keyguardUpdateMonitor.isFingerprintDetectionRunning && + keyguardUpdateMonitor.isUnlockingWithFingerprintAllowed + } private val showIndicatorForAlternateBouncer: Flow<Boolean> = + // Note: this interactor internally verifies that SideFPS is enabled and running. alternateBouncerInteractor.isVisible /** @@ -89,16 +114,11 @@ constructor( } .distinctUntilChanged() - private fun shouldShowIndicatorForPrimaryBouncer(): Boolean { - val sfpsEnabled: Boolean = - context.resources.getBoolean(R.bool.config_show_sidefps_hint_on_bouncer) - val sfpsDetectionRunning = keyguardUpdateMonitor.isFingerprintDetectionRunning - val isUnlockingWithFpAllowed = keyguardUpdateMonitor.isUnlockingWithFingerprintAllowed - + private fun isBouncerActive(): Boolean { + if (sceneContainerFlags.isEnabled()) { + return sceneInteractor.currentScene.value == Scenes.Bouncer + } return primaryBouncerInteractor.isBouncerShowing() && - sfpsEnabled && - sfpsDetectionRunning && - isUnlockingWithFpAllowed && !primaryBouncerInteractor.isAnimatingAway() } diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt index d4a0c8f74b14..30c5e6ed4812 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt @@ -77,6 +77,8 @@ import com.android.systemui.log.logcatLogBuffer import com.android.systemui.plugins.statusbar.StatusBarStateController 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.shared.flag.fakeSceneContainerFlags import com.android.systemui.shared.Flags.FLAG_SIDEFPS_CONTROLLER_REFACTOR import com.android.systemui.statusbar.phone.dozeServiceHost import com.android.systemui.statusbar.policy.KeyguardStateController @@ -85,7 +87,6 @@ import com.android.systemui.unfold.compat.ScreenSizeFoldProvider import com.android.systemui.user.domain.interactor.SelectedUserInteractor import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.mockito.eq -import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever import com.android.systemui.util.time.FakeSystemClock import java.util.Optional @@ -238,6 +239,8 @@ class SideFpsOverlayViewBinderTest : SysuiTestCase() { testScope.backgroundScope, mContext, deviceEntryFingerprintAuthRepository, + kosmos.fakeSceneContainerFlags, + kosmos.sceneInteractor, primaryBouncerInteractor, alternateBouncerInteractor, keyguardUpdateMonitor diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt index ae20c703b93d..1acb20322c14 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt @@ -75,6 +75,8 @@ import com.android.systemui.log.logcatLogBuffer import com.android.systemui.plugins.statusbar.StatusBarStateController 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.shared.flag.fakeSceneContainerFlags import com.android.systemui.shared.Flags.FLAG_SIDEFPS_CONTROLLER_REFACTOR import com.android.systemui.statusbar.phone.dozeServiceHost import com.android.systemui.statusbar.policy.KeyguardStateController @@ -233,6 +235,8 @@ class SideFpsOverlayViewModelTest : SysuiTestCase() { testScope.backgroundScope, mContext, deviceEntryFingerprintAuthRepository, + kosmos.fakeSceneContainerFlags, + kosmos.sceneInteractor, primaryBouncerInteractor, alternateBouncerInteractor, keyguardUpdateMonitor diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractorTest.kt index 3b4f683124e8..9266af452abd 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractorTest.kt @@ -36,16 +36,20 @@ import com.android.systemui.keyguard.DismissCallbackRegistry import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintAuthRepository import com.android.systemui.keyguard.data.repository.FakeTrustRepository +import com.android.systemui.kosmos.testScope import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.res.R +import com.android.systemui.scene.domain.interactor.sceneInteractor +import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags +import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.shared.Flags.FLAG_SIDEFPS_CONTROLLER_REFACTOR import com.android.systemui.statusbar.policy.KeyguardStateController +import com.android.systemui.testKosmos import com.android.systemui.user.domain.interactor.SelectedUserInteractor import com.android.systemui.util.mockito.whenever import com.android.systemui.util.time.FakeSystemClock import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest @@ -69,6 +73,8 @@ class DeviceEntrySideFpsOverlayInteractorTest : SysuiTestCase() { @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor @Mock private lateinit var mSelectedUserInteractor: SelectedUserInteractor + private val kosmos = testKosmos() + private val testScope = kosmos.testScope private val bouncerRepository = FakeKeyguardBouncerRepository() private val biometricSettingsRepository = FakeBiometricSettingsRepository() private val deviceEntryFingerprintAuthRepository = FakeDeviceEntryFingerprintAuthRepository() @@ -78,11 +84,11 @@ class DeviceEntrySideFpsOverlayInteractorTest : SysuiTestCase() { private lateinit var underTest: DeviceEntrySideFpsOverlayInteractor - private val testScope = TestScope(StandardTestDispatcher()) - @Before fun setup() { mSetFlagsRule.enableFlags(FLAG_SIDEFPS_CONTROLLER_REFACTOR) + kosmos.fakeSceneContainerFlags.enabled = false + primaryBouncerInteractor = PrimaryBouncerInteractor( bouncerRepository, @@ -100,6 +106,7 @@ class DeviceEntrySideFpsOverlayInteractorTest : SysuiTestCase() { mSelectedUserInteractor, faceAuthInteractor ) + alternateBouncerInteractor = AlternateBouncerInteractor( mock(StatusBarStateController::class.java), @@ -114,11 +121,14 @@ class DeviceEntrySideFpsOverlayInteractorTest : SysuiTestCase() { { mock(KeyguardTransitionInteractor::class.java) }, testScope.backgroundScope, ) + underTest = DeviceEntrySideFpsOverlayInteractor( testScope.backgroundScope, mContext, deviceEntryFingerprintAuthRepository, + kosmos.fakeSceneContainerFlags, + kosmos.sceneInteractor, primaryBouncerInteractor, alternateBouncerInteractor, keyguardUpdateMonitor @@ -138,7 +148,7 @@ class DeviceEntrySideFpsOverlayInteractorTest : SysuiTestCase() { fpsDetectionRunning = true, isUnlockingWithFpAllowed = true ) - assertThat(showIndicatorForDeviceEntry).isEqualTo(true) + assertThat(showIndicatorForDeviceEntry).isTrue() } @Test @@ -154,7 +164,63 @@ class DeviceEntrySideFpsOverlayInteractorTest : SysuiTestCase() { fpsDetectionRunning = true, isUnlockingWithFpAllowed = true ) - assertThat(showIndicatorForDeviceEntry).isEqualTo(false) + assertThat(showIndicatorForDeviceEntry).isFalse() + } + + @Test + fun updatesShowIndicatorForDeviceEntry_onBouncerSceneActive() = + testScope.runTest { + kosmos.fakeSceneContainerFlags.enabled = true + underTest = + DeviceEntrySideFpsOverlayInteractor( + testScope.backgroundScope, + mContext, + deviceEntryFingerprintAuthRepository, + kosmos.fakeSceneContainerFlags, + kosmos.sceneInteractor, + primaryBouncerInteractor, + alternateBouncerInteractor, + keyguardUpdateMonitor + ) + + val showIndicatorForDeviceEntry by + collectLastValue(underTest.showIndicatorForDeviceEntry) + runCurrent() + + updateBouncerScene( + isActive = true, + fpsDetectionRunning = true, + isUnlockingWithFpAllowed = true + ) + assertThat(showIndicatorForDeviceEntry).isTrue() + } + + @Test + fun updatesShowIndicatorForDeviceEntry_onBouncerSceneInactive() = + testScope.runTest { + kosmos.fakeSceneContainerFlags.enabled = true + underTest = + DeviceEntrySideFpsOverlayInteractor( + testScope.backgroundScope, + mContext, + deviceEntryFingerprintAuthRepository, + kosmos.fakeSceneContainerFlags, + kosmos.sceneInteractor, + primaryBouncerInteractor, + alternateBouncerInteractor, + keyguardUpdateMonitor + ) + + val showIndicatorForDeviceEntry by + collectLastValue(underTest.showIndicatorForDeviceEntry) + runCurrent() + + updateBouncerScene( + isActive = false, + fpsDetectionRunning = true, + isUnlockingWithFpAllowed = true + ) + assertThat(showIndicatorForDeviceEntry).isFalse() } @Test @@ -170,7 +236,7 @@ class DeviceEntrySideFpsOverlayInteractorTest : SysuiTestCase() { fpsDetectionRunning = false, isUnlockingWithFpAllowed = true ) - assertThat(showIndicatorForDeviceEntry).isEqualTo(false) + assertThat(showIndicatorForDeviceEntry).isFalse() } } @@ -187,7 +253,39 @@ class DeviceEntrySideFpsOverlayInteractorTest : SysuiTestCase() { fpsDetectionRunning = true, isUnlockingWithFpAllowed = false ) - assertThat(showIndicatorForDeviceEntry).isEqualTo(false) + assertThat(showIndicatorForDeviceEntry).isFalse() + } + } + + @Test + fun updatesShowIndicatorForDeviceEntry_fromBouncerScene_whenFpsDetectionNotRunning() { + testScope.runTest { + val showIndicatorForDeviceEntry by + collectLastValue(underTest.showIndicatorForDeviceEntry) + runCurrent() + + updateBouncerScene( + isActive = true, + fpsDetectionRunning = false, + isUnlockingWithFpAllowed = true + ) + assertThat(showIndicatorForDeviceEntry).isFalse() + } + } + + @Test + fun updatesShowIndicatorForDeviceEntry_fromBouncerScene_onUnlockingWithFpDisallowed() { + testScope.runTest { + val showIndicatorForDeviceEntry by + collectLastValue(underTest.showIndicatorForDeviceEntry) + runCurrent() + + updateBouncerScene( + isActive = true, + fpsDetectionRunning = true, + isUnlockingWithFpAllowed = false + ) + assertThat(showIndicatorForDeviceEntry).isFalse() } } @@ -204,7 +302,7 @@ class DeviceEntrySideFpsOverlayInteractorTest : SysuiTestCase() { fpsDetectionRunning = true, isUnlockingWithFpAllowed = true ) - assertThat(showIndicatorForDeviceEntry).isEqualTo(false) + assertThat(showIndicatorForDeviceEntry).isFalse() } } @@ -216,10 +314,10 @@ class DeviceEntrySideFpsOverlayInteractorTest : SysuiTestCase() { runCurrent() bouncerRepository.setAlternateVisible(true) - assertThat(showIndicatorForDeviceEntry).isEqualTo(true) + assertThat(showIndicatorForDeviceEntry).isTrue() bouncerRepository.setAlternateVisible(false) - assertThat(showIndicatorForDeviceEntry).isEqualTo(false) + assertThat(showIndicatorForDeviceEntry).isFalse() } @Test @@ -266,4 +364,25 @@ class DeviceEntrySideFpsOverlayInteractorTest : SysuiTestCase() { true ) } + + private fun TestScope.updateBouncerScene( + isActive: Boolean, + fpsDetectionRunning: Boolean, + isUnlockingWithFpAllowed: Boolean, + ) { + kosmos.sceneInteractor.changeScene( + if (isActive) Scenes.Bouncer else Scenes.Lockscreen, + "reason" + ) + + whenever(keyguardUpdateMonitor.isFingerprintDetectionRunning) + .thenReturn(fpsDetectionRunning) + whenever(keyguardUpdateMonitor.isUnlockingWithFingerprintAllowed) + .thenReturn(isUnlockingWithFpAllowed) + mContext.orCreateTestableResources.addOverride( + R.bool.config_show_sidefps_hint_on_bouncer, + true + ) + runCurrent() + } } |