Loading packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/OccludingAppDeviceEntryInteractor.kt +35 −21 Original line number Diff line number Diff line Loading @@ -22,10 +22,14 @@ import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags import com.android.systemui.keyguard.data.repository.DeviceEntryFingerprintAuthRepository import com.android.systemui.keyguard.shared.model.ErrorFingerprintAuthenticationStatus import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus import com.android.systemui.plugins.ActivityStarter import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.util.kotlin.sample import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi Loading Loading @@ -55,6 +59,8 @@ constructor( @Application scope: CoroutineScope, private val context: Context, activityStarter: ActivityStarter, powerInteractor: PowerInteractor, featureFlags: FeatureFlags, ) { private val keyguardOccludedByApp: Flow<Boolean> = combine( Loading Loading @@ -87,14 +93,21 @@ constructor( .ifKeyguardOccludedByApp(/* elseFlow */ flowOf(null)) init { if (featureFlags.isEnabled(Flags.FP_LISTEN_OCCLUDING_APPS)) { scope.launch { // On fingerprint success, go to the home screen fingerprintUnlockSuccessEvents.collect { goToHomeScreen() } // On fingerprint success when the screen is on, go to the home screen fingerprintUnlockSuccessEvents.sample(powerInteractor.isInteractive).collect { if (it) { goToHomeScreen() } // don't go to the home screen if the authentication is from AOD/dozing/off } } scope.launch { // On device fingerprint lockout, request the bouncer with a runnable to // go to the home screen. Without this, the bouncer won't proceed to the home screen. // go to the home screen. Without this, the bouncer won't proceed to the home // screen. fingerprintLockoutEvents.collect { activityStarter.dismissKeyguardThenExecute( object : ActivityStarter.OnDismissAction { Loading @@ -113,6 +126,7 @@ constructor( } } } } /** Launches an Activity which forces the current app to background by going home. */ private fun goToHomeScreen() { Loading packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/OccludingAppDeviceEntryInteractorTest.kt +25 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,8 @@ import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticati import com.android.systemui.keyguard.util.IndicationHelper import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.ActivityStarter.OnDismissAction import com.android.systemui.power.data.repository.FakePowerRepository import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever Loading Loading @@ -80,6 +82,7 @@ class OccludingAppDeviceEntryInteractorTest : SysuiTestCase() { private lateinit var configurationRepository: FakeConfigurationRepository private lateinit var featureFlags: FakeFeatureFlags private lateinit var trustRepository: FakeTrustRepository private lateinit var powerRepository: FakePowerRepository @Mock private lateinit var indicationHelper: IndicationHelper @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor Loading @@ -102,6 +105,7 @@ class OccludingAppDeviceEntryInteractorTest : SysuiTestCase() { set(Flags.DELAY_BOUNCER, false) } trustRepository = FakeTrustRepository() powerRepository = FakePowerRepository() underTest = OccludingAppDeviceEntryInteractor( BiometricMessageInteractor( Loading Loading @@ -145,6 +149,14 @@ class OccludingAppDeviceEntryInteractorTest : SysuiTestCase() { testScope.backgroundScope, mockedContext, activityStarter, PowerInteractor( powerRepository, keyguardRepository, falsingCollector = mock(), screenOffAnimationController = mock(), statusBarStateController = mock(), ), FakeFeatureFlags().apply { set(Flags.FP_LISTEN_OCCLUDING_APPS, true) }, ) } Loading @@ -159,6 +171,18 @@ class OccludingAppDeviceEntryInteractorTest : SysuiTestCase() { verifyGoToHomeScreen() } @Test fun fingerprintSuccess_notInteractive_doesNotGoToHomeScreen() = testScope.runTest { givenOnOccludingApp(true) powerRepository.setInteractive(false) fingerprintAuthRepository.setAuthenticationStatus( SuccessFingerprintAuthenticationStatus(0, true) ) runCurrent() verifyNeverGoToHomeScreen() } @Test fun fingerprintSuccess_notOnOccludingApp_doesNotGoToHomeScreen() = testScope.runTest { Loading Loading @@ -291,6 +315,7 @@ class OccludingAppDeviceEntryInteractorTest : SysuiTestCase() { } private fun givenOnOccludingApp(isOnOccludingApp: Boolean) { powerRepository.setInteractive(true) keyguardRepository.setKeyguardOccluded(isOnOccludingApp) keyguardRepository.setKeyguardShowing(isOnOccludingApp) bouncerRepository.setPrimaryShow(!isOnOccludingApp) Loading Loading
packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/OccludingAppDeviceEntryInteractor.kt +35 −21 Original line number Diff line number Diff line Loading @@ -22,10 +22,14 @@ import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags import com.android.systemui.keyguard.data.repository.DeviceEntryFingerprintAuthRepository import com.android.systemui.keyguard.shared.model.ErrorFingerprintAuthenticationStatus import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus import com.android.systemui.plugins.ActivityStarter import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.util.kotlin.sample import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi Loading Loading @@ -55,6 +59,8 @@ constructor( @Application scope: CoroutineScope, private val context: Context, activityStarter: ActivityStarter, powerInteractor: PowerInteractor, featureFlags: FeatureFlags, ) { private val keyguardOccludedByApp: Flow<Boolean> = combine( Loading Loading @@ -87,14 +93,21 @@ constructor( .ifKeyguardOccludedByApp(/* elseFlow */ flowOf(null)) init { if (featureFlags.isEnabled(Flags.FP_LISTEN_OCCLUDING_APPS)) { scope.launch { // On fingerprint success, go to the home screen fingerprintUnlockSuccessEvents.collect { goToHomeScreen() } // On fingerprint success when the screen is on, go to the home screen fingerprintUnlockSuccessEvents.sample(powerInteractor.isInteractive).collect { if (it) { goToHomeScreen() } // don't go to the home screen if the authentication is from AOD/dozing/off } } scope.launch { // On device fingerprint lockout, request the bouncer with a runnable to // go to the home screen. Without this, the bouncer won't proceed to the home screen. // go to the home screen. Without this, the bouncer won't proceed to the home // screen. fingerprintLockoutEvents.collect { activityStarter.dismissKeyguardThenExecute( object : ActivityStarter.OnDismissAction { Loading @@ -113,6 +126,7 @@ constructor( } } } } /** Launches an Activity which forces the current app to background by going home. */ private fun goToHomeScreen() { Loading
packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/OccludingAppDeviceEntryInteractorTest.kt +25 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,8 @@ import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticati import com.android.systemui.keyguard.util.IndicationHelper import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.ActivityStarter.OnDismissAction import com.android.systemui.power.data.repository.FakePowerRepository import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever Loading Loading @@ -80,6 +82,7 @@ class OccludingAppDeviceEntryInteractorTest : SysuiTestCase() { private lateinit var configurationRepository: FakeConfigurationRepository private lateinit var featureFlags: FakeFeatureFlags private lateinit var trustRepository: FakeTrustRepository private lateinit var powerRepository: FakePowerRepository @Mock private lateinit var indicationHelper: IndicationHelper @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor Loading @@ -102,6 +105,7 @@ class OccludingAppDeviceEntryInteractorTest : SysuiTestCase() { set(Flags.DELAY_BOUNCER, false) } trustRepository = FakeTrustRepository() powerRepository = FakePowerRepository() underTest = OccludingAppDeviceEntryInteractor( BiometricMessageInteractor( Loading Loading @@ -145,6 +149,14 @@ class OccludingAppDeviceEntryInteractorTest : SysuiTestCase() { testScope.backgroundScope, mockedContext, activityStarter, PowerInteractor( powerRepository, keyguardRepository, falsingCollector = mock(), screenOffAnimationController = mock(), statusBarStateController = mock(), ), FakeFeatureFlags().apply { set(Flags.FP_LISTEN_OCCLUDING_APPS, true) }, ) } Loading @@ -159,6 +171,18 @@ class OccludingAppDeviceEntryInteractorTest : SysuiTestCase() { verifyGoToHomeScreen() } @Test fun fingerprintSuccess_notInteractive_doesNotGoToHomeScreen() = testScope.runTest { givenOnOccludingApp(true) powerRepository.setInteractive(false) fingerprintAuthRepository.setAuthenticationStatus( SuccessFingerprintAuthenticationStatus(0, true) ) runCurrent() verifyNeverGoToHomeScreen() } @Test fun fingerprintSuccess_notOnOccludingApp_doesNotGoToHomeScreen() = testScope.runTest { Loading Loading @@ -291,6 +315,7 @@ class OccludingAppDeviceEntryInteractorTest : SysuiTestCase() { } private fun givenOnOccludingApp(isOnOccludingApp: Boolean) { powerRepository.setInteractive(true) keyguardRepository.setKeyguardOccluded(isOnOccludingApp) keyguardRepository.setKeyguardShowing(isOnOccludingApp) bouncerRepository.setPrimaryShow(!isOnOccludingApp) Loading