diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index 1602189297734..1252695d6bbba 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -889,4 +889,8 @@ --> 0.5 + + + 250 diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index 7d7b276fbe448..c1f70fbe8875c 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -2884,7 +2884,19 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE); } + /** + * If the current state of the device allows for triggering active unlock. This does not + * include active unlock availability. + */ + public boolean canTriggerActiveUnlockBasedOnDeviceState() { + return shouldTriggerActiveUnlock(/* shouldLog */ false); + } + private boolean shouldTriggerActiveUnlock() { + return shouldTriggerActiveUnlock(/* shouldLog */ true); + } + + private boolean shouldTriggerActiveUnlock(boolean shouldLog) { // Triggers: final boolean triggerActiveUnlockForAssistant = shouldTriggerActiveUnlockForAssistant(); final boolean awakeKeyguard = mPrimaryBouncerFullyShown || mAlternateBouncerShowing @@ -2914,19 +2926,21 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab && !mKeyguardGoingAway && !mSecureCameraLaunched; - // Aggregate relevant fields for debug logging. - logListenerModelData( - new KeyguardActiveUnlockModel( - System.currentTimeMillis(), - user, - shouldTriggerActiveUnlock, - awakeKeyguard, - mAuthInterruptActive, - fpLockedOut, - primaryAuthRequired, - mSwitchingUser, - triggerActiveUnlockForAssistant, - userCanDismissLockScreen)); + if (shouldLog) { + // Aggregate relevant fields for debug logging. + logListenerModelData( + new KeyguardActiveUnlockModel( + System.currentTimeMillis(), + user, + shouldTriggerActiveUnlock, + awakeKeyguard, + mAuthInterruptActive, + fpLockedOut, + primaryAuthRequired, + mSwitchingUser, + triggerActiveUnlockForAssistant, + userCanDismissLockScreen)); + } return shouldTriggerActiveUnlock; } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardFaceAuthModule.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardFaceAuthModule.kt index ef8b40191149f..ee0eb2d90aa77 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardFaceAuthModule.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardFaceAuthModule.kt @@ -46,8 +46,6 @@ interface KeyguardFaceAuthModule { impl: SystemUIKeyguardFaceAuthInteractor ): KeyguardFaceAuthInteractor - @Binds fun trustRepository(impl: TrustRepositoryImpl): TrustRepository - companion object { @Provides @SysUISingleton diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryModule.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryModule.kt index f27f89995dbd8..e7b9af62dacf2 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryModule.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryModule.kt @@ -45,4 +45,6 @@ interface KeyguardRepositoryModule { @Binds fun keyguardBouncerRepository(impl: KeyguardBouncerRepositoryImpl): KeyguardBouncerRepository + + @Binds fun trustRepository(impl: TrustRepositoryImpl): TrustRepository } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/TrustRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/TrustRepository.kt index d90f328719bbe..74c552085be6e 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/TrustRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/TrustRepository.kt @@ -28,7 +28,9 @@ import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.map @@ -40,6 +42,9 @@ import kotlinx.coroutines.flow.shareIn interface TrustRepository { /** Flow representing whether the current user is trusted. */ val isCurrentUserTrusted: Flow + + /** Flow representing whether active unlock is available for the current user. */ + val isCurrentUserActiveUnlockAvailable: StateFlow } @SysUISingleton @@ -89,11 +94,13 @@ constructor( } .shareIn(applicationScope, started = SharingStarted.Eagerly, replay = 1) - override val isCurrentUserTrusted: Flow - get() = - combine(trust, userRepository.selectedUserInfo, ::Pair) - .map { latestTrustModelForUser[it.second.id]?.isTrusted ?: false } - .distinctUntilChanged() - .onEach { logger.isCurrentUserTrusted(it) } - .onStart { emit(false) } + override val isCurrentUserTrusted: Flow = + combine(trust, userRepository.selectedUserInfo, ::Pair) + .map { latestTrustModelForUser[it.second.id]?.isTrusted ?: false } + .distinctUntilChanged() + .onEach { logger.isCurrentUserTrusted(it) } + .onStart { emit(false) } + + // TODO: Implement based on TrustManager callback b/267322286 + override val isCurrentUserActiveUnlockAvailable: StateFlow = MutableStateFlow(true) } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt index 970d00403f28d..110bcd715be22 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt @@ -32,14 +32,16 @@ import com.android.systemui.R import com.android.systemui.classifier.FalsingCollector import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main +import com.android.systemui.flags.FeatureFlags +import com.android.systemui.flags.Flags import com.android.systemui.keyguard.DismissCallbackRegistry import com.android.systemui.keyguard.data.BouncerView import com.android.systemui.keyguard.data.repository.KeyguardBouncerRepository +import com.android.systemui.keyguard.data.repository.TrustRepository import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants import com.android.systemui.keyguard.shared.model.BouncerShowMessageModel import com.android.systemui.plugins.ActivityStarter import com.android.systemui.shared.system.SysUiStatsLog -import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.statusbar.policy.KeyguardStateController import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine @@ -56,28 +58,21 @@ import javax.inject.Inject class PrimaryBouncerInteractor @Inject constructor( - private val repository: KeyguardBouncerRepository, - private val primaryBouncerView: BouncerView, - @Main private val mainHandler: Handler, - private val keyguardStateController: KeyguardStateController, - private val keyguardSecurityModel: KeyguardSecurityModel, - private val primaryBouncerCallbackInteractor: PrimaryBouncerCallbackInteractor, - private val falsingCollector: FalsingCollector, - private val dismissCallbackRegistry: DismissCallbackRegistry, - private val context: Context, - private val keyguardUpdateMonitor: KeyguardUpdateMonitor, - keyguardBypassController: KeyguardBypassController, + private val repository: KeyguardBouncerRepository, + private val primaryBouncerView: BouncerView, + @Main private val mainHandler: Handler, + private val keyguardStateController: KeyguardStateController, + private val keyguardSecurityModel: KeyguardSecurityModel, + private val primaryBouncerCallbackInteractor: PrimaryBouncerCallbackInteractor, + private val falsingCollector: FalsingCollector, + private val dismissCallbackRegistry: DismissCallbackRegistry, + private val context: Context, + private val keyguardUpdateMonitor: KeyguardUpdateMonitor, + private val trustRepository: TrustRepository, + private val featureFlags: FeatureFlags, ) { - /** Whether we want to wait for face auth. */ - private val primaryBouncerFaceDelay = - keyguardStateController.isFaceAuthEnabled && - !keyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible( - KeyguardUpdateMonitor.getCurrentUser() - ) && - !needsFullscreenBouncer() && - keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(BiometricSourceType.FACE) && - !keyguardBypassController.bypassEnabled - + private val passiveAuthBouncerDelay = context.resources.getInteger( + R.integer.primary_bouncer_passive_auth_delay).toLong() /** Runnable to show the primary bouncer. */ val showRunnable = Runnable { repository.setPrimaryShow(true) @@ -160,8 +155,9 @@ constructor( } repository.setPrimaryShowingSoon(true) - if (primaryBouncerFaceDelay) { - mainHandler.postDelayed(showRunnable, 1200L) + if (usePrimaryBouncerPassiveAuthDelay()) { + Log.d(TAG, "delay bouncer, passive auth may succeed") + mainHandler.postDelayed(showRunnable, passiveAuthBouncerDelay) } else { DejankUtils.postAfterTraversal(showRunnable) } @@ -377,6 +373,17 @@ constructor( return repository.primaryBouncerShow.value } + /** Whether we want to wait to show the bouncer in case passive auth succeeds. */ + private fun usePrimaryBouncerPassiveAuthDelay(): Boolean { + val canRunFaceAuth = keyguardStateController.isFaceAuthEnabled && + keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(BiometricSourceType.FACE) + val canRunActiveUnlock = trustRepository.isCurrentUserActiveUnlockAvailable.value && + keyguardUpdateMonitor.canTriggerActiveUnlockBasedOnDeviceState() + return featureFlags.isEnabled(Flags.DELAY_BOUNCER) && + !needsFullscreenBouncer() && + (canRunFaceAuth || canRunActiveUnlock) + } + companion object { private const val TAG = "PrimaryBouncerInteractor" } diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerWithCoroutinesTest.kt index 8bf32cf399633..8f6017cd2a7ca 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerWithCoroutinesTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerWithCoroutinesTest.kt @@ -21,22 +21,23 @@ import android.testing.TestableLooper import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.keyguard.KeyguardSecurityModel +import com.android.systemui.RoboPilotTest import com.android.systemui.classifier.FalsingCollector +import com.android.systemui.flags.FakeFeatureFlags import com.android.systemui.keyguard.DismissCallbackRegistry import com.android.systemui.keyguard.data.BouncerView import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository import com.android.systemui.keyguard.data.repository.DeviceEntryFingerprintAuthRepository import com.android.systemui.keyguard.data.repository.KeyguardBouncerRepository import com.android.systemui.keyguard.data.repository.KeyguardBouncerRepositoryImpl +import com.android.systemui.keyguard.data.repository.TrustRepository import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.plugins.statusbar.StatusBarStateController -import com.android.systemui.RoboPilotTest import com.android.systemui.statusbar.StatusBarState -import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.util.time.FakeSystemClock import com.android.systemui.util.time.SystemClock @@ -94,7 +95,8 @@ class UdfpsKeyguardViewControllerWithCoroutinesTest : UdfpsKeyguardViewControlle mock(DismissCallbackRegistry::class.java), context, mKeyguardUpdateMonitor, - mock(KeyguardBypassController::class.java), + mock(TrustRepository::class.java), + FakeFeatureFlags(), ) mAlternateBouncerInteractor = AlternateBouncerInteractor( diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt index 5da1a846fbfd5..e261982dfd180 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt @@ -35,12 +35,12 @@ import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFaceAuthRepo import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintAuthRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository +import com.android.systemui.keyguard.data.repository.TrustRepository import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.shared.model.TransitionStep import com.android.systemui.log.FaceAuthenticationLogger import com.android.systemui.plugins.statusbar.StatusBarStateController -import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.util.time.FakeSystemClock import com.google.common.truth.Truth.assertThat @@ -100,7 +100,8 @@ class KeyguardFaceAuthInteractorTest : SysuiTestCase() { mock(DismissCallbackRegistry::class.java), context, keyguardUpdateMonitor, - mock(KeyguardBypassController::class.java), + mock(TrustRepository::class.java), + FakeFeatureFlags(), ), AlternateBouncerInteractor( mock(StatusBarStateController::class.java), diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt index 24a47b014152f..eed1e739b9091 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt @@ -16,7 +16,7 @@ package com.android.systemui.keyguard.domain.interactor -import android.os.Looper +import android.hardware.biometrics.BiometricSourceType import android.testing.AndroidTestingRunner import android.testing.TestableLooper.RunWithLooper import android.testing.TestableResources @@ -28,15 +28,17 @@ import com.android.systemui.DejankUtils import com.android.systemui.R import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingCollector +import com.android.systemui.flags.FakeFeatureFlags +import com.android.systemui.flags.Flags import com.android.systemui.keyguard.DismissCallbackRegistry import com.android.systemui.keyguard.data.BouncerView import com.android.systemui.keyguard.data.BouncerViewDelegate +import com.android.systemui.keyguard.data.repository.FakeTrustRepository import com.android.systemui.keyguard.data.repository.KeyguardBouncerRepository import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.EXPANSION_HIDDEN import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.EXPANSION_VISIBLE import com.android.systemui.keyguard.shared.model.BouncerShowMessageModel import com.android.systemui.plugins.ActivityStarter -import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.whenever @@ -67,16 +69,23 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() { @Mock private lateinit var mPrimaryBouncerCallbackInteractor: PrimaryBouncerCallbackInteractor @Mock private lateinit var falsingCollector: FalsingCollector @Mock private lateinit var dismissCallbackRegistry: DismissCallbackRegistry - @Mock private lateinit var keyguardBypassController: KeyguardBypassController @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor - private val mainHandler = FakeHandler(Looper.getMainLooper()) + private lateinit var mainHandler: FakeHandler private lateinit var underTest: PrimaryBouncerInteractor private lateinit var resources: TestableResources + private lateinit var trustRepository: FakeTrustRepository + private lateinit var featureFlags: FakeFeatureFlags @Before fun setUp() { MockitoAnnotations.initMocks(this) + whenever(keyguardSecurityModel.getSecurityMode(anyInt())) + .thenReturn(KeyguardSecurityModel.SecurityMode.PIN) + DejankUtils.setImmediate(true) + mainHandler = FakeHandler(android.os.Looper.getMainLooper()) + trustRepository = FakeTrustRepository() + featureFlags = FakeFeatureFlags().apply { set(Flags.DELAY_BOUNCER, false) } underTest = PrimaryBouncerInteractor( repository, @@ -89,7 +98,8 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() { dismissCallbackRegistry, context, keyguardUpdateMonitor, - keyguardBypassController, + trustRepository, + featureFlags, ) whenever(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(null) whenever(repository.primaryBouncerShow.value).thenReturn(false) @@ -383,6 +393,55 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() { verify(repository).setSideFpsShowing(false) } + @Test + fun delayBouncerWhenFaceAuthPossible() { + mainHandler.setMode(FakeHandler.Mode.QUEUEING) + + // GIVEN bouncer should be delayed due to face auth + featureFlags.apply { set(Flags.DELAY_BOUNCER, true) } + whenever(keyguardStateController.isFaceAuthEnabled).thenReturn(true) + whenever(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(BiometricSourceType.FACE)) + .thenReturn(true) + + // WHEN bouncer show is requested + underTest.show(true) + + // THEN primary show & primary showing soon aren't updated immediately + verify(repository, never()).setPrimaryShow(true) + verify(repository, never()).setPrimaryShowingSoon(false) + + // WHEN all queued messages are dispatched + mainHandler.dispatchQueuedMessages() + + // THEN primary show & primary showing soon are updated + verify(repository).setPrimaryShow(true) + verify(repository).setPrimaryShowingSoon(false) + } + + @Test + fun delayBouncerWhenActiveUnlockPossible() { + mainHandler.setMode(FakeHandler.Mode.QUEUEING) + + // GIVEN bouncer should be delayed due to active unlock + featureFlags.apply { set(Flags.DELAY_BOUNCER, true) } + trustRepository.setCurrentUserActiveUnlockAvailable(true) + whenever(keyguardUpdateMonitor.canTriggerActiveUnlockBasedOnDeviceState()).thenReturn(true) + + // WHEN bouncer show is requested + underTest.show(true) + + // THEN primary show & primary showing soon were scheduled to update + verify(repository, never()).setPrimaryShow(true) + verify(repository, never()).setPrimaryShowingSoon(false) + + // WHEN all queued messages are dispatched + mainHandler.dispatchQueuedMessages() + + // THEN primary show & primary showing soon are updated + verify(repository).setPrimaryShow(true) + verify(repository).setPrimaryShowingSoon(false) + } + private fun updateSideFpsVisibilityParameters( isVisible: Boolean, sfpsEnabled: Boolean, diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt index e35e97109a3fe..5056b43798d20 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt @@ -25,9 +25,11 @@ import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingCollector import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.flags.FakeFeatureFlags import com.android.systemui.keyguard.DismissCallbackRegistry import com.android.systemui.keyguard.data.BouncerView import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository +import com.android.systemui.keyguard.data.repository.TrustRepository import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.utils.os.FakeHandler @@ -37,6 +39,7 @@ import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock +import org.mockito.Mockito import org.mockito.MockitoAnnotations @SmallTest @@ -71,7 +74,8 @@ class PrimaryBouncerInteractorWithCoroutinesTest : SysuiTestCase() { dismissCallbackRegistry, context, keyguardUpdateMonitor, - keyguardBypassController, + Mockito.mock(TrustRepository::class.java), + FakeFeatureFlags(), ) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModelTest.kt index 0e9c99e7ba6c8..e9f1ac103f87c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModelTest.kt @@ -24,9 +24,11 @@ import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingCollector +import com.android.systemui.flags.FakeFeatureFlags import com.android.systemui.keyguard.DismissCallbackRegistry import com.android.systemui.keyguard.data.BouncerView import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository +import com.android.systemui.keyguard.data.repository.TrustRepository import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor import com.android.systemui.keyguard.shared.model.BouncerShowMessageModel @@ -42,6 +44,7 @@ import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock +import org.mockito.Mockito import org.mockito.MockitoAnnotations @SmallTest @@ -77,7 +80,8 @@ class KeyguardBouncerViewModelTest : SysuiTestCase() { dismissCallbackRegistry, context, keyguardUpdateMonitor, - keyguardBypassController, + Mockito.mock(TrustRepository::class.java), + FakeFeatureFlags(), ) underTest = KeyguardBouncerViewModel(bouncerView, bouncerInteractor) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeTrustRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeTrustRepository.kt index 6690de87d0a29..f0dbc60cae1cc 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeTrustRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeTrustRepository.kt @@ -19,13 +19,23 @@ package com.android.systemui.keyguard.data.repository import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow class FakeTrustRepository : TrustRepository { private val _isCurrentUserTrusted = MutableStateFlow(false) override val isCurrentUserTrusted: Flow get() = _isCurrentUserTrusted + private val _isCurrentUserActiveUnlockAvailable = MutableStateFlow(false) + override val isCurrentUserActiveUnlockAvailable: StateFlow = + _isCurrentUserActiveUnlockAvailable.asStateFlow() + fun setCurrentUserTrusted(trust: Boolean) { _isCurrentUserTrusted.value = trust } + + fun setCurrentUserActiveUnlockAvailable(available: Boolean) { + _isCurrentUserActiveUnlockAvailable.value = available + } }