Introduce bouncer delay behind flag
Whenever the flag is enabled, the 250ms bouncer delay is enabled as long as face auth is enrolled and could run or if active unlock (regardless of whether it's actually available) could've run based on the device state. This doesn't yet use the true active unlock available signal yet since the API isn't available. Test: atest PrimaryBouncerInteractorTest Bug: 267322286 Change-Id: I1f87d2e4848f112880dad64995309ed384407b63
This commit is contained in:
@@ -889,4 +889,8 @@
|
||||
-->
|
||||
<dimen name="shade_swipe_collapse_threshold">0.5</dimen>
|
||||
<!-- [END] MULTI SHADE -->
|
||||
|
||||
<!-- Time (in ms) to delay the bouncer views from showing when passive auth may be used for
|
||||
device entry. -->
|
||||
<integer name="primary_bouncer_passive_auth_delay">250</integer>
|
||||
</resources>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -46,8 +46,6 @@ interface KeyguardFaceAuthModule {
|
||||
impl: SystemUIKeyguardFaceAuthInteractor
|
||||
): KeyguardFaceAuthInteractor
|
||||
|
||||
@Binds fun trustRepository(impl: TrustRepositoryImpl): TrustRepository
|
||||
|
||||
companion object {
|
||||
@Provides
|
||||
@SysUISingleton
|
||||
|
||||
@@ -45,4 +45,6 @@ interface KeyguardRepositoryModule {
|
||||
|
||||
@Binds
|
||||
fun keyguardBouncerRepository(impl: KeyguardBouncerRepositoryImpl): KeyguardBouncerRepository
|
||||
|
||||
@Binds fun trustRepository(impl: TrustRepositoryImpl): TrustRepository
|
||||
}
|
||||
|
||||
@@ -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<Boolean>
|
||||
|
||||
/** Flow representing whether active unlock is available for the current user. */
|
||||
val isCurrentUserActiveUnlockAvailable: StateFlow<Boolean>
|
||||
}
|
||||
|
||||
@SysUISingleton
|
||||
@@ -89,11 +94,13 @@ constructor(
|
||||
}
|
||||
.shareIn(applicationScope, started = SharingStarted.Eagerly, replay = 1)
|
||||
|
||||
override val isCurrentUserTrusted: Flow<Boolean>
|
||||
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<Boolean> =
|
||||
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<Boolean> = MutableStateFlow(true)
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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(),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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<Boolean>
|
||||
get() = _isCurrentUserTrusted
|
||||
|
||||
private val _isCurrentUserActiveUnlockAvailable = MutableStateFlow(false)
|
||||
override val isCurrentUserActiveUnlockAvailable: StateFlow<Boolean> =
|
||||
_isCurrentUserActiveUnlockAvailable.asStateFlow()
|
||||
|
||||
fun setCurrentUserTrusted(trust: Boolean) {
|
||||
_isCurrentUserTrusted.value = trust
|
||||
}
|
||||
|
||||
fun setCurrentUserActiveUnlockAvailable(available: Boolean) {
|
||||
_isCurrentUserActiveUnlockAvailable.value = available
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user