Merge "Hookup active unlock running state to bouncer delay logic" into udc-dev
This commit is contained in:
@@ -4395,7 +4395,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
mFingerprintListenBuffer.toList()
|
mFingerprintListenBuffer.toList()
|
||||||
).printTableData(pw);
|
).printTableData(pw);
|
||||||
}
|
}
|
||||||
|
pw.println("ActiveUnlockRunning="
|
||||||
|
+ mTrustManager.isActiveUnlockRunning(KeyguardUpdateMonitor.getCurrentUser()));
|
||||||
new DumpsysTableLogger(
|
new DumpsysTableLogger(
|
||||||
"KeyguardActiveUnlockTriggers",
|
"KeyguardActiveUnlockTriggers",
|
||||||
KeyguardActiveUnlockModel.TABLE_HEADERS,
|
KeyguardActiveUnlockModel.TABLE_HEADERS,
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package com.android.keyguard.logging
|
package com.android.keyguard.logging
|
||||||
|
|
||||||
import com.android.systemui.dagger.SysUISingleton
|
import com.android.systemui.dagger.SysUISingleton
|
||||||
|
import com.android.systemui.keyguard.shared.model.ActiveUnlockModel
|
||||||
import com.android.systemui.keyguard.shared.model.TrustManagedModel
|
import com.android.systemui.keyguard.shared.model.TrustManagedModel
|
||||||
import com.android.systemui.keyguard.shared.model.TrustModel
|
import com.android.systemui.keyguard.shared.model.TrustModel
|
||||||
import com.android.systemui.log.LogBuffer
|
import com.android.systemui.log.LogBuffer
|
||||||
@@ -76,6 +77,18 @@ constructor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun activeUnlockModelEmitted(value: ActiveUnlockModel) {
|
||||||
|
logBuffer.log(
|
||||||
|
TAG,
|
||||||
|
LogLevel.DEBUG,
|
||||||
|
{
|
||||||
|
int1 = value.userId
|
||||||
|
bool1 = value.isRunning
|
||||||
|
},
|
||||||
|
{ "activeUnlockModel emitted: userId: $int1 isRunning: $bool1" }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun isCurrentUserTrusted(isCurrentUserTrusted: Boolean) {
|
fun isCurrentUserTrusted(isCurrentUserTrusted: Boolean) {
|
||||||
logBuffer.log(
|
logBuffer.log(
|
||||||
TAG,
|
TAG,
|
||||||
@@ -85,6 +98,15 @@ constructor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isCurrentUserActiveUnlockRunning(isCurrentUserActiveUnlockRunning: Boolean) {
|
||||||
|
logBuffer.log(
|
||||||
|
TAG,
|
||||||
|
LogLevel.DEBUG,
|
||||||
|
{ bool1 = isCurrentUserActiveUnlockRunning },
|
||||||
|
{ "isCurrentUserActiveUnlockRunning emitted: $bool1" }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun isCurrentUserTrustManaged(isTrustManaged: Boolean) {
|
fun isCurrentUserTrustManaged(isTrustManaged: Boolean) {
|
||||||
logBuffer.log(TAG, DEBUG, { bool1 = isTrustManaged }, { "isTrustManaged emitted: $bool1" })
|
logBuffer.log(TAG, DEBUG, { bool1 = isTrustManaged }, { "isTrustManaged emitted: $bool1" })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLoggin
|
|||||||
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
|
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
|
||||||
import com.android.systemui.dagger.SysUISingleton
|
import com.android.systemui.dagger.SysUISingleton
|
||||||
import com.android.systemui.dagger.qualifiers.Application
|
import com.android.systemui.dagger.qualifiers.Application
|
||||||
|
import com.android.systemui.keyguard.shared.model.ActiveUnlockModel
|
||||||
import com.android.systemui.keyguard.shared.model.TrustManagedModel
|
import com.android.systemui.keyguard.shared.model.TrustManagedModel
|
||||||
import com.android.systemui.keyguard.shared.model.TrustModel
|
import com.android.systemui.keyguard.shared.model.TrustModel
|
||||||
import com.android.systemui.user.data.repository.UserRepository
|
import com.android.systemui.user.data.repository.UserRepository
|
||||||
@@ -29,7 +30,6 @@ import javax.inject.Inject
|
|||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.channels.awaitClose
|
import kotlinx.coroutines.channels.awaitClose
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
|
||||||
import kotlinx.coroutines.flow.SharingStarted
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
@@ -45,8 +45,8 @@ interface TrustRepository {
|
|||||||
/** Flow representing whether the current user is trusted. */
|
/** Flow representing whether the current user is trusted. */
|
||||||
val isCurrentUserTrusted: Flow<Boolean>
|
val isCurrentUserTrusted: Flow<Boolean>
|
||||||
|
|
||||||
/** Flow representing whether active unlock is available for the current user. */
|
/** Flow representing whether active unlock is running for the current user. */
|
||||||
val isCurrentUserActiveUnlockAvailable: StateFlow<Boolean>
|
val isCurrentUserActiveUnlockRunning: Flow<Boolean>
|
||||||
|
|
||||||
/** Reports that whether trust is managed has changed for the current user. */
|
/** Reports that whether trust is managed has changed for the current user. */
|
||||||
val isCurrentUserTrustManaged: StateFlow<Boolean>
|
val isCurrentUserTrustManaged: StateFlow<Boolean>
|
||||||
@@ -62,6 +62,7 @@ constructor(
|
|||||||
private val logger: TrustRepositoryLogger,
|
private val logger: TrustRepositoryLogger,
|
||||||
) : TrustRepository {
|
) : TrustRepository {
|
||||||
private val latestTrustModelForUser = mutableMapOf<Int, TrustModel>()
|
private val latestTrustModelForUser = mutableMapOf<Int, TrustModel>()
|
||||||
|
private val activeUnlockRunningForUser = mutableMapOf<Int, ActiveUnlockModel>()
|
||||||
private val trustManagedForUser = mutableMapOf<Int, TrustManagedModel>()
|
private val trustManagedForUser = mutableMapOf<Int, TrustManagedModel>()
|
||||||
|
|
||||||
private val trust =
|
private val trust =
|
||||||
@@ -87,6 +88,17 @@ constructor(
|
|||||||
|
|
||||||
override fun onEnabledTrustAgentsChanged(userId: Int) = Unit
|
override fun onEnabledTrustAgentsChanged(userId: Int) = Unit
|
||||||
|
|
||||||
|
override fun onIsActiveUnlockRunningChanged(
|
||||||
|
isRunning: Boolean,
|
||||||
|
userId: Int
|
||||||
|
) {
|
||||||
|
trySendWithFailureLogging(
|
||||||
|
ActiveUnlockModel(isRunning, userId),
|
||||||
|
TrustRepositoryLogger.TAG,
|
||||||
|
"onActiveUnlockRunningChanged"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onTrustManagedChanged(isTrustManaged: Boolean, userId: Int) {
|
override fun onTrustManagedChanged(isTrustManaged: Boolean, userId: Int) {
|
||||||
logger.onTrustManagedChanged(isTrustManaged, userId)
|
logger.onTrustManagedChanged(isTrustManaged, userId)
|
||||||
trySendWithFailureLogging(
|
trySendWithFailureLogging(
|
||||||
@@ -95,11 +107,6 @@ constructor(
|
|||||||
"onTrustManagedChanged"
|
"onTrustManagedChanged"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onIsActiveUnlockRunningChanged(
|
|
||||||
isRunning: Boolean,
|
|
||||||
userId: Int
|
|
||||||
) = Unit
|
|
||||||
}
|
}
|
||||||
trustManager.registerTrustListener(callback)
|
trustManager.registerTrustListener(callback)
|
||||||
logger.trustListenerRegistered()
|
logger.trustListenerRegistered()
|
||||||
@@ -114,6 +121,10 @@ constructor(
|
|||||||
latestTrustModelForUser[it.userId] = it
|
latestTrustModelForUser[it.userId] = it
|
||||||
logger.trustModelEmitted(it)
|
logger.trustModelEmitted(it)
|
||||||
}
|
}
|
||||||
|
is ActiveUnlockModel -> {
|
||||||
|
activeUnlockRunningForUser[it.userId] = it
|
||||||
|
logger.activeUnlockModelEmitted(it)
|
||||||
|
}
|
||||||
is TrustManagedModel -> {
|
is TrustManagedModel -> {
|
||||||
trustManagedForUser[it.userId] = it
|
trustManagedForUser[it.userId] = it
|
||||||
logger.trustManagedModelEmitted(it)
|
logger.trustManagedModelEmitted(it)
|
||||||
@@ -122,8 +133,17 @@ constructor(
|
|||||||
}
|
}
|
||||||
.shareIn(applicationScope, started = SharingStarted.Eagerly, replay = 1)
|
.shareIn(applicationScope, started = SharingStarted.Eagerly, replay = 1)
|
||||||
|
|
||||||
// TODO: Implement based on TrustManager callback b/267322286
|
override val isCurrentUserActiveUnlockRunning: Flow<Boolean> =
|
||||||
override val isCurrentUserActiveUnlockAvailable: StateFlow<Boolean> = MutableStateFlow(true)
|
combine(trust, userRepository.selectedUserInfo, ::Pair)
|
||||||
|
.map { activeUnlockRunningForUser[it.second.id]?.isRunning ?: false }
|
||||||
|
.distinctUntilChanged()
|
||||||
|
.onEach { logger.isCurrentUserActiveUnlockRunning(it) }
|
||||||
|
.onStart {
|
||||||
|
emit(
|
||||||
|
activeUnlockRunningForUser[userRepository.getSelectedUserInfo().id]?.isRunning
|
||||||
|
?: false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
override val isCurrentUserTrustManaged: StateFlow<Boolean>
|
override val isCurrentUserTrustManaged: StateFlow<Boolean>
|
||||||
get() =
|
get() =
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import com.android.systemui.DejankUtils
|
|||||||
import com.android.systemui.R
|
import com.android.systemui.R
|
||||||
import com.android.systemui.classifier.FalsingCollector
|
import com.android.systemui.classifier.FalsingCollector
|
||||||
import com.android.systemui.dagger.SysUISingleton
|
import com.android.systemui.dagger.SysUISingleton
|
||||||
|
import com.android.systemui.dagger.qualifiers.Application
|
||||||
import com.android.systemui.dagger.qualifiers.Main
|
import com.android.systemui.dagger.qualifiers.Main
|
||||||
import com.android.systemui.flags.FeatureFlags
|
import com.android.systemui.flags.FeatureFlags
|
||||||
import com.android.systemui.flags.Flags
|
import com.android.systemui.flags.Flags
|
||||||
@@ -43,11 +44,14 @@ import com.android.systemui.keyguard.shared.model.BouncerShowMessageModel
|
|||||||
import com.android.systemui.plugins.ActivityStarter
|
import com.android.systemui.plugins.ActivityStarter
|
||||||
import com.android.systemui.shared.system.SysUiStatsLog
|
import com.android.systemui.shared.system.SysUiStatsLog
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.collect
|
||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.filter
|
import kotlinx.coroutines.flow.filter
|
||||||
import kotlinx.coroutines.flow.filterNotNull
|
import kotlinx.coroutines.flow.filterNotNull
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -58,18 +62,19 @@ import javax.inject.Inject
|
|||||||
class PrimaryBouncerInteractor
|
class PrimaryBouncerInteractor
|
||||||
@Inject
|
@Inject
|
||||||
constructor(
|
constructor(
|
||||||
private val repository: KeyguardBouncerRepository,
|
private val repository: KeyguardBouncerRepository,
|
||||||
private val primaryBouncerView: BouncerView,
|
private val primaryBouncerView: BouncerView,
|
||||||
@Main private val mainHandler: Handler,
|
@Main private val mainHandler: Handler,
|
||||||
private val keyguardStateController: KeyguardStateController,
|
private val keyguardStateController: KeyguardStateController,
|
||||||
private val keyguardSecurityModel: KeyguardSecurityModel,
|
private val keyguardSecurityModel: KeyguardSecurityModel,
|
||||||
private val primaryBouncerCallbackInteractor: PrimaryBouncerCallbackInteractor,
|
private val primaryBouncerCallbackInteractor: PrimaryBouncerCallbackInteractor,
|
||||||
private val falsingCollector: FalsingCollector,
|
private val falsingCollector: FalsingCollector,
|
||||||
private val dismissCallbackRegistry: DismissCallbackRegistry,
|
private val dismissCallbackRegistry: DismissCallbackRegistry,
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
|
private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
|
||||||
private val trustRepository: TrustRepository,
|
private val trustRepository: TrustRepository,
|
||||||
private val featureFlags: FeatureFlags,
|
private val featureFlags: FeatureFlags,
|
||||||
|
@Application private val applicationScope: CoroutineScope,
|
||||||
) {
|
) {
|
||||||
private val passiveAuthBouncerDelay = context.resources.getInteger(
|
private val passiveAuthBouncerDelay = context.resources.getInteger(
|
||||||
R.integer.primary_bouncer_passive_auth_delay).toLong()
|
R.integer.primary_bouncer_passive_auth_delay).toLong()
|
||||||
@@ -104,6 +109,7 @@ constructor(
|
|||||||
/** Allow for interaction when just about fully visible */
|
/** Allow for interaction when just about fully visible */
|
||||||
val isInteractable: Flow<Boolean> = bouncerExpansion.map { it > 0.9 }
|
val isInteractable: Flow<Boolean> = bouncerExpansion.map { it > 0.9 }
|
||||||
val sideFpsShowing: Flow<Boolean> = repository.sideFpsShowing
|
val sideFpsShowing: Flow<Boolean> = repository.sideFpsShowing
|
||||||
|
private var currentUserActiveUnlockRunning = false
|
||||||
|
|
||||||
/** This callback needs to be a class field so it does not get garbage collected. */
|
/** This callback needs to be a class field so it does not get garbage collected. */
|
||||||
val keyguardUpdateMonitorCallback =
|
val keyguardUpdateMonitorCallback =
|
||||||
@@ -122,6 +128,13 @@ constructor(
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback)
|
keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback)
|
||||||
|
if (featureFlags.isEnabled(Flags.DELAY_BOUNCER)) {
|
||||||
|
applicationScope.launch {
|
||||||
|
trustRepository.isCurrentUserActiveUnlockRunning.collect {
|
||||||
|
currentUserActiveUnlockRunning = it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(b/243685699): Move isScrimmed logic to data layer.
|
// TODO(b/243685699): Move isScrimmed logic to data layer.
|
||||||
@@ -377,8 +390,9 @@ constructor(
|
|||||||
private fun usePrimaryBouncerPassiveAuthDelay(): Boolean {
|
private fun usePrimaryBouncerPassiveAuthDelay(): Boolean {
|
||||||
val canRunFaceAuth = keyguardStateController.isFaceAuthEnabled &&
|
val canRunFaceAuth = keyguardStateController.isFaceAuthEnabled &&
|
||||||
keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(BiometricSourceType.FACE)
|
keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(BiometricSourceType.FACE)
|
||||||
val canRunActiveUnlock = trustRepository.isCurrentUserActiveUnlockAvailable.value &&
|
val canRunActiveUnlock = currentUserActiveUnlockRunning &&
|
||||||
keyguardUpdateMonitor.canTriggerActiveUnlockBasedOnDeviceState()
|
keyguardUpdateMonitor.canTriggerActiveUnlockBasedOnDeviceState()
|
||||||
|
|
||||||
return featureFlags.isEnabled(Flags.DELAY_BOUNCER) &&
|
return featureFlags.isEnabled(Flags.DELAY_BOUNCER) &&
|
||||||
!needsFullscreenBouncer() &&
|
!needsFullscreenBouncer() &&
|
||||||
(canRunFaceAuth || canRunActiveUnlock)
|
(canRunFaceAuth || canRunActiveUnlock)
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 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.shared.model
|
||||||
|
|
||||||
|
/** Represents the active unlock state */
|
||||||
|
data class ActiveUnlockModel(
|
||||||
|
/** If true, the system believes active unlock is available and can be usd to unlock. */
|
||||||
|
val isRunning: Boolean,
|
||||||
|
/** The user, for which active unlock may be running. */
|
||||||
|
val userId: Int,
|
||||||
|
)
|
||||||
@@ -24,13 +24,14 @@ import com.android.keyguard.KeyguardSecurityModel
|
|||||||
import com.android.systemui.RoboPilotTest
|
import com.android.systemui.RoboPilotTest
|
||||||
import com.android.systemui.classifier.FalsingCollector
|
import com.android.systemui.classifier.FalsingCollector
|
||||||
import com.android.systemui.flags.FakeFeatureFlags
|
import com.android.systemui.flags.FakeFeatureFlags
|
||||||
|
import com.android.systemui.flags.Flags
|
||||||
import com.android.systemui.keyguard.DismissCallbackRegistry
|
import com.android.systemui.keyguard.DismissCallbackRegistry
|
||||||
import com.android.systemui.keyguard.data.BouncerView
|
import com.android.systemui.keyguard.data.BouncerView
|
||||||
import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository
|
import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository
|
||||||
import com.android.systemui.keyguard.data.repository.DeviceEntryFingerprintAuthRepository
|
import com.android.systemui.keyguard.data.repository.DeviceEntryFingerprintAuthRepository
|
||||||
|
import com.android.systemui.keyguard.data.repository.FakeTrustRepository
|
||||||
import com.android.systemui.keyguard.data.repository.KeyguardBouncerRepository
|
import com.android.systemui.keyguard.data.repository.KeyguardBouncerRepository
|
||||||
import com.android.systemui.keyguard.data.repository.KeyguardBouncerRepositoryImpl
|
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.AlternateBouncerInteractor
|
||||||
import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor
|
import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor
|
||||||
import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor
|
import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor
|
||||||
@@ -95,8 +96,9 @@ class UdfpsKeyguardViewLegacyControllerWithCoroutinesTest :
|
|||||||
mock(DismissCallbackRegistry::class.java),
|
mock(DismissCallbackRegistry::class.java),
|
||||||
context,
|
context,
|
||||||
mKeyguardUpdateMonitor,
|
mKeyguardUpdateMonitor,
|
||||||
mock(TrustRepository::class.java),
|
FakeTrustRepository(),
|
||||||
FakeFeatureFlags(),
|
FakeFeatureFlags().apply { set(Flags.DELAY_BOUNCER, true) },
|
||||||
|
testScope.backgroundScope,
|
||||||
)
|
)
|
||||||
mAlternateBouncerInteractor =
|
mAlternateBouncerInteractor =
|
||||||
AlternateBouncerInteractor(
|
AlternateBouncerInteractor(
|
||||||
|
|||||||
@@ -64,7 +64,6 @@ class TrustRepositoryTest : SysuiTestCase() {
|
|||||||
testScope = TestScope()
|
testScope = TestScope()
|
||||||
userRepository = FakeUserRepository()
|
userRepository = FakeUserRepository()
|
||||||
userRepository.setUserInfos(users)
|
userRepository.setUserInfos(users)
|
||||||
|
|
||||||
val logger =
|
val logger =
|
||||||
TrustRepositoryLogger(
|
TrustRepositoryLogger(
|
||||||
LogBuffer("TestBuffer", 1, mock(LogcatEchoTracker::class.java), false)
|
LogBuffer("TestBuffer", 1, mock(LogcatEchoTracker::class.java), false)
|
||||||
@@ -224,4 +223,41 @@ class TrustRepositoryTest : SysuiTestCase() {
|
|||||||
|
|
||||||
assertThat(isCurrentUserTrusted()).isTrue()
|
assertThat(isCurrentUserTrusted()).isTrue()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun isCurrentUserActiveUnlockRunning_runningFirstBeforeUserInfoChanges_emitsCorrectValue() =
|
||||||
|
testScope.runTest {
|
||||||
|
runCurrent()
|
||||||
|
verify(trustManager).registerTrustListener(listener.capture())
|
||||||
|
val isCurrentUserActiveUnlockRunning by
|
||||||
|
collectLastValue(underTest.isCurrentUserActiveUnlockRunning)
|
||||||
|
userRepository.setSelectedUserInfo(users[1])
|
||||||
|
|
||||||
|
// active unlock running = true for users[0].id, but not the current user
|
||||||
|
listener.value.onIsActiveUnlockRunningChanged(true, users[0].id)
|
||||||
|
assertThat(isCurrentUserActiveUnlockRunning).isFalse()
|
||||||
|
|
||||||
|
// current user is now users[0].id
|
||||||
|
userRepository.setSelectedUserInfo(users[0])
|
||||||
|
assertThat(isCurrentUserActiveUnlockRunning).isTrue()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun isCurrentUserActiveUnlockRunning_whenActiveUnlockRunningForCurrentUser_emitsNewValue() =
|
||||||
|
testScope.runTest {
|
||||||
|
runCurrent()
|
||||||
|
verify(trustManager).registerTrustListener(listener.capture())
|
||||||
|
val isCurrentUserActiveUnlockRunning by
|
||||||
|
collectLastValue(underTest.isCurrentUserActiveUnlockRunning)
|
||||||
|
userRepository.setSelectedUserInfo(users[0])
|
||||||
|
|
||||||
|
listener.value.onIsActiveUnlockRunningChanged(true, users[0].id)
|
||||||
|
assertThat(isCurrentUserActiveUnlockRunning).isTrue()
|
||||||
|
|
||||||
|
listener.value.onIsActiveUnlockRunningChanged(false, users[0].id)
|
||||||
|
assertThat(isCurrentUserActiveUnlockRunning).isFalse()
|
||||||
|
|
||||||
|
listener.value.onIsActiveUnlockRunningChanged(true, users[0].id)
|
||||||
|
assertThat(isCurrentUserActiveUnlockRunning).isTrue()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFaceAuthRepo
|
|||||||
import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintAuthRepository
|
import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintAuthRepository
|
||||||
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
|
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
|
||||||
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
|
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
|
||||||
import com.android.systemui.keyguard.data.repository.TrustRepository
|
import com.android.systemui.keyguard.data.repository.FakeTrustRepository
|
||||||
import com.android.systemui.keyguard.shared.model.KeyguardState
|
import com.android.systemui.keyguard.shared.model.KeyguardState
|
||||||
import com.android.systemui.keyguard.shared.model.TransitionState
|
import com.android.systemui.keyguard.shared.model.TransitionState
|
||||||
import com.android.systemui.keyguard.shared.model.TransitionStep
|
import com.android.systemui.keyguard.shared.model.TransitionStep
|
||||||
@@ -100,8 +100,9 @@ class KeyguardFaceAuthInteractorTest : SysuiTestCase() {
|
|||||||
mock(DismissCallbackRegistry::class.java),
|
mock(DismissCallbackRegistry::class.java),
|
||||||
context,
|
context,
|
||||||
keyguardUpdateMonitor,
|
keyguardUpdateMonitor,
|
||||||
mock(TrustRepository::class.java),
|
FakeTrustRepository(),
|
||||||
FakeFeatureFlags(),
|
FakeFeatureFlags().apply { set(Flags.DELAY_BOUNCER, true) },
|
||||||
|
testScope.backgroundScope,
|
||||||
),
|
),
|
||||||
AlternateBouncerInteractor(
|
AlternateBouncerInteractor(
|
||||||
mock(StatusBarStateController::class.java),
|
mock(StatusBarStateController::class.java),
|
||||||
|
|||||||
@@ -44,6 +44,8 @@ import com.android.systemui.util.mockito.any
|
|||||||
import com.android.systemui.util.mockito.whenever
|
import com.android.systemui.util.mockito.whenever
|
||||||
import com.android.systemui.utils.os.FakeHandler
|
import com.android.systemui.utils.os.FakeHandler
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import kotlinx.coroutines.test.TestScope
|
||||||
|
import kotlinx.coroutines.test.runCurrent
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
@@ -75,6 +77,7 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() {
|
|||||||
private lateinit var resources: TestableResources
|
private lateinit var resources: TestableResources
|
||||||
private lateinit var trustRepository: FakeTrustRepository
|
private lateinit var trustRepository: FakeTrustRepository
|
||||||
private lateinit var featureFlags: FakeFeatureFlags
|
private lateinit var featureFlags: FakeFeatureFlags
|
||||||
|
private lateinit var testScope: TestScope
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
@@ -83,9 +86,10 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() {
|
|||||||
.thenReturn(KeyguardSecurityModel.SecurityMode.PIN)
|
.thenReturn(KeyguardSecurityModel.SecurityMode.PIN)
|
||||||
|
|
||||||
DejankUtils.setImmediate(true)
|
DejankUtils.setImmediate(true)
|
||||||
|
testScope = TestScope()
|
||||||
mainHandler = FakeHandler(android.os.Looper.getMainLooper())
|
mainHandler = FakeHandler(android.os.Looper.getMainLooper())
|
||||||
trustRepository = FakeTrustRepository()
|
trustRepository = FakeTrustRepository()
|
||||||
featureFlags = FakeFeatureFlags().apply { set(Flags.DELAY_BOUNCER, false) }
|
featureFlags = FakeFeatureFlags().apply { set(Flags.DELAY_BOUNCER, true) }
|
||||||
underTest =
|
underTest =
|
||||||
PrimaryBouncerInteractor(
|
PrimaryBouncerInteractor(
|
||||||
repository,
|
repository,
|
||||||
@@ -100,6 +104,7 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() {
|
|||||||
keyguardUpdateMonitor,
|
keyguardUpdateMonitor,
|
||||||
trustRepository,
|
trustRepository,
|
||||||
featureFlags,
|
featureFlags,
|
||||||
|
testScope.backgroundScope,
|
||||||
)
|
)
|
||||||
whenever(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(null)
|
whenever(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(null)
|
||||||
whenever(repository.primaryBouncerShow.value).thenReturn(false)
|
whenever(repository.primaryBouncerShow.value).thenReturn(false)
|
||||||
@@ -398,7 +403,6 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() {
|
|||||||
mainHandler.setMode(FakeHandler.Mode.QUEUEING)
|
mainHandler.setMode(FakeHandler.Mode.QUEUEING)
|
||||||
|
|
||||||
// GIVEN bouncer should be delayed due to face auth
|
// GIVEN bouncer should be delayed due to face auth
|
||||||
featureFlags.apply { set(Flags.DELAY_BOUNCER, true) }
|
|
||||||
whenever(keyguardStateController.isFaceAuthEnabled).thenReturn(true)
|
whenever(keyguardStateController.isFaceAuthEnabled).thenReturn(true)
|
||||||
whenever(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(BiometricSourceType.FACE))
|
whenever(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(BiometricSourceType.FACE))
|
||||||
.thenReturn(true)
|
.thenReturn(true)
|
||||||
@@ -420,26 +424,29 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun delayBouncerWhenActiveUnlockPossible() {
|
fun delayBouncerWhenActiveUnlockPossible() {
|
||||||
mainHandler.setMode(FakeHandler.Mode.QUEUEING)
|
testScope.run {
|
||||||
|
mainHandler.setMode(FakeHandler.Mode.QUEUEING)
|
||||||
|
|
||||||
// GIVEN bouncer should be delayed due to active unlock
|
// GIVEN bouncer should be delayed due to active unlock
|
||||||
featureFlags.apply { set(Flags.DELAY_BOUNCER, true) }
|
trustRepository.setCurrentUserActiveUnlockAvailable(true)
|
||||||
trustRepository.setCurrentUserActiveUnlockAvailable(true)
|
whenever(keyguardUpdateMonitor.canTriggerActiveUnlockBasedOnDeviceState())
|
||||||
whenever(keyguardUpdateMonitor.canTriggerActiveUnlockBasedOnDeviceState()).thenReturn(true)
|
.thenReturn(true)
|
||||||
|
runCurrent()
|
||||||
|
|
||||||
// WHEN bouncer show is requested
|
// WHEN bouncer show is requested
|
||||||
underTest.show(true)
|
underTest.show(true)
|
||||||
|
|
||||||
// THEN primary show & primary showing soon were scheduled to update
|
// THEN primary show & primary showing soon were scheduled to update
|
||||||
verify(repository, never()).setPrimaryShow(true)
|
verify(repository, never()).setPrimaryShow(true)
|
||||||
verify(repository, never()).setPrimaryShowingSoon(false)
|
verify(repository, never()).setPrimaryShowingSoon(false)
|
||||||
|
|
||||||
// WHEN all queued messages are dispatched
|
// WHEN all queued messages are dispatched
|
||||||
mainHandler.dispatchQueuedMessages()
|
mainHandler.dispatchQueuedMessages()
|
||||||
|
|
||||||
// THEN primary show & primary showing soon are updated
|
// THEN primary show & primary showing soon are updated
|
||||||
verify(repository).setPrimaryShow(true)
|
verify(repository).setPrimaryShow(true)
|
||||||
verify(repository).setPrimaryShowingSoon(false)
|
verify(repository).setPrimaryShowingSoon(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateSideFpsVisibilityParameters(
|
private fun updateSideFpsVisibilityParameters(
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import com.android.systemui.SysuiTestCase
|
|||||||
import com.android.systemui.classifier.FalsingCollector
|
import com.android.systemui.classifier.FalsingCollector
|
||||||
import com.android.systemui.coroutines.collectLastValue
|
import com.android.systemui.coroutines.collectLastValue
|
||||||
import com.android.systemui.flags.FakeFeatureFlags
|
import com.android.systemui.flags.FakeFeatureFlags
|
||||||
|
import com.android.systemui.flags.Flags
|
||||||
import com.android.systemui.keyguard.DismissCallbackRegistry
|
import com.android.systemui.keyguard.DismissCallbackRegistry
|
||||||
import com.android.systemui.keyguard.data.BouncerView
|
import com.android.systemui.keyguard.data.BouncerView
|
||||||
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
|
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
|
||||||
@@ -34,6 +35,7 @@ import com.android.systemui.statusbar.phone.KeyguardBypassController
|
|||||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||||
import com.android.systemui.utils.os.FakeHandler
|
import com.android.systemui.utils.os.FakeHandler
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import kotlinx.coroutines.test.TestScope
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
@@ -75,7 +77,8 @@ class PrimaryBouncerInteractorWithCoroutinesTest : SysuiTestCase() {
|
|||||||
context,
|
context,
|
||||||
keyguardUpdateMonitor,
|
keyguardUpdateMonitor,
|
||||||
Mockito.mock(TrustRepository::class.java),
|
Mockito.mock(TrustRepository::class.java),
|
||||||
FakeFeatureFlags(),
|
FakeFeatureFlags().apply { set(Flags.DELAY_BOUNCER, true) },
|
||||||
|
TestScope().backgroundScope,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import com.android.systemui.RoboPilotTest
|
|||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
import com.android.systemui.classifier.FalsingCollector
|
import com.android.systemui.classifier.FalsingCollector
|
||||||
import com.android.systemui.flags.FakeFeatureFlags
|
import com.android.systemui.flags.FakeFeatureFlags
|
||||||
|
import com.android.systemui.flags.Flags
|
||||||
import com.android.systemui.keyguard.DismissCallbackRegistry
|
import com.android.systemui.keyguard.DismissCallbackRegistry
|
||||||
import com.android.systemui.keyguard.data.BouncerView
|
import com.android.systemui.keyguard.data.BouncerView
|
||||||
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
|
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
|
||||||
@@ -38,6 +39,7 @@ import com.android.systemui.utils.os.FakeHandler
|
|||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
import kotlinx.coroutines.test.TestScope
|
||||||
import kotlinx.coroutines.test.runCurrent
|
import kotlinx.coroutines.test.runCurrent
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
@@ -81,7 +83,8 @@ class KeyguardBouncerViewModelTest : SysuiTestCase() {
|
|||||||
context,
|
context,
|
||||||
keyguardUpdateMonitor,
|
keyguardUpdateMonitor,
|
||||||
Mockito.mock(TrustRepository::class.java),
|
Mockito.mock(TrustRepository::class.java),
|
||||||
FakeFeatureFlags(),
|
FakeFeatureFlags().apply { set(Flags.DELAY_BOUNCER, true) },
|
||||||
|
TestScope().backgroundScope,
|
||||||
)
|
)
|
||||||
underTest = KeyguardBouncerViewModel(bouncerView, bouncerInteractor)
|
underTest = KeyguardBouncerViewModel(bouncerView, bouncerInteractor)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class FakeTrustRepository : TrustRepository {
|
|||||||
get() = _isCurrentUserTrusted
|
get() = _isCurrentUserTrusted
|
||||||
|
|
||||||
private val _isCurrentUserActiveUnlockAvailable = MutableStateFlow(false)
|
private val _isCurrentUserActiveUnlockAvailable = MutableStateFlow(false)
|
||||||
override val isCurrentUserActiveUnlockAvailable: StateFlow<Boolean> =
|
override val isCurrentUserActiveUnlockRunning: StateFlow<Boolean> =
|
||||||
_isCurrentUserActiveUnlockAvailable.asStateFlow()
|
_isCurrentUserActiveUnlockAvailable.asStateFlow()
|
||||||
|
|
||||||
private val _isCurrentUserTrustManaged = MutableStateFlow(false)
|
private val _isCurrentUserTrustManaged = MutableStateFlow(false)
|
||||||
|
|||||||
Reference in New Issue
Block a user