Merge "[flexiglass] Hooks up real app state and logic in keyguard (1)" into udc-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
848b73fe14
@@ -16,8 +16,11 @@
|
|||||||
|
|
||||||
package com.android.systemui.authentication
|
package com.android.systemui.authentication
|
||||||
|
|
||||||
|
import com.android.keyguard.KeyguardSecurityModel
|
||||||
import com.android.systemui.authentication.data.repository.AuthenticationRepositoryModule
|
import com.android.systemui.authentication.data.repository.AuthenticationRepositoryModule
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
import java.util.function.Function
|
||||||
|
|
||||||
@Module(
|
@Module(
|
||||||
includes =
|
includes =
|
||||||
@@ -25,4 +28,12 @@ import dagger.Module
|
|||||||
AuthenticationRepositoryModule::class,
|
AuthenticationRepositoryModule::class,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
object AuthenticationModule
|
object AuthenticationModule {
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
fun getSecurityMode(
|
||||||
|
model: KeyguardSecurityModel,
|
||||||
|
): Function<Int, KeyguardSecurityModel.SecurityMode> {
|
||||||
|
return Function { userId -> model.getSecurityMode(userId) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,13 +16,20 @@
|
|||||||
|
|
||||||
package com.android.systemui.authentication.data.repository
|
package com.android.systemui.authentication.data.repository
|
||||||
|
|
||||||
|
import com.android.internal.widget.LockPatternUtils
|
||||||
|
import com.android.keyguard.KeyguardSecurityModel
|
||||||
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
|
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
|
||||||
|
import com.android.systemui.dagger.qualifiers.Background
|
||||||
|
import com.android.systemui.user.data.repository.UserRepository
|
||||||
import dagger.Binds
|
import dagger.Binds
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import javax.inject.Inject
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import java.util.function.Function
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
/** Defines interface for classes that can access authentication-related application state. */
|
/** Defines interface for classes that can access authentication-related application state. */
|
||||||
interface AuthenticationRepository {
|
interface AuthenticationRepository {
|
||||||
@@ -37,12 +44,6 @@ interface AuthenticationRepository {
|
|||||||
*/
|
*/
|
||||||
val isUnlocked: StateFlow<Boolean>
|
val isUnlocked: StateFlow<Boolean>
|
||||||
|
|
||||||
/**
|
|
||||||
* The currently-configured authentication method. This determines how the authentication
|
|
||||||
* challenge is completed in order to unlock an otherwise locked device.
|
|
||||||
*/
|
|
||||||
val authenticationMethod: StateFlow<AuthenticationMethodModel>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether lock screen bypass is enabled. When enabled, the lock screen will be automatically
|
* Whether lock screen bypass is enabled. When enabled, the lock screen will be automatically
|
||||||
* dismisses once the authentication challenge is completed. For example, completing a biometric
|
* dismisses once the authentication challenge is completed. For example, completing a biometric
|
||||||
@@ -57,12 +58,15 @@ interface AuthenticationRepository {
|
|||||||
*/
|
*/
|
||||||
val failedAuthenticationAttempts: StateFlow<Int>
|
val failedAuthenticationAttempts: StateFlow<Int>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the currently-configured authentication method. This determines how the
|
||||||
|
* authentication challenge is completed in order to unlock an otherwise locked device.
|
||||||
|
*/
|
||||||
|
suspend fun getAuthenticationMethod(): AuthenticationMethodModel
|
||||||
|
|
||||||
/** See [isUnlocked]. */
|
/** See [isUnlocked]. */
|
||||||
fun setUnlocked(isUnlocked: Boolean)
|
fun setUnlocked(isUnlocked: Boolean)
|
||||||
|
|
||||||
/** See [authenticationMethod]. */
|
|
||||||
fun setAuthenticationMethod(authenticationMethod: AuthenticationMethodModel)
|
|
||||||
|
|
||||||
/** See [isBypassEnabled]. */
|
/** See [isBypassEnabled]. */
|
||||||
fun setBypassEnabled(isBypassEnabled: Boolean)
|
fun setBypassEnabled(isBypassEnabled: Boolean)
|
||||||
|
|
||||||
@@ -70,19 +74,18 @@ interface AuthenticationRepository {
|
|||||||
fun setFailedAuthenticationAttempts(failedAuthenticationAttempts: Int)
|
fun setFailedAuthenticationAttempts(failedAuthenticationAttempts: Int)
|
||||||
}
|
}
|
||||||
|
|
||||||
class AuthenticationRepositoryImpl @Inject constructor() : AuthenticationRepository {
|
class AuthenticationRepositoryImpl
|
||||||
// TODO(b/280883900): get data from real data sources in SysUI.
|
@Inject
|
||||||
|
constructor(
|
||||||
|
private val getSecurityMode: Function<Int, KeyguardSecurityModel.SecurityMode>,
|
||||||
|
@Background private val backgroundDispatcher: CoroutineDispatcher,
|
||||||
|
private val userRepository: UserRepository,
|
||||||
|
private val lockPatternUtils: LockPatternUtils,
|
||||||
|
) : AuthenticationRepository {
|
||||||
|
|
||||||
private val _isUnlocked = MutableStateFlow(false)
|
private val _isUnlocked = MutableStateFlow(false)
|
||||||
override val isUnlocked: StateFlow<Boolean> = _isUnlocked.asStateFlow()
|
override val isUnlocked: StateFlow<Boolean> = _isUnlocked.asStateFlow()
|
||||||
|
|
||||||
private val _authenticationMethod =
|
|
||||||
MutableStateFlow<AuthenticationMethodModel>(
|
|
||||||
AuthenticationMethodModel.Pin(listOf(1, 2, 3, 4), autoConfirm = false)
|
|
||||||
)
|
|
||||||
override val authenticationMethod: StateFlow<AuthenticationMethodModel> =
|
|
||||||
_authenticationMethod.asStateFlow()
|
|
||||||
|
|
||||||
private val _isBypassEnabled = MutableStateFlow(false)
|
private val _isBypassEnabled = MutableStateFlow(false)
|
||||||
override val isBypassEnabled: StateFlow<Boolean> = _isBypassEnabled.asStateFlow()
|
override val isBypassEnabled: StateFlow<Boolean> = _isBypassEnabled.asStateFlow()
|
||||||
|
|
||||||
@@ -90,6 +93,41 @@ class AuthenticationRepositoryImpl @Inject constructor() : AuthenticationReposit
|
|||||||
override val failedAuthenticationAttempts: StateFlow<Int> =
|
override val failedAuthenticationAttempts: StateFlow<Int> =
|
||||||
_failedAuthenticationAttempts.asStateFlow()
|
_failedAuthenticationAttempts.asStateFlow()
|
||||||
|
|
||||||
|
override suspend fun getAuthenticationMethod(): AuthenticationMethodModel {
|
||||||
|
return withContext(backgroundDispatcher) {
|
||||||
|
val selectedUserId = userRepository.getSelectedUserInfo().id
|
||||||
|
when (getSecurityMode.apply(selectedUserId)) {
|
||||||
|
KeyguardSecurityModel.SecurityMode.PIN,
|
||||||
|
KeyguardSecurityModel.SecurityMode.SimPin ->
|
||||||
|
AuthenticationMethodModel.Pin(
|
||||||
|
code = listOf(1, 2, 3, 4), // TODO(b/280883900): remove this
|
||||||
|
autoConfirm = lockPatternUtils.isAutoPinConfirmEnabled(selectedUserId),
|
||||||
|
)
|
||||||
|
KeyguardSecurityModel.SecurityMode.Password,
|
||||||
|
KeyguardSecurityModel.SecurityMode.SimPuk ->
|
||||||
|
AuthenticationMethodModel.Password(
|
||||||
|
password = "password", // TODO(b/280883900): remove this
|
||||||
|
)
|
||||||
|
KeyguardSecurityModel.SecurityMode.Pattern ->
|
||||||
|
AuthenticationMethodModel.Pattern(
|
||||||
|
coordinates =
|
||||||
|
listOf(
|
||||||
|
AuthenticationMethodModel.Pattern.PatternCoordinate(2, 0),
|
||||||
|
AuthenticationMethodModel.Pattern.PatternCoordinate(2, 1),
|
||||||
|
AuthenticationMethodModel.Pattern.PatternCoordinate(2, 2),
|
||||||
|
AuthenticationMethodModel.Pattern.PatternCoordinate(1, 1),
|
||||||
|
AuthenticationMethodModel.Pattern.PatternCoordinate(0, 0),
|
||||||
|
AuthenticationMethodModel.Pattern.PatternCoordinate(0, 1),
|
||||||
|
AuthenticationMethodModel.Pattern.PatternCoordinate(0, 2),
|
||||||
|
), // TODO(b/280883900): remove this
|
||||||
|
)
|
||||||
|
KeyguardSecurityModel.SecurityMode.None -> AuthenticationMethodModel.None
|
||||||
|
KeyguardSecurityModel.SecurityMode.Invalid -> error("Invalid security mode!")
|
||||||
|
null -> error("Invalid security is null!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun setUnlocked(isUnlocked: Boolean) {
|
override fun setUnlocked(isUnlocked: Boolean) {
|
||||||
_isUnlocked.value = isUnlocked
|
_isUnlocked.value = isUnlocked
|
||||||
}
|
}
|
||||||
@@ -98,10 +136,6 @@ class AuthenticationRepositoryImpl @Inject constructor() : AuthenticationReposit
|
|||||||
_isBypassEnabled.value = isBypassEnabled
|
_isBypassEnabled.value = isBypassEnabled
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setAuthenticationMethod(authenticationMethod: AuthenticationMethodModel) {
|
|
||||||
_authenticationMethod.value = authenticationMethod
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setFailedAuthenticationAttempts(failedAuthenticationAttempts: Int) {
|
override fun setFailedAuthenticationAttempts(failedAuthenticationAttempts: Int) {
|
||||||
_failedAuthenticationAttempts.value = failedAuthenticationAttempts
|
_failedAuthenticationAttempts.value = failedAuthenticationAttempts
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,9 +25,8 @@ import javax.inject.Inject
|
|||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
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.map
|
||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
|
|
||||||
/** Hosts application business logic related to authentication. */
|
/** Hosts application business logic related to authentication. */
|
||||||
@SysUISingleton
|
@SysUISingleton
|
||||||
@@ -37,12 +36,6 @@ constructor(
|
|||||||
@Application applicationScope: CoroutineScope,
|
@Application applicationScope: CoroutineScope,
|
||||||
private val repository: AuthenticationRepository,
|
private val repository: AuthenticationRepository,
|
||||||
) {
|
) {
|
||||||
/**
|
|
||||||
* The currently-configured authentication method. This determines how the authentication
|
|
||||||
* challenge is completed in order to unlock an otherwise locked device.
|
|
||||||
*/
|
|
||||||
val authenticationMethod: StateFlow<AuthenticationMethodModel> = repository.authenticationMethod
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the device is unlocked.
|
* Whether the device is unlocked.
|
||||||
*
|
*
|
||||||
@@ -52,20 +45,18 @@ constructor(
|
|||||||
* Note that this state has no real bearing on whether the lock screen is showing or dismissed.
|
* Note that this state has no real bearing on whether the lock screen is showing or dismissed.
|
||||||
*/
|
*/
|
||||||
val isUnlocked: StateFlow<Boolean> =
|
val isUnlocked: StateFlow<Boolean> =
|
||||||
combine(authenticationMethod, repository.isUnlocked) { authMethod, isUnlocked ->
|
repository.isUnlocked
|
||||||
isUnlockedWithAuthMethod(
|
.map { isUnlocked ->
|
||||||
isUnlocked = isUnlocked,
|
if (getAuthenticationMethod() is AuthenticationMethodModel.None) {
|
||||||
authMethod = authMethod,
|
true
|
||||||
)
|
} else {
|
||||||
|
isUnlocked
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.stateIn(
|
.stateIn(
|
||||||
scope = applicationScope,
|
scope = applicationScope,
|
||||||
started = SharingStarted.Eagerly,
|
started = SharingStarted.Eagerly,
|
||||||
initialValue =
|
initialValue = true,
|
||||||
isUnlockedWithAuthMethod(
|
|
||||||
isUnlocked = repository.isUnlocked.value,
|
|
||||||
authMethod = repository.authenticationMethod.value,
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -82,25 +73,20 @@ constructor(
|
|||||||
*/
|
*/
|
||||||
val failedAuthenticationAttempts: StateFlow<Int> = repository.failedAuthenticationAttempts
|
val failedAuthenticationAttempts: StateFlow<Int> = repository.failedAuthenticationAttempts
|
||||||
|
|
||||||
init {
|
/**
|
||||||
// UNLOCKS WHEN AUTH METHOD REMOVED.
|
* Returns the currently-configured authentication method. This determines how the
|
||||||
//
|
* authentication challenge is completed in order to unlock an otherwise locked device.
|
||||||
// Unlocks the device if the auth method becomes None.
|
*/
|
||||||
applicationScope.launch {
|
suspend fun getAuthenticationMethod(): AuthenticationMethodModel {
|
||||||
repository.authenticationMethod.collect {
|
return repository.getAuthenticationMethod()
|
||||||
if (it is AuthenticationMethodModel.None) {
|
|
||||||
unlockDevice()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns `true` if the device currently requires authentication before content can be viewed;
|
* Returns `true` if the device currently requires authentication before content can be viewed;
|
||||||
* `false` if content can be displayed without unlocking first.
|
* `false` if content can be displayed without unlocking first.
|
||||||
*/
|
*/
|
||||||
fun isAuthenticationRequired(): Boolean {
|
suspend fun isAuthenticationRequired(): Boolean {
|
||||||
return !isUnlocked.value && authenticationMethod.value.isSecure
|
return !isUnlocked.value && getAuthenticationMethod().isSecure
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -133,8 +119,8 @@ constructor(
|
|||||||
* @return `true` if the authentication succeeded and the device is now unlocked; `false` when
|
* @return `true` if the authentication succeeded and the device is now unlocked; `false` when
|
||||||
* authentication failed, `null` if the check was not performed.
|
* authentication failed, `null` if the check was not performed.
|
||||||
*/
|
*/
|
||||||
fun authenticate(input: List<Any>, tryAutoConfirm: Boolean = false): Boolean? {
|
suspend fun authenticate(input: List<Any>, tryAutoConfirm: Boolean = false): Boolean? {
|
||||||
val authMethod = this.authenticationMethod.value
|
val authMethod = getAuthenticationMethod()
|
||||||
if (tryAutoConfirm) {
|
if (tryAutoConfirm) {
|
||||||
if ((authMethod as? AuthenticationMethodModel.Pin)?.autoConfirm != true) {
|
if ((authMethod as? AuthenticationMethodModel.Pin)?.autoConfirm != true) {
|
||||||
// Do not attempt to authenticate unless the PIN lock is set to auto-confirm.
|
// Do not attempt to authenticate unless the PIN lock is set to auto-confirm.
|
||||||
@@ -176,28 +162,12 @@ constructor(
|
|||||||
repository.setUnlocked(true)
|
repository.setUnlocked(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** See [authenticationMethod]. */
|
|
||||||
fun setAuthenticationMethod(authenticationMethod: AuthenticationMethodModel) {
|
|
||||||
repository.setAuthenticationMethod(authenticationMethod)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** See [isBypassEnabled]. */
|
/** See [isBypassEnabled]. */
|
||||||
fun toggleBypassEnabled() {
|
fun toggleBypassEnabled() {
|
||||||
repository.setBypassEnabled(!repository.isBypassEnabled.value)
|
repository.setBypassEnabled(!repository.isBypassEnabled.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private fun isUnlockedWithAuthMethod(
|
|
||||||
isUnlocked: Boolean,
|
|
||||||
authMethod: AuthenticationMethodModel,
|
|
||||||
): Boolean {
|
|
||||||
return if (authMethod is AuthenticationMethodModel.None) {
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
isUnlocked
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a PIN code from the given list. It's assumed the given list elements are all
|
* Returns a PIN code from the given list. It's assumed the given list elements are all
|
||||||
* [Int] in the range [0-9].
|
* [Int] in the range [0-9].
|
||||||
|
|||||||
@@ -68,43 +68,39 @@ constructor(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
|
||||||
* The currently-configured authentication method. This determines how the authentication
|
|
||||||
* challenge is completed in order to unlock an otherwise locked device.
|
|
||||||
*/
|
|
||||||
val authenticationMethod: StateFlow<AuthenticationMethodModel> =
|
|
||||||
authenticationInteractor.authenticationMethod
|
|
||||||
|
|
||||||
/** The current authentication throttling state. If `null`, there's no throttling. */
|
/** The current authentication throttling state. If `null`, there's no throttling. */
|
||||||
val throttling: StateFlow<AuthenticationThrottledModel?> = repository.throttling
|
val throttling: StateFlow<AuthenticationThrottledModel?> = repository.throttling
|
||||||
|
|
||||||
init {
|
init {
|
||||||
applicationScope.launch {
|
applicationScope.launch {
|
||||||
combine(
|
sceneInteractor.currentScene(containerName).collect { currentScene ->
|
||||||
sceneInteractor.currentScene(containerName),
|
if (currentScene.key == SceneKey.Bouncer) {
|
||||||
authenticationInteractor.authenticationMethod,
|
when (getAuthenticationMethod()) {
|
||||||
::Pair,
|
is AuthenticationMethodModel.None ->
|
||||||
)
|
sceneInteractor.setCurrentScene(
|
||||||
.collect { (currentScene, authMethod) ->
|
containerName,
|
||||||
if (currentScene.key == SceneKey.Bouncer) {
|
SceneModel(SceneKey.Gone),
|
||||||
when (authMethod) {
|
)
|
||||||
is AuthenticationMethodModel.None ->
|
is AuthenticationMethodModel.Swipe ->
|
||||||
sceneInteractor.setCurrentScene(
|
sceneInteractor.setCurrentScene(
|
||||||
containerName,
|
containerName,
|
||||||
SceneModel(SceneKey.Gone),
|
SceneModel(SceneKey.Lockscreen),
|
||||||
)
|
)
|
||||||
is AuthenticationMethodModel.Swipe ->
|
else -> Unit
|
||||||
sceneInteractor.setCurrentScene(
|
|
||||||
containerName,
|
|
||||||
SceneModel(SceneKey.Lockscreen),
|
|
||||||
)
|
|
||||||
else -> Unit
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the currently-configured authentication method. This determines how the
|
||||||
|
* authentication challenge is completed in order to unlock an otherwise locked device.
|
||||||
|
*/
|
||||||
|
suspend fun getAuthenticationMethod(): AuthenticationMethodModel {
|
||||||
|
return authenticationInteractor.getAuthenticationMethod()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Either shows the bouncer or unlocks the device, if the bouncer doesn't need to be shown.
|
* Either shows the bouncer or unlocks the device, if the bouncer doesn't need to be shown.
|
||||||
*
|
*
|
||||||
@@ -115,18 +111,20 @@ constructor(
|
|||||||
containerName: String,
|
containerName: String,
|
||||||
message: String? = null,
|
message: String? = null,
|
||||||
) {
|
) {
|
||||||
if (authenticationInteractor.isAuthenticationRequired()) {
|
applicationScope.launch {
|
||||||
repository.setMessage(message ?: promptMessage(authenticationMethod.value))
|
if (authenticationInteractor.isAuthenticationRequired()) {
|
||||||
sceneInteractor.setCurrentScene(
|
repository.setMessage(message ?: promptMessage(getAuthenticationMethod()))
|
||||||
containerName = containerName,
|
sceneInteractor.setCurrentScene(
|
||||||
scene = SceneModel(SceneKey.Bouncer),
|
containerName = containerName,
|
||||||
)
|
scene = SceneModel(SceneKey.Bouncer),
|
||||||
} else {
|
)
|
||||||
authenticationInteractor.unlockDevice()
|
} else {
|
||||||
sceneInteractor.setCurrentScene(
|
authenticationInteractor.unlockDevice()
|
||||||
containerName = containerName,
|
sceneInteractor.setCurrentScene(
|
||||||
scene = SceneModel(SceneKey.Gone),
|
containerName = containerName,
|
||||||
)
|
scene = SceneModel(SceneKey.Gone),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,7 +133,7 @@ constructor(
|
|||||||
* method.
|
* method.
|
||||||
*/
|
*/
|
||||||
fun resetMessage() {
|
fun resetMessage() {
|
||||||
repository.setMessage(promptMessage(authenticationMethod.value))
|
applicationScope.launch { repository.setMessage(promptMessage(getAuthenticationMethod())) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Removes the user-facing message. */
|
/** Removes the user-facing message. */
|
||||||
@@ -160,7 +158,7 @@ constructor(
|
|||||||
* @return `true` if the authentication succeeded and the device is now unlocked; `false` when
|
* @return `true` if the authentication succeeded and the device is now unlocked; `false` when
|
||||||
* authentication failed, `null` if the check was not performed.
|
* authentication failed, `null` if the check was not performed.
|
||||||
*/
|
*/
|
||||||
fun authenticate(
|
suspend fun authenticate(
|
||||||
input: List<Any>,
|
input: List<Any>,
|
||||||
tryAutoConfirm: Boolean = false,
|
tryAutoConfirm: Boolean = false,
|
||||||
): Boolean? {
|
): Boolean? {
|
||||||
@@ -198,7 +196,7 @@ constructor(
|
|||||||
repository.setThrottling(null)
|
repository.setThrottling(null)
|
||||||
clearMessage()
|
clearMessage()
|
||||||
}
|
}
|
||||||
else -> repository.setMessage(errorMessage(authenticationMethod.value))
|
else -> repository.setMessage(errorMessage(getAuthenticationMethod()))
|
||||||
}
|
}
|
||||||
|
|
||||||
return isAuthenticated
|
return isAuthenticated
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import kotlinx.coroutines.flow.StateFlow
|
|||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
|
import kotlinx.coroutines.flow.flow
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -66,6 +67,7 @@ constructor(
|
|||||||
|
|
||||||
private val password: PasswordBouncerViewModel by lazy {
|
private val password: PasswordBouncerViewModel by lazy {
|
||||||
PasswordBouncerViewModel(
|
PasswordBouncerViewModel(
|
||||||
|
applicationScope = applicationScope,
|
||||||
interactor = interactor,
|
interactor = interactor,
|
||||||
isInputEnabled = isInputEnabled,
|
isInputEnabled = isInputEnabled,
|
||||||
)
|
)
|
||||||
@@ -81,14 +83,25 @@ constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** View-model for the current UI, based on the current authentication method. */
|
/** View-model for the current UI, based on the current authentication method. */
|
||||||
val authMethod: StateFlow<AuthMethodBouncerViewModel?> =
|
val authMethod: StateFlow<AuthMethodBouncerViewModel?>
|
||||||
interactor.authenticationMethod
|
get() =
|
||||||
.map { authMethod -> toViewModel(authMethod) }
|
flow {
|
||||||
.stateIn(
|
emit(null)
|
||||||
scope = applicationScope,
|
emit(interactor.getAuthenticationMethod())
|
||||||
started = SharingStarted.WhileSubscribed(),
|
}
|
||||||
initialValue = toViewModel(interactor.authenticationMethod.value),
|
.map { authMethod ->
|
||||||
)
|
when (authMethod) {
|
||||||
|
is AuthenticationMethodModel.Pin -> pin
|
||||||
|
is AuthenticationMethodModel.Password -> password
|
||||||
|
is AuthenticationMethodModel.Pattern -> pattern
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.stateIn(
|
||||||
|
scope = applicationScope,
|
||||||
|
started = SharingStarted.WhileSubscribed(),
|
||||||
|
initialValue = null,
|
||||||
|
)
|
||||||
|
|
||||||
/** The user-facing message to show in the bouncer. */
|
/** The user-facing message to show in the bouncer. */
|
||||||
val message: StateFlow<MessageViewModel> =
|
val message: StateFlow<MessageViewModel> =
|
||||||
@@ -125,7 +138,7 @@ constructor(
|
|||||||
interactor.throttling
|
interactor.throttling
|
||||||
.map { model ->
|
.map { model ->
|
||||||
model?.let {
|
model?.let {
|
||||||
when (interactor.authenticationMethod.value) {
|
when (interactor.getAuthenticationMethod()) {
|
||||||
is AuthenticationMethodModel.Pin ->
|
is AuthenticationMethodModel.Pin ->
|
||||||
R.string.kg_too_many_failed_pin_attempts_dialog_message
|
R.string.kg_too_many_failed_pin_attempts_dialog_message
|
||||||
is AuthenticationMethodModel.Password ->
|
is AuthenticationMethodModel.Password ->
|
||||||
@@ -161,17 +174,6 @@ constructor(
|
|||||||
_throttlingDialogMessage.value = null
|
_throttlingDialogMessage.value = null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun toViewModel(
|
|
||||||
authMethod: AuthenticationMethodModel,
|
|
||||||
): AuthMethodBouncerViewModel? {
|
|
||||||
return when (authMethod) {
|
|
||||||
is AuthenticationMethodModel.Pin -> pin
|
|
||||||
is AuthenticationMethodModel.Password -> password
|
|
||||||
is AuthenticationMethodModel.Pattern -> pattern
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun toMessageViewModel(
|
private fun toMessageViewModel(
|
||||||
message: String?,
|
message: String?,
|
||||||
throttling: AuthenticationThrottledModel?,
|
throttling: AuthenticationThrottledModel?,
|
||||||
|
|||||||
@@ -17,12 +17,15 @@
|
|||||||
package com.android.systemui.bouncer.ui.viewmodel
|
package com.android.systemui.bouncer.ui.viewmodel
|
||||||
|
|
||||||
import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
|
import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
/** Holds UI state and handles user input for the password bouncer UI. */
|
/** Holds UI state and handles user input for the password bouncer UI. */
|
||||||
class PasswordBouncerViewModel(
|
class PasswordBouncerViewModel(
|
||||||
|
private val applicationScope: CoroutineScope,
|
||||||
private val interactor: BouncerInteractor,
|
private val interactor: BouncerInteractor,
|
||||||
isInputEnabled: StateFlow<Boolean>,
|
isInputEnabled: StateFlow<Boolean>,
|
||||||
) :
|
) :
|
||||||
@@ -50,10 +53,13 @@ class PasswordBouncerViewModel(
|
|||||||
|
|
||||||
/** Notifies that the user has pressed the key for attempting to authenticate the password. */
|
/** Notifies that the user has pressed the key for attempting to authenticate the password. */
|
||||||
fun onAuthenticateKeyPressed() {
|
fun onAuthenticateKeyPressed() {
|
||||||
if (interactor.authenticate(password.value.toCharArray().toList()) != true) {
|
val password = _password.value.toCharArray().toList()
|
||||||
showFailureAnimation()
|
|
||||||
}
|
|
||||||
|
|
||||||
_password.value = ""
|
_password.value = ""
|
||||||
|
|
||||||
|
applicationScope.launch {
|
||||||
|
if (interactor.authenticate(password) != true) {
|
||||||
|
showFailureAnimation()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,13 +29,15 @@ 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.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
import kotlinx.coroutines.flow.flow
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
/** Holds UI state and handles user input for the pattern bouncer UI. */
|
/** Holds UI state and handles user input for the pattern bouncer UI. */
|
||||||
class PatternBouncerViewModel(
|
class PatternBouncerViewModel(
|
||||||
private val applicationContext: Context,
|
private val applicationContext: Context,
|
||||||
applicationScope: CoroutineScope,
|
private val applicationScope: CoroutineScope,
|
||||||
private val interactor: BouncerInteractor,
|
private val interactor: BouncerInteractor,
|
||||||
isInputEnabled: StateFlow<Boolean>,
|
isInputEnabled: StateFlow<Boolean>,
|
||||||
) :
|
) :
|
||||||
@@ -69,12 +71,17 @@ class PatternBouncerViewModel(
|
|||||||
|
|
||||||
/** Whether the pattern itself should be rendered visibly. */
|
/** Whether the pattern itself should be rendered visibly. */
|
||||||
val isPatternVisible: StateFlow<Boolean> =
|
val isPatternVisible: StateFlow<Boolean> =
|
||||||
interactor.authenticationMethod
|
flow {
|
||||||
.map { authMethod -> isPatternVisible(authMethod) }
|
emit(null)
|
||||||
|
emit(interactor.getAuthenticationMethod())
|
||||||
|
}
|
||||||
|
.map { authMethod ->
|
||||||
|
(authMethod as? AuthenticationMethodModel.Pattern)?.isPatternVisible ?: false
|
||||||
|
}
|
||||||
.stateIn(
|
.stateIn(
|
||||||
scope = applicationScope,
|
scope = applicationScope,
|
||||||
started = SharingStarted.Eagerly,
|
started = SharingStarted.Eagerly,
|
||||||
initialValue = isPatternVisible(interactor.authenticationMethod.value),
|
initialValue = false,
|
||||||
)
|
)
|
||||||
|
|
||||||
/** Notifies that the UI has been shown to the user. */
|
/** Notifies that the UI has been shown to the user. */
|
||||||
@@ -154,17 +161,15 @@ class PatternBouncerViewModel(
|
|||||||
/** Notifies that the user has ended the drag gesture across the dot grid. */
|
/** Notifies that the user has ended the drag gesture across the dot grid. */
|
||||||
fun onDragEnd() {
|
fun onDragEnd() {
|
||||||
val pattern = _selectedDots.value.map { it.toCoordinate() }
|
val pattern = _selectedDots.value.map { it.toCoordinate() }
|
||||||
if (interactor.authenticate(pattern) != true) {
|
|
||||||
showFailureAnimation()
|
|
||||||
}
|
|
||||||
|
|
||||||
_dots.value = defaultDots()
|
_dots.value = defaultDots()
|
||||||
_currentDot.value = null
|
_currentDot.value = null
|
||||||
_selectedDots.value = linkedSetOf()
|
_selectedDots.value = linkedSetOf()
|
||||||
}
|
|
||||||
|
|
||||||
private fun isPatternVisible(authMethodModel: AuthenticationMethodModel): Boolean {
|
applicationScope.launch {
|
||||||
return (authMethodModel as? AuthenticationMethodModel.Pattern)?.isPatternVisible ?: false
|
if (interactor.authenticate(pattern) != true) {
|
||||||
|
showFailureAnimation()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun defaultDots(): List<PatternDotViewModel> {
|
private fun defaultDots(): List<PatternDotViewModel> {
|
||||||
|
|||||||
@@ -22,13 +22,14 @@ import kotlinx.coroutines.CoroutineScope
|
|||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
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.flow
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
/** Holds UI state and handles user input for the PIN code bouncer UI. */
|
/** Holds UI state and handles user input for the PIN code bouncer UI. */
|
||||||
class PinBouncerViewModel(
|
class PinBouncerViewModel(
|
||||||
applicationScope: CoroutineScope,
|
private val applicationScope: CoroutineScope,
|
||||||
private val interactor: BouncerInteractor,
|
private val interactor: BouncerInteractor,
|
||||||
isInputEnabled: StateFlow<Boolean>,
|
isInputEnabled: StateFlow<Boolean>,
|
||||||
) :
|
) :
|
||||||
@@ -39,40 +40,48 @@ class PinBouncerViewModel(
|
|||||||
private val mutablePinEntries = MutableStateFlow<List<EnteredKey>>(emptyList())
|
private val mutablePinEntries = MutableStateFlow<List<EnteredKey>>(emptyList())
|
||||||
val pinEntries: StateFlow<List<EnteredKey>> = mutablePinEntries
|
val pinEntries: StateFlow<List<EnteredKey>> = mutablePinEntries
|
||||||
|
|
||||||
/** The length of the hinted PIN, or null if pin length hint should not be shown. */
|
/** The length of the hinted PIN, or `null` if pin length hint should not be shown. */
|
||||||
val hintedPinLength: StateFlow<Int?> =
|
val hintedPinLength: StateFlow<Int?> =
|
||||||
interactor.authenticationMethod
|
flow {
|
||||||
.map { authMethod -> computeHintedPinLength(authMethod) }
|
emit(null)
|
||||||
.stateIn(
|
emit(interactor.getAuthenticationMethod())
|
||||||
scope = applicationScope,
|
}
|
||||||
started = SharingStarted.Eagerly,
|
.map { authMethod ->
|
||||||
initialValue = computeHintedPinLength(interactor.authenticationMethod.value),
|
// Hinting is enabled for 6-digit codes only
|
||||||
)
|
autoConfirmPinLength(authMethod).takeIf { it == HINTING_PASSCODE_LENGTH }
|
||||||
|
|
||||||
/** Appearance of the backspace button. */
|
|
||||||
val backspaceButtonAppearance: StateFlow<ActionButtonAppearance> =
|
|
||||||
combine(interactor.authenticationMethod, mutablePinEntries) { authMethod, enteredPin ->
|
|
||||||
computeBackspaceButtonAppearance(authMethod, enteredPin)
|
|
||||||
}
|
}
|
||||||
.stateIn(
|
.stateIn(
|
||||||
scope = applicationScope,
|
scope = applicationScope,
|
||||||
started = SharingStarted.Eagerly,
|
started = SharingStarted.Eagerly,
|
||||||
initialValue =
|
initialValue = null,
|
||||||
computeBackspaceButtonAppearance(
|
)
|
||||||
interactor.authenticationMethod.value,
|
|
||||||
mutablePinEntries.value
|
/** Appearance of the backspace button. */
|
||||||
),
|
val backspaceButtonAppearance: StateFlow<ActionButtonAppearance> =
|
||||||
|
mutablePinEntries
|
||||||
|
.map { mutablePinEntries ->
|
||||||
|
computeBackspaceButtonAppearance(
|
||||||
|
interactor.getAuthenticationMethod(),
|
||||||
|
mutablePinEntries
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.stateIn(
|
||||||
|
scope = applicationScope,
|
||||||
|
started = SharingStarted.Eagerly,
|
||||||
|
initialValue = ActionButtonAppearance.Hidden,
|
||||||
)
|
)
|
||||||
|
|
||||||
/** Appearance of the confirm button. */
|
/** Appearance of the confirm button. */
|
||||||
val confirmButtonAppearance: StateFlow<ActionButtonAppearance> =
|
val confirmButtonAppearance: StateFlow<ActionButtonAppearance> =
|
||||||
interactor.authenticationMethod
|
flow {
|
||||||
|
emit(null)
|
||||||
|
emit(interactor.getAuthenticationMethod())
|
||||||
|
}
|
||||||
.map { authMethod -> computeConfirmButtonAppearance(authMethod) }
|
.map { authMethod -> computeConfirmButtonAppearance(authMethod) }
|
||||||
.stateIn(
|
.stateIn(
|
||||||
scope = applicationScope,
|
scope = applicationScope,
|
||||||
started = SharingStarted.Eagerly,
|
started = SharingStarted.Eagerly,
|
||||||
initialValue =
|
initialValue = ActionButtonAppearance.Hidden,
|
||||||
computeConfirmButtonAppearance(interactor.authenticationMethod.value),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
/** Notifies that the UI has been shown to the user. */
|
/** Notifies that the UI has been shown to the user. */
|
||||||
@@ -111,30 +120,28 @@ class PinBouncerViewModel(
|
|||||||
|
|
||||||
private fun tryAuthenticate(useAutoConfirm: Boolean) {
|
private fun tryAuthenticate(useAutoConfirm: Boolean) {
|
||||||
val pinCode = mutablePinEntries.value.map { it.input }
|
val pinCode = mutablePinEntries.value.map { it.input }
|
||||||
val isSuccess = interactor.authenticate(pinCode, useAutoConfirm) ?: return
|
|
||||||
|
|
||||||
if (!isSuccess) {
|
applicationScope.launch {
|
||||||
showFailureAnimation()
|
val isSuccess = interactor.authenticate(pinCode, useAutoConfirm) ?: return@launch
|
||||||
|
|
||||||
|
if (!isSuccess) {
|
||||||
|
showFailureAnimation()
|
||||||
|
}
|
||||||
|
|
||||||
|
mutablePinEntries.value = emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
mutablePinEntries.value = emptyList()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isAutoConfirmEnabled(authMethodModel: AuthenticationMethodModel): Boolean {
|
private fun isAutoConfirmEnabled(authMethodModel: AuthenticationMethodModel?): Boolean {
|
||||||
return (authMethodModel as? AuthenticationMethodModel.Pin)?.autoConfirm == true
|
return (authMethodModel as? AuthenticationMethodModel.Pin)?.autoConfirm == true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun autoConfirmPinLength(authMethodModel: AuthenticationMethodModel): Int? {
|
private fun autoConfirmPinLength(authMethodModel: AuthenticationMethodModel?): Int? {
|
||||||
if (!isAutoConfirmEnabled(authMethodModel)) return null
|
if (!isAutoConfirmEnabled(authMethodModel)) return null
|
||||||
|
|
||||||
return (authMethodModel as? AuthenticationMethodModel.Pin)?.code?.size
|
return (authMethodModel as? AuthenticationMethodModel.Pin)?.code?.size
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun computeHintedPinLength(authMethodModel: AuthenticationMethodModel): Int? {
|
|
||||||
// Hinting is enabled for 6-digit codes only
|
|
||||||
return autoConfirmPinLength(authMethodModel).takeIf { it == HINTING_PASSCODE_LENGTH }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun computeBackspaceButtonAppearance(
|
private fun computeBackspaceButtonAppearance(
|
||||||
authMethodModel: AuthenticationMethodModel,
|
authMethodModel: AuthenticationMethodModel,
|
||||||
enteredPin: List<EnteredKey>
|
enteredPin: List<EnteredKey>
|
||||||
@@ -149,7 +156,7 @@ class PinBouncerViewModel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
private fun computeConfirmButtonAppearance(
|
private fun computeConfirmButtonAppearance(
|
||||||
authMethodModel: AuthenticationMethodModel
|
authMethodModel: AuthenticationMethodModel?
|
||||||
): ActionButtonAppearance {
|
): ActionButtonAppearance {
|
||||||
return if (isAutoConfirmEnabled(authMethodModel)) {
|
return if (isAutoConfirmEnabled(authMethodModel)) {
|
||||||
ActionButtonAppearance.Hidden
|
ActionButtonAppearance.Hidden
|
||||||
|
|||||||
@@ -61,23 +61,16 @@ constructor(
|
|||||||
|
|
||||||
/** Whether it's currently possible to swipe up to dismiss the lockscreen. */
|
/** Whether it's currently possible to swipe up to dismiss the lockscreen. */
|
||||||
val isSwipeToDismissEnabled: StateFlow<Boolean> =
|
val isSwipeToDismissEnabled: StateFlow<Boolean> =
|
||||||
combine(
|
authenticationInteractor.isUnlocked
|
||||||
authenticationInteractor.isUnlocked,
|
.map { isUnlocked ->
|
||||||
authenticationInteractor.authenticationMethod,
|
!isUnlocked &&
|
||||||
) { isUnlocked, authMethod ->
|
authenticationInteractor.getAuthenticationMethod() is
|
||||||
isSwipeToUnlockEnabled(
|
AuthenticationMethodModel.Swipe
|
||||||
isUnlocked = isUnlocked,
|
|
||||||
authMethod = authMethod,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
.stateIn(
|
.stateIn(
|
||||||
scope = applicationScope,
|
scope = applicationScope,
|
||||||
started = SharingStarted.WhileSubscribed(),
|
started = SharingStarted.WhileSubscribed(),
|
||||||
initialValue =
|
initialValue = false,
|
||||||
isSwipeToUnlockEnabled(
|
|
||||||
isUnlocked = authenticationInteractor.isUnlocked.value,
|
|
||||||
authMethod = authenticationInteractor.authenticationMethod.value,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -124,44 +117,17 @@ constructor(
|
|||||||
// If switched from the lockscreen to the gone scene and the auth method was a swipe,
|
// If switched from the lockscreen to the gone scene and the auth method was a swipe,
|
||||||
// unlocks the device.
|
// unlocks the device.
|
||||||
applicationScope.launch {
|
applicationScope.launch {
|
||||||
combine(
|
sceneInteractor.currentScene(containerName).pairwise().collect {
|
||||||
authenticationInteractor.authenticationMethod,
|
(previousScene, currentScene) ->
|
||||||
sceneInteractor.currentScene(containerName).pairwise(),
|
if (
|
||||||
::Pair,
|
authenticationInteractor.getAuthenticationMethod() is
|
||||||
)
|
AuthenticationMethodModel.Swipe &&
|
||||||
.collect { (authMethod, scenes) ->
|
previousScene.key == SceneKey.Lockscreen &&
|
||||||
val (previousScene, currentScene) = scenes
|
currentScene.key == SceneKey.Gone
|
||||||
if (
|
) {
|
||||||
authMethod is AuthenticationMethodModel.Swipe &&
|
authenticationInteractor.unlockDevice()
|
||||||
previousScene.key == SceneKey.Lockscreen &&
|
|
||||||
currentScene.key == SceneKey.Gone
|
|
||||||
) {
|
|
||||||
authenticationInteractor.unlockDevice()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DISMISS Lockscreen IF AUTH METHOD IS REMOVED.
|
|
||||||
//
|
|
||||||
// If the auth method becomes None while on the lockscreen scene, dismisses the lock
|
|
||||||
// screen.
|
|
||||||
applicationScope.launch {
|
|
||||||
combine(
|
|
||||||
authenticationInteractor.authenticationMethod,
|
|
||||||
sceneInteractor.currentScene(containerName),
|
|
||||||
::Pair,
|
|
||||||
)
|
|
||||||
.collect { (authMethod, scene) ->
|
|
||||||
if (
|
|
||||||
scene.key == SceneKey.Lockscreen &&
|
|
||||||
authMethod == AuthenticationMethodModel.None
|
|
||||||
) {
|
|
||||||
sceneInteractor.setCurrentScene(
|
|
||||||
containerName = containerName,
|
|
||||||
scene = SceneModel(SceneKey.Gone),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,13 +136,6 @@ constructor(
|
|||||||
bouncerInteractor.showOrUnlockDevice(containerName = containerName)
|
bouncerInteractor.showOrUnlockDevice(containerName = containerName)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isSwipeToUnlockEnabled(
|
|
||||||
isUnlocked: Boolean,
|
|
||||||
authMethod: AuthenticationMethodModel,
|
|
||||||
): Boolean {
|
|
||||||
return !isUnlocked && authMethod is AuthenticationMethodModel.Swipe
|
|
||||||
}
|
|
||||||
|
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
interface Factory {
|
interface Factory {
|
||||||
fun create(
|
fun create(
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import com.android.systemui.coroutines.collectLastValue
|
|||||||
import com.android.systemui.scene.SceneTestUtils
|
import com.android.systemui.scene.SceneTestUtils
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
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.Test
|
import org.junit.Test
|
||||||
@@ -37,8 +36,8 @@ import org.junit.runners.JUnit4
|
|||||||
@RunWith(JUnit4::class)
|
@RunWith(JUnit4::class)
|
||||||
class AuthenticationInteractorTest : SysuiTestCase() {
|
class AuthenticationInteractorTest : SysuiTestCase() {
|
||||||
|
|
||||||
private val testScope = TestScope()
|
private val utils = SceneTestUtils(this)
|
||||||
private val utils = SceneTestUtils(this, testScope)
|
private val testScope = utils.testScope
|
||||||
private val repository: AuthenticationRepository = utils.authenticationRepository()
|
private val repository: AuthenticationRepository = utils.authenticationRepository()
|
||||||
private val underTest =
|
private val underTest =
|
||||||
utils.authenticationInteractor(
|
utils.authenticationInteractor(
|
||||||
@@ -46,23 +45,23 @@ class AuthenticationInteractorTest : SysuiTestCase() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun authMethod() =
|
fun getAuthenticationMethod() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val authMethod by collectLastValue(underTest.authenticationMethod)
|
assertThat(underTest.getAuthenticationMethod())
|
||||||
assertThat(authMethod).isEqualTo(AuthenticationMethodModel.Pin(1234))
|
.isEqualTo(AuthenticationMethodModel.Pin(1234))
|
||||||
|
|
||||||
underTest.setAuthenticationMethod(AuthenticationMethodModel.Password("password"))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
assertThat(authMethod).isEqualTo(AuthenticationMethodModel.Password("password"))
|
AuthenticationMethodModel.Password("password")
|
||||||
|
)
|
||||||
|
assertThat(underTest.getAuthenticationMethod())
|
||||||
|
.isEqualTo(AuthenticationMethodModel.Password("password"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun isUnlocked_whenAuthMethodIsNone_isTrue() =
|
fun isUnlocked_whenAuthMethodIsNone_isTrue() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
|
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.None)
|
||||||
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
||||||
assertThat(isUnlocked).isFalse()
|
|
||||||
|
|
||||||
underTest.setAuthenticationMethod(AuthenticationMethodModel.None)
|
|
||||||
|
|
||||||
assertThat(isUnlocked).isTrue()
|
assertThat(isUnlocked).isTrue()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +107,9 @@ class AuthenticationInteractorTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
underTest.lockDevice()
|
underTest.lockDevice()
|
||||||
runCurrent()
|
runCurrent()
|
||||||
underTest.setAuthenticationMethod(AuthenticationMethodModel.Password("password"))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Password("password")
|
||||||
|
)
|
||||||
|
|
||||||
assertThat(underTest.isAuthenticationRequired()).isTrue()
|
assertThat(underTest.isAuthenticationRequired()).isTrue()
|
||||||
}
|
}
|
||||||
@@ -118,7 +119,7 @@ class AuthenticationInteractorTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
underTest.lockDevice()
|
underTest.lockDevice()
|
||||||
runCurrent()
|
runCurrent()
|
||||||
underTest.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
|
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
|
||||||
|
|
||||||
assertThat(underTest.isAuthenticationRequired()).isFalse()
|
assertThat(underTest.isAuthenticationRequired()).isFalse()
|
||||||
}
|
}
|
||||||
@@ -128,7 +129,9 @@ class AuthenticationInteractorTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
underTest.unlockDevice()
|
underTest.unlockDevice()
|
||||||
runCurrent()
|
runCurrent()
|
||||||
underTest.setAuthenticationMethod(AuthenticationMethodModel.Password("password"))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Password("password")
|
||||||
|
)
|
||||||
|
|
||||||
assertThat(underTest.isAuthenticationRequired()).isFalse()
|
assertThat(underTest.isAuthenticationRequired()).isFalse()
|
||||||
}
|
}
|
||||||
@@ -138,7 +141,7 @@ class AuthenticationInteractorTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
underTest.unlockDevice()
|
underTest.unlockDevice()
|
||||||
runCurrent()
|
runCurrent()
|
||||||
underTest.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
|
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
|
||||||
|
|
||||||
assertThat(underTest.isAuthenticationRequired()).isFalse()
|
assertThat(underTest.isAuthenticationRequired()).isFalse()
|
||||||
}
|
}
|
||||||
@@ -148,7 +151,9 @@ class AuthenticationInteractorTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
|
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
|
||||||
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
||||||
underTest.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(1234)
|
||||||
|
)
|
||||||
assertThat(isUnlocked).isFalse()
|
assertThat(isUnlocked).isFalse()
|
||||||
|
|
||||||
assertThat(underTest.authenticate(listOf(1, 2, 3, 4))).isTrue()
|
assertThat(underTest.authenticate(listOf(1, 2, 3, 4))).isTrue()
|
||||||
@@ -161,7 +166,9 @@ class AuthenticationInteractorTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
|
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
|
||||||
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
||||||
underTest.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(1234)
|
||||||
|
)
|
||||||
assertThat(isUnlocked).isFalse()
|
assertThat(isUnlocked).isFalse()
|
||||||
|
|
||||||
assertThat(underTest.authenticate(listOf(9, 8, 7))).isFalse()
|
assertThat(underTest.authenticate(listOf(9, 8, 7))).isFalse()
|
||||||
@@ -174,7 +181,9 @@ class AuthenticationInteractorTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
|
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
|
||||||
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
||||||
underTest.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(1234)
|
||||||
|
)
|
||||||
assertThat(isUnlocked).isFalse()
|
assertThat(isUnlocked).isFalse()
|
||||||
|
|
||||||
assertThat(underTest.authenticate(listOf())).isFalse()
|
assertThat(underTest.authenticate(listOf())).isFalse()
|
||||||
@@ -187,7 +196,9 @@ class AuthenticationInteractorTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
|
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
|
||||||
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
||||||
underTest.setAuthenticationMethod(AuthenticationMethodModel.Pin(9999999999999999))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(9999999999999999)
|
||||||
|
)
|
||||||
assertThat(isUnlocked).isFalse()
|
assertThat(isUnlocked).isFalse()
|
||||||
|
|
||||||
assertThat(underTest.authenticate(List(16) { 9 })).isTrue()
|
assertThat(underTest.authenticate(List(16) { 9 })).isTrue()
|
||||||
@@ -206,7 +217,9 @@ class AuthenticationInteractorTest : SysuiTestCase() {
|
|||||||
|
|
||||||
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
|
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
|
||||||
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
||||||
underTest.setAuthenticationMethod(AuthenticationMethodModel.Pin(99999999999999999))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(99999999999999999)
|
||||||
|
)
|
||||||
assertThat(isUnlocked).isFalse()
|
assertThat(isUnlocked).isFalse()
|
||||||
|
|
||||||
assertThat(underTest.authenticate(List(17) { 9 })).isFalse()
|
assertThat(underTest.authenticate(List(17) { 9 })).isFalse()
|
||||||
@@ -219,7 +232,9 @@ class AuthenticationInteractorTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
|
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
|
||||||
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
||||||
underTest.setAuthenticationMethod(AuthenticationMethodModel.Password("password"))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Password("password")
|
||||||
|
)
|
||||||
assertThat(isUnlocked).isFalse()
|
assertThat(isUnlocked).isFalse()
|
||||||
|
|
||||||
assertThat(underTest.authenticate("password".toList())).isTrue()
|
assertThat(underTest.authenticate("password".toList())).isTrue()
|
||||||
@@ -232,7 +247,9 @@ class AuthenticationInteractorTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
|
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
|
||||||
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
||||||
underTest.setAuthenticationMethod(AuthenticationMethodModel.Password("password"))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Password("password")
|
||||||
|
)
|
||||||
assertThat(isUnlocked).isFalse()
|
assertThat(isUnlocked).isFalse()
|
||||||
|
|
||||||
assertThat(underTest.authenticate("alohomora".toList())).isFalse()
|
assertThat(underTest.authenticate("alohomora".toList())).isFalse()
|
||||||
@@ -245,7 +262,7 @@ class AuthenticationInteractorTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
|
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
|
||||||
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
||||||
underTest.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Pattern(
|
AuthenticationMethodModel.Pattern(
|
||||||
listOf(
|
listOf(
|
||||||
AuthenticationMethodModel.Pattern.PatternCoordinate(
|
AuthenticationMethodModel.Pattern.PatternCoordinate(
|
||||||
@@ -293,7 +310,7 @@ class AuthenticationInteractorTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
|
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
|
||||||
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
||||||
underTest.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Pattern(
|
AuthenticationMethodModel.Pattern(
|
||||||
listOf(
|
listOf(
|
||||||
AuthenticationMethodModel.Pattern.PatternCoordinate(
|
AuthenticationMethodModel.Pattern.PatternCoordinate(
|
||||||
@@ -341,7 +358,7 @@ class AuthenticationInteractorTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
|
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
|
||||||
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
||||||
underTest.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Pin(1234, autoConfirm = true)
|
AuthenticationMethodModel.Pin(1234, autoConfirm = true)
|
||||||
)
|
)
|
||||||
assertThat(isUnlocked).isFalse()
|
assertThat(isUnlocked).isFalse()
|
||||||
@@ -356,7 +373,7 @@ class AuthenticationInteractorTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
|
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
|
||||||
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
||||||
underTest.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Pin(1234, autoConfirm = true)
|
AuthenticationMethodModel.Pin(1234, autoConfirm = true)
|
||||||
)
|
)
|
||||||
assertThat(isUnlocked).isFalse()
|
assertThat(isUnlocked).isFalse()
|
||||||
@@ -371,7 +388,7 @@ class AuthenticationInteractorTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
|
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
|
||||||
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
||||||
underTest.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Pin(1234, autoConfirm = true)
|
AuthenticationMethodModel.Pin(1234, autoConfirm = true)
|
||||||
)
|
)
|
||||||
assertThat(isUnlocked).isFalse()
|
assertThat(isUnlocked).isFalse()
|
||||||
@@ -386,7 +403,7 @@ class AuthenticationInteractorTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
|
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
|
||||||
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
||||||
underTest.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Pin(1234, autoConfirm = true)
|
AuthenticationMethodModel.Pin(1234, autoConfirm = true)
|
||||||
)
|
)
|
||||||
assertThat(isUnlocked).isFalse()
|
assertThat(isUnlocked).isFalse()
|
||||||
@@ -402,7 +419,7 @@ class AuthenticationInteractorTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
|
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
|
||||||
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
||||||
underTest.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Pin(1234, autoConfirm = true)
|
AuthenticationMethodModel.Pin(1234, autoConfirm = true)
|
||||||
)
|
)
|
||||||
assertThat(isUnlocked).isFalse()
|
assertThat(isUnlocked).isFalse()
|
||||||
@@ -417,7 +434,7 @@ class AuthenticationInteractorTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
|
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
|
||||||
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
||||||
underTest.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Pin(1234, autoConfirm = false)
|
AuthenticationMethodModel.Pin(1234, autoConfirm = false)
|
||||||
)
|
)
|
||||||
assertThat(isUnlocked).isFalse()
|
assertThat(isUnlocked).isFalse()
|
||||||
@@ -432,22 +449,13 @@ class AuthenticationInteractorTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
|
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
|
||||||
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
||||||
underTest.setAuthenticationMethod(AuthenticationMethodModel.Password("password"))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Password("password")
|
||||||
|
)
|
||||||
assertThat(isUnlocked).isFalse()
|
assertThat(isUnlocked).isFalse()
|
||||||
|
|
||||||
assertThat(underTest.authenticate("password".toList(), tryAutoConfirm = true)).isNull()
|
assertThat(underTest.authenticate("password".toList(), tryAutoConfirm = true)).isNull()
|
||||||
assertThat(isUnlocked).isFalse()
|
assertThat(isUnlocked).isFalse()
|
||||||
assertThat(failedAttemptCount).isEqualTo(0)
|
assertThat(failedAttemptCount).isEqualTo(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
fun unlocksDevice_whenAuthMethodBecomesNone() =
|
|
||||||
testScope.runTest {
|
|
||||||
val isUnlocked by collectLastValue(underTest.isUnlocked)
|
|
||||||
assertThat(isUnlocked).isFalse()
|
|
||||||
|
|
||||||
repository.setAuthenticationMethod(AuthenticationMethodModel.None)
|
|
||||||
|
|
||||||
assertThat(isUnlocked).isTrue()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ import com.android.systemui.scene.shared.model.SceneKey
|
|||||||
import com.android.systemui.scene.shared.model.SceneModel
|
import com.android.systemui.scene.shared.model.SceneModel
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.test.TestScope
|
|
||||||
import kotlinx.coroutines.test.advanceTimeBy
|
import kotlinx.coroutines.test.advanceTimeBy
|
||||||
import kotlinx.coroutines.test.runCurrent
|
import kotlinx.coroutines.test.runCurrent
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
@@ -40,8 +39,8 @@ import org.junit.runners.JUnit4
|
|||||||
@RunWith(JUnit4::class)
|
@RunWith(JUnit4::class)
|
||||||
class BouncerInteractorTest : SysuiTestCase() {
|
class BouncerInteractorTest : SysuiTestCase() {
|
||||||
|
|
||||||
private val testScope = TestScope()
|
private val utils = SceneTestUtils(this)
|
||||||
private val utils = SceneTestUtils(this, testScope)
|
private val testScope = utils.testScope
|
||||||
private val authenticationInteractor =
|
private val authenticationInteractor =
|
||||||
utils.authenticationInteractor(
|
utils.authenticationInteractor(
|
||||||
repository = utils.authenticationRepository(),
|
repository = utils.authenticationRepository(),
|
||||||
@@ -69,7 +68,9 @@ class BouncerInteractorTest : SysuiTestCase() {
|
|||||||
val currentScene by collectLastValue(sceneInteractor.currentScene("container1"))
|
val currentScene by collectLastValue(sceneInteractor.currentScene("container1"))
|
||||||
val message by collectLastValue(underTest.message)
|
val message by collectLastValue(underTest.message)
|
||||||
|
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(1234)
|
||||||
|
)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
underTest.showOrUnlockDevice("container1")
|
underTest.showOrUnlockDevice("container1")
|
||||||
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
|
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
|
||||||
@@ -100,7 +101,7 @@ class BouncerInteractorTest : SysuiTestCase() {
|
|||||||
val currentScene by collectLastValue(sceneInteractor.currentScene("container1"))
|
val currentScene by collectLastValue(sceneInteractor.currentScene("container1"))
|
||||||
val message by collectLastValue(underTest.message)
|
val message by collectLastValue(underTest.message)
|
||||||
|
|
||||||
authenticationInteractor.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Pin(1234, autoConfirm = true)
|
AuthenticationMethodModel.Pin(1234, autoConfirm = true)
|
||||||
)
|
)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
@@ -130,7 +131,7 @@ class BouncerInteractorTest : SysuiTestCase() {
|
|||||||
val currentScene by collectLastValue(sceneInteractor.currentScene("container1"))
|
val currentScene by collectLastValue(sceneInteractor.currentScene("container1"))
|
||||||
val message by collectLastValue(underTest.message)
|
val message by collectLastValue(underTest.message)
|
||||||
|
|
||||||
authenticationInteractor.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Pin(1234, autoConfirm = false)
|
AuthenticationMethodModel.Pin(1234, autoConfirm = false)
|
||||||
)
|
)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
@@ -154,7 +155,7 @@ class BouncerInteractorTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val currentScene by collectLastValue(sceneInteractor.currentScene("container1"))
|
val currentScene by collectLastValue(sceneInteractor.currentScene("container1"))
|
||||||
val message by collectLastValue(underTest.message)
|
val message by collectLastValue(underTest.message)
|
||||||
authenticationInteractor.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Password("password")
|
AuthenticationMethodModel.Password("password")
|
||||||
)
|
)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
@@ -186,7 +187,7 @@ class BouncerInteractorTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val currentScene by collectLastValue(sceneInteractor.currentScene("container1"))
|
val currentScene by collectLastValue(sceneInteractor.currentScene("container1"))
|
||||||
val message by collectLastValue(underTest.message)
|
val message by collectLastValue(underTest.message)
|
||||||
authenticationInteractor.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Pattern(emptyList())
|
AuthenticationMethodModel.Pattern(emptyList())
|
||||||
)
|
)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
@@ -222,7 +223,9 @@ class BouncerInteractorTest : SysuiTestCase() {
|
|||||||
fun showOrUnlockDevice_notLocked_switchesToGoneScene() =
|
fun showOrUnlockDevice_notLocked_switchesToGoneScene() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val currentScene by collectLastValue(sceneInteractor.currentScene("container1"))
|
val currentScene by collectLastValue(sceneInteractor.currentScene("container1"))
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(1234)
|
||||||
|
)
|
||||||
authenticationInteractor.unlockDevice()
|
authenticationInteractor.unlockDevice()
|
||||||
runCurrent()
|
runCurrent()
|
||||||
|
|
||||||
@@ -235,7 +238,7 @@ class BouncerInteractorTest : SysuiTestCase() {
|
|||||||
fun showOrUnlockDevice_authMethodNotSecure_switchesToGoneScene() =
|
fun showOrUnlockDevice_authMethodNotSecure_switchesToGoneScene() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val currentScene by collectLastValue(sceneInteractor.currentScene("container1"))
|
val currentScene by collectLastValue(sceneInteractor.currentScene("container1"))
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
|
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
|
|
||||||
underTest.showOrUnlockDevice("container1")
|
underTest.showOrUnlockDevice("container1")
|
||||||
@@ -248,7 +251,7 @@ class BouncerInteractorTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val currentScene by collectLastValue(sceneInteractor.currentScene("container1"))
|
val currentScene by collectLastValue(sceneInteractor.currentScene("container1"))
|
||||||
val message by collectLastValue(underTest.message)
|
val message by collectLastValue(underTest.message)
|
||||||
authenticationInteractor.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Password("password")
|
AuthenticationMethodModel.Password("password")
|
||||||
)
|
)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
@@ -266,7 +269,9 @@ class BouncerInteractorTest : SysuiTestCase() {
|
|||||||
val throttling by collectLastValue(underTest.throttling)
|
val throttling by collectLastValue(underTest.throttling)
|
||||||
val message by collectLastValue(underTest.message)
|
val message by collectLastValue(underTest.message)
|
||||||
val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
|
val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(1234)
|
||||||
|
)
|
||||||
assertThat(throttling).isNull()
|
assertThat(throttling).isNull()
|
||||||
assertThat(message).isEqualTo("")
|
assertThat(message).isEqualTo("")
|
||||||
assertThat(isUnlocked).isFalse()
|
assertThat(isUnlocked).isFalse()
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import com.android.systemui.scene.SceneTestUtils
|
|||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.test.TestScope
|
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
@@ -35,8 +34,8 @@ import org.junit.runners.JUnit4
|
|||||||
@RunWith(JUnit4::class)
|
@RunWith(JUnit4::class)
|
||||||
class AuthMethodBouncerViewModelTest : SysuiTestCase() {
|
class AuthMethodBouncerViewModelTest : SysuiTestCase() {
|
||||||
|
|
||||||
private val testScope = TestScope()
|
private val utils = SceneTestUtils(this)
|
||||||
private val utils = SceneTestUtils(this, testScope)
|
private val testScope = utils.testScope
|
||||||
private val authenticationInteractor =
|
private val authenticationInteractor =
|
||||||
utils.authenticationInteractor(
|
utils.authenticationInteractor(
|
||||||
utils.authenticationRepository(),
|
utils.authenticationRepository(),
|
||||||
@@ -55,7 +54,9 @@ class AuthMethodBouncerViewModelTest : SysuiTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun animateFailure() =
|
fun animateFailure() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(1234)
|
||||||
|
)
|
||||||
val animateFailure by collectLastValue(underTest.animateFailure)
|
val animateFailure by collectLastValue(underTest.animateFailure)
|
||||||
assertThat(animateFailure).isFalse()
|
assertThat(animateFailure).isFalse()
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ import com.google.common.truth.Truth.assertThat
|
|||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.flow.emptyFlow
|
import kotlinx.coroutines.flow.emptyFlow
|
||||||
import kotlinx.coroutines.flow.flatMapLatest
|
import kotlinx.coroutines.flow.flatMapLatest
|
||||||
import kotlinx.coroutines.test.TestScope
|
|
||||||
import kotlinx.coroutines.test.advanceTimeBy
|
import kotlinx.coroutines.test.advanceTimeBy
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
@@ -38,8 +37,8 @@ import org.junit.runners.JUnit4
|
|||||||
@RunWith(JUnit4::class)
|
@RunWith(JUnit4::class)
|
||||||
class BouncerViewModelTest : SysuiTestCase() {
|
class BouncerViewModelTest : SysuiTestCase() {
|
||||||
|
|
||||||
private val testScope = TestScope()
|
private val utils = SceneTestUtils(this)
|
||||||
private val utils = SceneTestUtils(this, testScope)
|
private val testScope = utils.testScope
|
||||||
private val authenticationInteractor =
|
private val authenticationInteractor =
|
||||||
utils.authenticationInteractor(
|
utils.authenticationInteractor(
|
||||||
repository = utils.authenticationRepository(),
|
repository = utils.authenticationRepository(),
|
||||||
@@ -54,11 +53,11 @@ class BouncerViewModelTest : SysuiTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun authMethod_nonNullForSecureMethods_nullForNotSecureMethods() =
|
fun authMethod_nonNullForSecureMethods_nullForNotSecureMethods() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val authMethodViewModel: AuthMethodBouncerViewModel? by
|
|
||||||
collectLastValue(underTest.authMethod)
|
|
||||||
authMethodsToTest().forEach { authMethod ->
|
authMethodsToTest().forEach { authMethod ->
|
||||||
authenticationInteractor.setAuthenticationMethod(authMethod)
|
utils.authenticationRepository.setAuthenticationMethod(authMethod)
|
||||||
|
|
||||||
|
val authMethodViewModel: AuthMethodBouncerViewModel? by
|
||||||
|
collectLastValue(underTest.authMethod)
|
||||||
if (authMethod.isSecure) {
|
if (authMethod.isSecure) {
|
||||||
assertThat(authMethodViewModel).isNotNull()
|
assertThat(authMethodViewModel).isNotNull()
|
||||||
} else {
|
} else {
|
||||||
@@ -75,13 +74,13 @@ class BouncerViewModelTest : SysuiTestCase() {
|
|||||||
collectLastValue(underTest.authMethod)
|
collectLastValue(underTest.authMethod)
|
||||||
// First pass, populate our "seen" map:
|
// First pass, populate our "seen" map:
|
||||||
authMethodsToTest().forEach { authMethod ->
|
authMethodsToTest().forEach { authMethod ->
|
||||||
authenticationInteractor.setAuthenticationMethod(authMethod)
|
utils.authenticationRepository.setAuthenticationMethod(authMethod)
|
||||||
authMethodViewModel?.let { seen[authMethod] = it }
|
authMethodViewModel?.let { seen[authMethod] = it }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Second pass, assert same instances are reused:
|
// Second pass, assert same instances are reused:
|
||||||
authMethodsToTest().forEach { authMethod ->
|
authMethodsToTest().forEach { authMethod ->
|
||||||
authenticationInteractor.setAuthenticationMethod(authMethod)
|
utils.authenticationRepository.setAuthenticationMethod(authMethod)
|
||||||
authMethodViewModel?.let { assertThat(it).isSameInstanceAs(seen[authMethod]) }
|
authMethodViewModel?.let { assertThat(it).isSameInstanceAs(seen[authMethod]) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -97,7 +96,9 @@ class BouncerViewModelTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val message by collectLastValue(underTest.message)
|
val message by collectLastValue(underTest.message)
|
||||||
val throttling by collectLastValue(bouncerInteractor.throttling)
|
val throttling by collectLastValue(bouncerInteractor.throttling)
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(1234)
|
||||||
|
)
|
||||||
assertThat(message?.isUpdateAnimated).isTrue()
|
assertThat(message?.isUpdateAnimated).isTrue()
|
||||||
|
|
||||||
repeat(BouncerInteractor.THROTTLE_EVERY) {
|
repeat(BouncerInteractor.THROTTLE_EVERY) {
|
||||||
@@ -120,7 +121,9 @@ class BouncerViewModelTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
val throttling by collectLastValue(bouncerInteractor.throttling)
|
val throttling by collectLastValue(bouncerInteractor.throttling)
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(1234)
|
||||||
|
)
|
||||||
assertThat(isInputEnabled).isTrue()
|
assertThat(isInputEnabled).isTrue()
|
||||||
|
|
||||||
repeat(BouncerInteractor.THROTTLE_EVERY) {
|
repeat(BouncerInteractor.THROTTLE_EVERY) {
|
||||||
@@ -137,7 +140,9 @@ class BouncerViewModelTest : SysuiTestCase() {
|
|||||||
fun throttlingDialogMessage() =
|
fun throttlingDialogMessage() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val throttlingDialogMessage by collectLastValue(underTest.throttlingDialogMessage)
|
val throttlingDialogMessage by collectLastValue(underTest.throttlingDialogMessage)
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(1234)
|
||||||
|
)
|
||||||
|
|
||||||
repeat(BouncerInteractor.THROTTLE_EVERY) {
|
repeat(BouncerInteractor.THROTTLE_EVERY) {
|
||||||
// Wrong PIN.
|
// Wrong PIN.
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import com.google.common.truth.Truth.assertThat
|
|||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.test.TestScope
|
import kotlinx.coroutines.test.runCurrent
|
||||||
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
|
||||||
@@ -40,8 +40,8 @@ import org.junit.runners.JUnit4
|
|||||||
@RunWith(JUnit4::class)
|
@RunWith(JUnit4::class)
|
||||||
class PasswordBouncerViewModelTest : SysuiTestCase() {
|
class PasswordBouncerViewModelTest : SysuiTestCase() {
|
||||||
|
|
||||||
private val testScope = TestScope()
|
private val utils = SceneTestUtils(this)
|
||||||
private val utils = SceneTestUtils(this, testScope)
|
private val testScope = utils.testScope
|
||||||
private val authenticationInteractor =
|
private val authenticationInteractor =
|
||||||
utils.authenticationInteractor(
|
utils.authenticationInteractor(
|
||||||
repository = utils.authenticationRepository(),
|
repository = utils.authenticationRepository(),
|
||||||
@@ -58,6 +58,7 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
|
|||||||
)
|
)
|
||||||
private val underTest =
|
private val underTest =
|
||||||
PasswordBouncerViewModel(
|
PasswordBouncerViewModel(
|
||||||
|
applicationScope = testScope.backgroundScope,
|
||||||
interactor = bouncerInteractor,
|
interactor = bouncerInteractor,
|
||||||
isInputEnabled = MutableStateFlow(true).asStateFlow(),
|
isInputEnabled = MutableStateFlow(true).asStateFlow(),
|
||||||
)
|
)
|
||||||
@@ -75,7 +76,7 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
|
|||||||
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
|
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
|
||||||
val message by collectLastValue(bouncerViewModel.message)
|
val message by collectLastValue(bouncerViewModel.message)
|
||||||
val password by collectLastValue(underTest.password)
|
val password by collectLastValue(underTest.password)
|
||||||
authenticationInteractor.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Password("password")
|
AuthenticationMethodModel.Password("password")
|
||||||
)
|
)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
@@ -98,7 +99,7 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
|
|||||||
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
|
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
|
||||||
val message by collectLastValue(bouncerViewModel.message)
|
val message by collectLastValue(bouncerViewModel.message)
|
||||||
val password by collectLastValue(underTest.password)
|
val password by collectLastValue(underTest.password)
|
||||||
authenticationInteractor.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Password("password")
|
AuthenticationMethodModel.Password("password")
|
||||||
)
|
)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
@@ -106,6 +107,7 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
|
|||||||
assertThat(isUnlocked).isFalse()
|
assertThat(isUnlocked).isFalse()
|
||||||
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
|
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
|
||||||
underTest.onShown()
|
underTest.onShown()
|
||||||
|
runCurrent()
|
||||||
|
|
||||||
underTest.onPasswordInputChanged("password")
|
underTest.onPasswordInputChanged("password")
|
||||||
|
|
||||||
@@ -120,7 +122,7 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
|
val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
|
||||||
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
|
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
|
||||||
authenticationInteractor.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Password("password")
|
AuthenticationMethodModel.Password("password")
|
||||||
)
|
)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
@@ -143,7 +145,7 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
|
|||||||
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
|
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
|
||||||
val message by collectLastValue(bouncerViewModel.message)
|
val message by collectLastValue(bouncerViewModel.message)
|
||||||
val password by collectLastValue(underTest.password)
|
val password by collectLastValue(underTest.password)
|
||||||
authenticationInteractor.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Password("password")
|
AuthenticationMethodModel.Password("password")
|
||||||
)
|
)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
@@ -168,7 +170,7 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
|
|||||||
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
|
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
|
||||||
val message by collectLastValue(bouncerViewModel.message)
|
val message by collectLastValue(bouncerViewModel.message)
|
||||||
val password by collectLastValue(underTest.password)
|
val password by collectLastValue(underTest.password)
|
||||||
authenticationInteractor.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Password("password")
|
AuthenticationMethodModel.Password("password")
|
||||||
)
|
)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ import com.google.common.truth.Truth.assertWithMessage
|
|||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.test.TestScope
|
import kotlinx.coroutines.test.runCurrent
|
||||||
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
|
||||||
@@ -41,8 +41,8 @@ import org.junit.runners.JUnit4
|
|||||||
@RunWith(JUnit4::class)
|
@RunWith(JUnit4::class)
|
||||||
class PatternBouncerViewModelTest : SysuiTestCase() {
|
class PatternBouncerViewModelTest : SysuiTestCase() {
|
||||||
|
|
||||||
private val testScope = TestScope()
|
private val utils = SceneTestUtils(this)
|
||||||
private val utils = SceneTestUtils(this, testScope)
|
private val testScope = utils.testScope
|
||||||
private val authenticationInteractor =
|
private val authenticationInteractor =
|
||||||
utils.authenticationInteractor(
|
utils.authenticationInteractor(
|
||||||
repository = utils.authenticationRepository(),
|
repository = utils.authenticationRepository(),
|
||||||
@@ -79,7 +79,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
|
|||||||
val message by collectLastValue(bouncerViewModel.message)
|
val message by collectLastValue(bouncerViewModel.message)
|
||||||
val selectedDots by collectLastValue(underTest.selectedDots)
|
val selectedDots by collectLastValue(underTest.selectedDots)
|
||||||
val currentDot by collectLastValue(underTest.currentDot)
|
val currentDot by collectLastValue(underTest.currentDot)
|
||||||
authenticationInteractor.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Pattern(CORRECT_PATTERN)
|
AuthenticationMethodModel.Pattern(CORRECT_PATTERN)
|
||||||
)
|
)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
@@ -104,7 +104,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
|
|||||||
val message by collectLastValue(bouncerViewModel.message)
|
val message by collectLastValue(bouncerViewModel.message)
|
||||||
val selectedDots by collectLastValue(underTest.selectedDots)
|
val selectedDots by collectLastValue(underTest.selectedDots)
|
||||||
val currentDot by collectLastValue(underTest.currentDot)
|
val currentDot by collectLastValue(underTest.currentDot)
|
||||||
authenticationInteractor.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Pattern(CORRECT_PATTERN)
|
AuthenticationMethodModel.Pattern(CORRECT_PATTERN)
|
||||||
)
|
)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
@@ -112,6 +112,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
|
|||||||
assertThat(isUnlocked).isFalse()
|
assertThat(isUnlocked).isFalse()
|
||||||
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
|
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
|
||||||
underTest.onShown()
|
underTest.onShown()
|
||||||
|
runCurrent()
|
||||||
|
|
||||||
underTest.onDragStart()
|
underTest.onDragStart()
|
||||||
|
|
||||||
@@ -129,7 +130,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
|
|||||||
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
|
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
|
||||||
val selectedDots by collectLastValue(underTest.selectedDots)
|
val selectedDots by collectLastValue(underTest.selectedDots)
|
||||||
val currentDot by collectLastValue(underTest.currentDot)
|
val currentDot by collectLastValue(underTest.currentDot)
|
||||||
authenticationInteractor.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Pattern(CORRECT_PATTERN)
|
AuthenticationMethodModel.Pattern(CORRECT_PATTERN)
|
||||||
)
|
)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
@@ -180,7 +181,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
|
|||||||
val message by collectLastValue(bouncerViewModel.message)
|
val message by collectLastValue(bouncerViewModel.message)
|
||||||
val selectedDots by collectLastValue(underTest.selectedDots)
|
val selectedDots by collectLastValue(underTest.selectedDots)
|
||||||
val currentDot by collectLastValue(underTest.currentDot)
|
val currentDot by collectLastValue(underTest.currentDot)
|
||||||
authenticationInteractor.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Pattern(CORRECT_PATTERN)
|
AuthenticationMethodModel.Pattern(CORRECT_PATTERN)
|
||||||
)
|
)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
@@ -215,7 +216,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
|
|||||||
val message by collectLastValue(bouncerViewModel.message)
|
val message by collectLastValue(bouncerViewModel.message)
|
||||||
val selectedDots by collectLastValue(underTest.selectedDots)
|
val selectedDots by collectLastValue(underTest.selectedDots)
|
||||||
val currentDot by collectLastValue(underTest.currentDot)
|
val currentDot by collectLastValue(underTest.currentDot)
|
||||||
authenticationInteractor.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Pattern(CORRECT_PATTERN)
|
AuthenticationMethodModel.Pattern(CORRECT_PATTERN)
|
||||||
)
|
)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ import com.google.common.truth.Truth.assertThat
|
|||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.test.TestScope
|
import kotlinx.coroutines.test.runCurrent
|
||||||
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
|
||||||
@@ -41,8 +41,8 @@ import org.junit.runners.JUnit4
|
|||||||
@RunWith(JUnit4::class)
|
@RunWith(JUnit4::class)
|
||||||
class PinBouncerViewModelTest : SysuiTestCase() {
|
class PinBouncerViewModelTest : SysuiTestCase() {
|
||||||
|
|
||||||
private val testScope = TestScope()
|
private val utils = SceneTestUtils(this)
|
||||||
private val utils = SceneTestUtils(this, testScope)
|
private val testScope = utils.testScope
|
||||||
private val sceneInteractor = utils.sceneInteractor()
|
private val sceneInteractor = utils.sceneInteractor()
|
||||||
private val authenticationInteractor =
|
private val authenticationInteractor =
|
||||||
utils.authenticationInteractor(
|
utils.authenticationInteractor(
|
||||||
@@ -85,7 +85,6 @@ class PinBouncerViewModelTest : SysuiTestCase() {
|
|||||||
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
|
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
|
||||||
val message by collectLastValue(bouncerViewModel.message)
|
val message by collectLastValue(bouncerViewModel.message)
|
||||||
val entries by collectLastValue(underTest.pinEntries)
|
val entries by collectLastValue(underTest.pinEntries)
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
|
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
|
sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
|
||||||
assertThat(isUnlocked).isFalse()
|
assertThat(isUnlocked).isFalse()
|
||||||
@@ -106,12 +105,15 @@ class PinBouncerViewModelTest : SysuiTestCase() {
|
|||||||
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
|
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
|
||||||
val message by collectLastValue(bouncerViewModel.message)
|
val message by collectLastValue(bouncerViewModel.message)
|
||||||
val entries by collectLastValue(underTest.pinEntries)
|
val entries by collectLastValue(underTest.pinEntries)
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(1234)
|
||||||
|
)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
|
sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
|
||||||
assertThat(isUnlocked).isFalse()
|
assertThat(isUnlocked).isFalse()
|
||||||
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
|
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
|
||||||
underTest.onShown()
|
underTest.onShown()
|
||||||
|
runCurrent()
|
||||||
|
|
||||||
underTest.onPinButtonClicked(1)
|
underTest.onPinButtonClicked(1)
|
||||||
|
|
||||||
@@ -129,12 +131,15 @@ class PinBouncerViewModelTest : SysuiTestCase() {
|
|||||||
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
|
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
|
||||||
val message by collectLastValue(bouncerViewModel.message)
|
val message by collectLastValue(bouncerViewModel.message)
|
||||||
val entries by collectLastValue(underTest.pinEntries)
|
val entries by collectLastValue(underTest.pinEntries)
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(1234)
|
||||||
|
)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
|
sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
|
||||||
assertThat(isUnlocked).isFalse()
|
assertThat(isUnlocked).isFalse()
|
||||||
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
|
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
|
||||||
underTest.onShown()
|
underTest.onShown()
|
||||||
|
runCurrent()
|
||||||
underTest.onPinButtonClicked(1)
|
underTest.onPinButtonClicked(1)
|
||||||
assertThat(entries).hasSize(1)
|
assertThat(entries).hasSize(1)
|
||||||
|
|
||||||
@@ -153,7 +158,9 @@ class PinBouncerViewModelTest : SysuiTestCase() {
|
|||||||
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
|
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
|
||||||
val message by collectLastValue(bouncerViewModel.message)
|
val message by collectLastValue(bouncerViewModel.message)
|
||||||
val entries by collectLastValue(underTest.pinEntries)
|
val entries by collectLastValue(underTest.pinEntries)
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(1234)
|
||||||
|
)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
|
sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
|
||||||
assertThat(isUnlocked).isFalse()
|
assertThat(isUnlocked).isFalse()
|
||||||
@@ -180,12 +187,15 @@ class PinBouncerViewModelTest : SysuiTestCase() {
|
|||||||
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
|
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
|
||||||
val message by collectLastValue(bouncerViewModel.message)
|
val message by collectLastValue(bouncerViewModel.message)
|
||||||
val entries by collectLastValue(underTest.pinEntries)
|
val entries by collectLastValue(underTest.pinEntries)
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(1234)
|
||||||
|
)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
|
sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
|
||||||
assertThat(isUnlocked).isFalse()
|
assertThat(isUnlocked).isFalse()
|
||||||
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
|
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
|
||||||
underTest.onShown()
|
underTest.onShown()
|
||||||
|
runCurrent()
|
||||||
underTest.onPinButtonClicked(1)
|
underTest.onPinButtonClicked(1)
|
||||||
underTest.onPinButtonClicked(2)
|
underTest.onPinButtonClicked(2)
|
||||||
underTest.onPinButtonClicked(3)
|
underTest.onPinButtonClicked(3)
|
||||||
@@ -204,7 +214,9 @@ class PinBouncerViewModelTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
|
val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
|
||||||
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
|
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(1234)
|
||||||
|
)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
|
sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
|
||||||
assertThat(isUnlocked).isFalse()
|
assertThat(isUnlocked).isFalse()
|
||||||
@@ -228,7 +240,9 @@ class PinBouncerViewModelTest : SysuiTestCase() {
|
|||||||
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
|
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
|
||||||
val message by collectLastValue(bouncerViewModel.message)
|
val message by collectLastValue(bouncerViewModel.message)
|
||||||
val entries by collectLastValue(underTest.pinEntries)
|
val entries by collectLastValue(underTest.pinEntries)
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(1234)
|
||||||
|
)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
|
sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
|
||||||
assertThat(isUnlocked).isFalse()
|
assertThat(isUnlocked).isFalse()
|
||||||
@@ -255,7 +269,9 @@ class PinBouncerViewModelTest : SysuiTestCase() {
|
|||||||
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
|
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
|
||||||
val message by collectLastValue(bouncerViewModel.message)
|
val message by collectLastValue(bouncerViewModel.message)
|
||||||
val entries by collectLastValue(underTest.pinEntries)
|
val entries by collectLastValue(underTest.pinEntries)
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(1234)
|
||||||
|
)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
|
sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
|
||||||
assertThat(isUnlocked).isFalse()
|
assertThat(isUnlocked).isFalse()
|
||||||
@@ -290,7 +306,7 @@ class PinBouncerViewModelTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
|
val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
|
||||||
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
|
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
|
||||||
authenticationInteractor.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Pin(1234, autoConfirm = true)
|
AuthenticationMethodModel.Pin(1234, autoConfirm = true)
|
||||||
)
|
)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
@@ -314,7 +330,7 @@ class PinBouncerViewModelTest : SysuiTestCase() {
|
|||||||
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
|
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
|
||||||
val message by collectLastValue(bouncerViewModel.message)
|
val message by collectLastValue(bouncerViewModel.message)
|
||||||
val entries by collectLastValue(underTest.pinEntries)
|
val entries by collectLastValue(underTest.pinEntries)
|
||||||
authenticationInteractor.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Pin(1234, autoConfirm = true)
|
AuthenticationMethodModel.Pin(1234, autoConfirm = true)
|
||||||
)
|
)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
@@ -338,7 +354,7 @@ class PinBouncerViewModelTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val backspaceButtonAppearance by collectLastValue(underTest.backspaceButtonAppearance)
|
val backspaceButtonAppearance by collectLastValue(underTest.backspaceButtonAppearance)
|
||||||
|
|
||||||
authenticationInteractor.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Pin(1234, autoConfirm = false)
|
AuthenticationMethodModel.Pin(1234, autoConfirm = false)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -349,7 +365,7 @@ class PinBouncerViewModelTest : SysuiTestCase() {
|
|||||||
fun backspaceButtonAppearance_withAutoConfirmButNoInput_isHidden() =
|
fun backspaceButtonAppearance_withAutoConfirmButNoInput_isHidden() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val backspaceButtonAppearance by collectLastValue(underTest.backspaceButtonAppearance)
|
val backspaceButtonAppearance by collectLastValue(underTest.backspaceButtonAppearance)
|
||||||
authenticationInteractor.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Pin(1234, autoConfirm = true)
|
AuthenticationMethodModel.Pin(1234, autoConfirm = true)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -360,7 +376,7 @@ class PinBouncerViewModelTest : SysuiTestCase() {
|
|||||||
fun backspaceButtonAppearance_withAutoConfirmAndInput_isShownQuiet() =
|
fun backspaceButtonAppearance_withAutoConfirmAndInput_isShownQuiet() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val backspaceButtonAppearance by collectLastValue(underTest.backspaceButtonAppearance)
|
val backspaceButtonAppearance by collectLastValue(underTest.backspaceButtonAppearance)
|
||||||
authenticationInteractor.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Pin(1234, autoConfirm = true)
|
AuthenticationMethodModel.Pin(1234, autoConfirm = true)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -374,7 +390,7 @@ class PinBouncerViewModelTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val confirmButtonAppearance by collectLastValue(underTest.confirmButtonAppearance)
|
val confirmButtonAppearance by collectLastValue(underTest.confirmButtonAppearance)
|
||||||
|
|
||||||
authenticationInteractor.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Pin(1234, autoConfirm = false)
|
AuthenticationMethodModel.Pin(1234, autoConfirm = false)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -385,7 +401,7 @@ class PinBouncerViewModelTest : SysuiTestCase() {
|
|||||||
fun confirmButtonAppearance_withAutoConfirm_isHidden() =
|
fun confirmButtonAppearance_withAutoConfirm_isHidden() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val confirmButtonAppearance by collectLastValue(underTest.confirmButtonAppearance)
|
val confirmButtonAppearance by collectLastValue(underTest.confirmButtonAppearance)
|
||||||
authenticationInteractor.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Pin(1234, autoConfirm = true)
|
AuthenticationMethodModel.Pin(1234, autoConfirm = true)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -396,7 +412,7 @@ class PinBouncerViewModelTest : SysuiTestCase() {
|
|||||||
fun hintedPinLength_withoutAutoConfirm_isNull() =
|
fun hintedPinLength_withoutAutoConfirm_isNull() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val hintedPinLength by collectLastValue(underTest.hintedPinLength)
|
val hintedPinLength by collectLastValue(underTest.hintedPinLength)
|
||||||
authenticationInteractor.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Pin(1234, autoConfirm = false)
|
AuthenticationMethodModel.Pin(1234, autoConfirm = false)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -407,7 +423,7 @@ class PinBouncerViewModelTest : SysuiTestCase() {
|
|||||||
fun hintedPinLength_withAutoConfirmPinLessThanSixDigits_isNull() =
|
fun hintedPinLength_withAutoConfirmPinLessThanSixDigits_isNull() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val hintedPinLength by collectLastValue(underTest.hintedPinLength)
|
val hintedPinLength by collectLastValue(underTest.hintedPinLength)
|
||||||
authenticationInteractor.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Pin(12345, autoConfirm = true)
|
AuthenticationMethodModel.Pin(12345, autoConfirm = true)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -418,7 +434,7 @@ class PinBouncerViewModelTest : SysuiTestCase() {
|
|||||||
fun hintedPinLength_withAutoConfirmPinExactlySixDigits_isSix() =
|
fun hintedPinLength_withAutoConfirmPinExactlySixDigits_isSix() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val hintedPinLength by collectLastValue(underTest.hintedPinLength)
|
val hintedPinLength by collectLastValue(underTest.hintedPinLength)
|
||||||
authenticationInteractor.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Pin(123456, autoConfirm = true)
|
AuthenticationMethodModel.Pin(123456, autoConfirm = true)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -429,7 +445,7 @@ class PinBouncerViewModelTest : SysuiTestCase() {
|
|||||||
fun hintedPinLength_withAutoConfirmPinMoreThanSixDigits_isNull() =
|
fun hintedPinLength_withAutoConfirmPinMoreThanSixDigits_isNull() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val hintedPinLength by collectLastValue(underTest.hintedPinLength)
|
val hintedPinLength by collectLastValue(underTest.hintedPinLength)
|
||||||
authenticationInteractor.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Pin(1234567, autoConfirm = true)
|
AuthenticationMethodModel.Pin(1234567, autoConfirm = true)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ import com.android.systemui.scene.shared.model.SceneKey
|
|||||||
import com.android.systemui.scene.shared.model.SceneModel
|
import com.android.systemui.scene.shared.model.SceneModel
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
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.Test
|
import org.junit.Test
|
||||||
@@ -38,8 +37,8 @@ import org.junit.runners.JUnit4
|
|||||||
@RunWith(JUnit4::class)
|
@RunWith(JUnit4::class)
|
||||||
class LockscreenSceneInteractorTest : SysuiTestCase() {
|
class LockscreenSceneInteractorTest : SysuiTestCase() {
|
||||||
|
|
||||||
private val testScope = TestScope()
|
private val utils = SceneTestUtils(this)
|
||||||
private val utils = SceneTestUtils(this, testScope)
|
private val testScope = utils.testScope
|
||||||
private val sceneInteractor = utils.sceneInteractor()
|
private val sceneInteractor = utils.sceneInteractor()
|
||||||
private val authenticationInteractor =
|
private val authenticationInteractor =
|
||||||
utils.authenticationInteractor(
|
utils.authenticationInteractor(
|
||||||
@@ -74,7 +73,7 @@ class LockscreenSceneInteractorTest : SysuiTestCase() {
|
|||||||
val isSwipeToDismissEnabled by collectLastValue(underTest.isSwipeToDismissEnabled)
|
val isSwipeToDismissEnabled by collectLastValue(underTest.isSwipeToDismissEnabled)
|
||||||
|
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
|
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
|
||||||
|
|
||||||
assertThat(isSwipeToDismissEnabled).isTrue()
|
assertThat(isSwipeToDismissEnabled).isTrue()
|
||||||
}
|
}
|
||||||
@@ -85,7 +84,7 @@ class LockscreenSceneInteractorTest : SysuiTestCase() {
|
|||||||
val isSwipeToDismissEnabled by collectLastValue(underTest.isSwipeToDismissEnabled)
|
val isSwipeToDismissEnabled by collectLastValue(underTest.isSwipeToDismissEnabled)
|
||||||
|
|
||||||
authenticationInteractor.unlockDevice()
|
authenticationInteractor.unlockDevice()
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
|
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
|
||||||
|
|
||||||
assertThat(isSwipeToDismissEnabled).isFalse()
|
assertThat(isSwipeToDismissEnabled).isFalse()
|
||||||
}
|
}
|
||||||
@@ -95,7 +94,9 @@ class LockscreenSceneInteractorTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
|
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(1234)
|
||||||
|
)
|
||||||
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
|
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
|
||||||
|
|
||||||
underTest.dismissLockscreen()
|
underTest.dismissLockscreen()
|
||||||
@@ -108,7 +109,9 @@ class LockscreenSceneInteractorTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
|
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
|
||||||
authenticationInteractor.unlockDevice()
|
authenticationInteractor.unlockDevice()
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(1234)
|
||||||
|
)
|
||||||
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
|
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
|
||||||
|
|
||||||
underTest.dismissLockscreen()
|
underTest.dismissLockscreen()
|
||||||
@@ -121,7 +124,7 @@ class LockscreenSceneInteractorTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
|
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
|
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
|
||||||
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
|
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
|
||||||
|
|
||||||
underTest.dismissLockscreen()
|
underTest.dismissLockscreen()
|
||||||
@@ -182,7 +185,7 @@ class LockscreenSceneInteractorTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
|
val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
|
||||||
sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Lockscreen))
|
sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Lockscreen))
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
|
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
|
||||||
assertThat(isUnlocked).isFalse()
|
assertThat(isUnlocked).isFalse()
|
||||||
|
|
||||||
sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Gone))
|
sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Gone))
|
||||||
@@ -195,7 +198,9 @@ class LockscreenSceneInteractorTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
|
val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
|
||||||
sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Lockscreen))
|
sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Lockscreen))
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(1234)
|
||||||
|
)
|
||||||
assertThat(isUnlocked).isFalse()
|
assertThat(isUnlocked).isFalse()
|
||||||
|
|
||||||
sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Gone))
|
sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Gone))
|
||||||
@@ -210,7 +215,7 @@ class LockscreenSceneInteractorTest : SysuiTestCase() {
|
|||||||
runCurrent()
|
runCurrent()
|
||||||
sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Shade))
|
sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Shade))
|
||||||
runCurrent()
|
runCurrent()
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
|
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
|
||||||
runCurrent()
|
runCurrent()
|
||||||
assertThat(isUnlocked).isFalse()
|
assertThat(isUnlocked).isFalse()
|
||||||
|
|
||||||
@@ -219,30 +224,17 @@ class LockscreenSceneInteractorTest : SysuiTestCase() {
|
|||||||
assertThat(isUnlocked).isFalse()
|
assertThat(isUnlocked).isFalse()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
fun authMethodChangedToNone_onLockScreenScene_dismissesLockScreen() =
|
|
||||||
testScope.runTest {
|
|
||||||
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
|
|
||||||
sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Lockscreen))
|
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
|
|
||||||
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
|
|
||||||
|
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.None)
|
|
||||||
|
|
||||||
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun authMethodChangedToNone_notOnLockScreenScene_doesNotDismissLockScreen() =
|
fun authMethodChangedToNone_notOnLockScreenScene_doesNotDismissLockScreen() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
|
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
|
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
|
||||||
runCurrent()
|
runCurrent()
|
||||||
sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.QuickSettings))
|
sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.QuickSettings))
|
||||||
runCurrent()
|
runCurrent()
|
||||||
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.QuickSettings))
|
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.QuickSettings))
|
||||||
|
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.None)
|
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.None)
|
||||||
|
|
||||||
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.QuickSettings))
|
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.QuickSettings))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import com.android.systemui.scene.shared.model.SceneKey
|
|||||||
import com.android.systemui.scene.shared.model.SceneModel
|
import com.android.systemui.scene.shared.model.SceneModel
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
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.Test
|
import org.junit.Test
|
||||||
@@ -41,8 +40,8 @@ import org.junit.runners.JUnit4
|
|||||||
@RunWith(JUnit4::class)
|
@RunWith(JUnit4::class)
|
||||||
class LockscreenSceneViewModelTest : SysuiTestCase() {
|
class LockscreenSceneViewModelTest : SysuiTestCase() {
|
||||||
|
|
||||||
private val testScope = TestScope()
|
private val utils = SceneTestUtils(this)
|
||||||
private val utils = SceneTestUtils(this, testScope)
|
private val testScope = utils.testScope
|
||||||
private val sceneInteractor = utils.sceneInteractor()
|
private val sceneInteractor = utils.sceneInteractor()
|
||||||
private val authenticationInteractor =
|
private val authenticationInteractor =
|
||||||
utils.authenticationInteractor(
|
utils.authenticationInteractor(
|
||||||
@@ -73,7 +72,7 @@ class LockscreenSceneViewModelTest : SysuiTestCase() {
|
|||||||
fun lockButtonIcon_whenLocked() =
|
fun lockButtonIcon_whenLocked() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val lockButtonIcon by collectLastValue(underTest.lockButtonIcon)
|
val lockButtonIcon by collectLastValue(underTest.lockButtonIcon)
|
||||||
authenticationInteractor.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Password("password")
|
AuthenticationMethodModel.Password("password")
|
||||||
)
|
)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
@@ -86,7 +85,7 @@ class LockscreenSceneViewModelTest : SysuiTestCase() {
|
|||||||
fun lockButtonIcon_whenUnlocked() =
|
fun lockButtonIcon_whenUnlocked() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val lockButtonIcon by collectLastValue(underTest.lockButtonIcon)
|
val lockButtonIcon by collectLastValue(underTest.lockButtonIcon)
|
||||||
authenticationInteractor.setAuthenticationMethod(
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
AuthenticationMethodModel.Password("password")
|
AuthenticationMethodModel.Password("password")
|
||||||
)
|
)
|
||||||
authenticationInteractor.unlockDevice()
|
authenticationInteractor.unlockDevice()
|
||||||
@@ -99,7 +98,7 @@ class LockscreenSceneViewModelTest : SysuiTestCase() {
|
|||||||
fun upTransitionSceneKey_swipeToUnlockedEnabled_gone() =
|
fun upTransitionSceneKey_swipeToUnlockedEnabled_gone() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val upTransitionSceneKey by collectLastValue(underTest.upDestinationSceneKey)
|
val upTransitionSceneKey by collectLastValue(underTest.upDestinationSceneKey)
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
|
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
|
|
||||||
assertThat(upTransitionSceneKey).isEqualTo(SceneKey.Gone)
|
assertThat(upTransitionSceneKey).isEqualTo(SceneKey.Gone)
|
||||||
@@ -109,7 +108,9 @@ class LockscreenSceneViewModelTest : SysuiTestCase() {
|
|||||||
fun upTransitionSceneKey_swipeToUnlockedNotEnabled_bouncer() =
|
fun upTransitionSceneKey_swipeToUnlockedNotEnabled_bouncer() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val upTransitionSceneKey by collectLastValue(underTest.upDestinationSceneKey)
|
val upTransitionSceneKey by collectLastValue(underTest.upDestinationSceneKey)
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(1234)
|
||||||
|
)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
|
|
||||||
assertThat(upTransitionSceneKey).isEqualTo(SceneKey.Bouncer)
|
assertThat(upTransitionSceneKey).isEqualTo(SceneKey.Bouncer)
|
||||||
@@ -119,7 +120,9 @@ class LockscreenSceneViewModelTest : SysuiTestCase() {
|
|||||||
fun onLockButtonClicked_deviceLockedSecurely_switchesToBouncer() =
|
fun onLockButtonClicked_deviceLockedSecurely_switchesToBouncer() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
|
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(1234)
|
||||||
|
)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
runCurrent()
|
runCurrent()
|
||||||
|
|
||||||
@@ -132,7 +135,9 @@ class LockscreenSceneViewModelTest : SysuiTestCase() {
|
|||||||
fun onContentClicked_deviceUnlocked_switchesToGone() =
|
fun onContentClicked_deviceUnlocked_switchesToGone() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
|
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(1234)
|
||||||
|
)
|
||||||
authenticationInteractor.unlockDevice()
|
authenticationInteractor.unlockDevice()
|
||||||
runCurrent()
|
runCurrent()
|
||||||
|
|
||||||
@@ -145,7 +150,9 @@ class LockscreenSceneViewModelTest : SysuiTestCase() {
|
|||||||
fun onContentClicked_deviceLockedSecurely_switchesToBouncer() =
|
fun onContentClicked_deviceLockedSecurely_switchesToBouncer() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
|
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(1234)
|
||||||
|
)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
runCurrent()
|
runCurrent()
|
||||||
|
|
||||||
@@ -158,7 +165,9 @@ class LockscreenSceneViewModelTest : SysuiTestCase() {
|
|||||||
fun onLockButtonClicked_deviceUnlocked_switchesToGone() =
|
fun onLockButtonClicked_deviceUnlocked_switchesToGone() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
|
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(1234)
|
||||||
|
)
|
||||||
authenticationInteractor.unlockDevice()
|
authenticationInteractor.unlockDevice()
|
||||||
runCurrent()
|
runCurrent()
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ import com.android.systemui.scene.shared.model.SceneKey
|
|||||||
import com.android.systemui.scene.shared.model.SceneModel
|
import com.android.systemui.scene.shared.model.SceneModel
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
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.Test
|
import org.junit.Test
|
||||||
@@ -39,8 +38,8 @@ import org.junit.runners.JUnit4
|
|||||||
@RunWith(JUnit4::class)
|
@RunWith(JUnit4::class)
|
||||||
class QuickSettingsSceneViewModelTest : SysuiTestCase() {
|
class QuickSettingsSceneViewModelTest : SysuiTestCase() {
|
||||||
|
|
||||||
private val testScope = TestScope()
|
private val utils = SceneTestUtils(this)
|
||||||
private val utils = SceneTestUtils(this, testScope)
|
private val testScope = utils.testScope
|
||||||
private val sceneInteractor = utils.sceneInteractor()
|
private val sceneInteractor = utils.sceneInteractor()
|
||||||
private val authenticationInteractor =
|
private val authenticationInteractor =
|
||||||
utils.authenticationInteractor(
|
utils.authenticationInteractor(
|
||||||
@@ -70,7 +69,9 @@ class QuickSettingsSceneViewModelTest : SysuiTestCase() {
|
|||||||
fun onContentClicked_deviceUnlocked_switchesToGone() =
|
fun onContentClicked_deviceUnlocked_switchesToGone() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
|
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(1234)
|
||||||
|
)
|
||||||
authenticationInteractor.unlockDevice()
|
authenticationInteractor.unlockDevice()
|
||||||
runCurrent()
|
runCurrent()
|
||||||
|
|
||||||
@@ -83,7 +84,9 @@ class QuickSettingsSceneViewModelTest : SysuiTestCase() {
|
|||||||
fun onContentClicked_deviceLockedSecurely_switchesToBouncer() =
|
fun onContentClicked_deviceLockedSecurely_switchesToBouncer() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
|
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(1234)
|
||||||
|
)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
runCurrent()
|
runCurrent()
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ import com.android.systemui.scene.shared.model.SceneKey
|
|||||||
import com.android.systemui.scene.shared.model.SceneModel
|
import com.android.systemui.scene.shared.model.SceneModel
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
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.Test
|
import org.junit.Test
|
||||||
@@ -39,8 +38,8 @@ import org.junit.runners.JUnit4
|
|||||||
@RunWith(JUnit4::class)
|
@RunWith(JUnit4::class)
|
||||||
class ShadeSceneViewModelTest : SysuiTestCase() {
|
class ShadeSceneViewModelTest : SysuiTestCase() {
|
||||||
|
|
||||||
private val testScope = TestScope()
|
private val utils = SceneTestUtils(this)
|
||||||
private val utils = SceneTestUtils(this, testScope)
|
private val testScope = utils.testScope
|
||||||
private val sceneInteractor = utils.sceneInteractor()
|
private val sceneInteractor = utils.sceneInteractor()
|
||||||
private val authenticationInteractor =
|
private val authenticationInteractor =
|
||||||
utils.authenticationInteractor(
|
utils.authenticationInteractor(
|
||||||
@@ -71,7 +70,9 @@ class ShadeSceneViewModelTest : SysuiTestCase() {
|
|||||||
fun upTransitionSceneKey_deviceLocked_lockScreen() =
|
fun upTransitionSceneKey_deviceLocked_lockScreen() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val upTransitionSceneKey by collectLastValue(underTest.upDestinationSceneKey)
|
val upTransitionSceneKey by collectLastValue(underTest.upDestinationSceneKey)
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(1234)
|
||||||
|
)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
|
|
||||||
assertThat(upTransitionSceneKey).isEqualTo(SceneKey.Lockscreen)
|
assertThat(upTransitionSceneKey).isEqualTo(SceneKey.Lockscreen)
|
||||||
@@ -81,7 +82,9 @@ class ShadeSceneViewModelTest : SysuiTestCase() {
|
|||||||
fun upTransitionSceneKey_deviceUnlocked_gone() =
|
fun upTransitionSceneKey_deviceUnlocked_gone() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val upTransitionSceneKey by collectLastValue(underTest.upDestinationSceneKey)
|
val upTransitionSceneKey by collectLastValue(underTest.upDestinationSceneKey)
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(1234)
|
||||||
|
)
|
||||||
authenticationInteractor.unlockDevice()
|
authenticationInteractor.unlockDevice()
|
||||||
|
|
||||||
assertThat(upTransitionSceneKey).isEqualTo(SceneKey.Gone)
|
assertThat(upTransitionSceneKey).isEqualTo(SceneKey.Gone)
|
||||||
@@ -91,7 +94,9 @@ class ShadeSceneViewModelTest : SysuiTestCase() {
|
|||||||
fun onContentClicked_deviceUnlocked_switchesToGone() =
|
fun onContentClicked_deviceUnlocked_switchesToGone() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
|
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(1234)
|
||||||
|
)
|
||||||
authenticationInteractor.unlockDevice()
|
authenticationInteractor.unlockDevice()
|
||||||
runCurrent()
|
runCurrent()
|
||||||
|
|
||||||
@@ -104,7 +109,9 @@ class ShadeSceneViewModelTest : SysuiTestCase() {
|
|||||||
fun onContentClicked_deviceLockedSecurely_switchesToBouncer() =
|
fun onContentClicked_deviceLockedSecurely_switchesToBouncer() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
|
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
|
||||||
authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
|
utils.authenticationRepository.setAuthenticationMethod(
|
||||||
|
AuthenticationMethodModel.Pin(1234)
|
||||||
|
)
|
||||||
authenticationInteractor.lockDevice()
|
authenticationInteractor.lockDevice()
|
||||||
runCurrent()
|
runCurrent()
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 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.authentication.data.repository
|
||||||
|
|
||||||
|
import com.android.keyguard.KeyguardSecurityModel.SecurityMode
|
||||||
|
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
|
||||||
|
|
||||||
|
class FakeAuthenticationRepository(
|
||||||
|
private val delegate: AuthenticationRepository,
|
||||||
|
private val onSecurityModeChanged: (SecurityMode) -> Unit,
|
||||||
|
) : AuthenticationRepository by delegate {
|
||||||
|
|
||||||
|
private var authenticationMethod: AuthenticationMethodModel = DEFAULT_AUTHENTICATION_METHOD
|
||||||
|
|
||||||
|
override suspend fun getAuthenticationMethod(): AuthenticationMethodModel {
|
||||||
|
return authenticationMethod
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setAuthenticationMethod(authenticationMethod: AuthenticationMethodModel) {
|
||||||
|
this.authenticationMethod = authenticationMethod
|
||||||
|
onSecurityModeChanged(authenticationMethod.toSecurityMode())
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val DEFAULT_AUTHENTICATION_METHOD =
|
||||||
|
AuthenticationMethodModel.Pin(listOf(1, 2, 3, 4), autoConfirm = false)
|
||||||
|
|
||||||
|
fun AuthenticationMethodModel.toSecurityMode(): SecurityMode {
|
||||||
|
return when (this) {
|
||||||
|
is AuthenticationMethodModel.Pin -> SecurityMode.PIN
|
||||||
|
is AuthenticationMethodModel.Password -> SecurityMode.Password
|
||||||
|
is AuthenticationMethodModel.Pattern -> SecurityMode.Pattern
|
||||||
|
is AuthenticationMethodModel.Swipe,
|
||||||
|
is AuthenticationMethodModel.None -> SecurityMode.None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,9 +16,12 @@
|
|||||||
|
|
||||||
package com.android.systemui.scene
|
package com.android.systemui.scene
|
||||||
|
|
||||||
|
import com.android.keyguard.KeyguardSecurityModel.SecurityMode
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
import com.android.systemui.authentication.data.repository.AuthenticationRepository
|
import com.android.systemui.authentication.data.repository.AuthenticationRepository
|
||||||
import com.android.systemui.authentication.data.repository.AuthenticationRepositoryImpl
|
import com.android.systemui.authentication.data.repository.AuthenticationRepositoryImpl
|
||||||
|
import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository
|
||||||
|
import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository.Companion.toSecurityMode
|
||||||
import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
|
import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
|
||||||
import com.android.systemui.bouncer.data.repository.BouncerRepository
|
import com.android.systemui.bouncer.data.repository.BouncerRepository
|
||||||
import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
|
import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
|
||||||
@@ -28,8 +31,12 @@ import com.android.systemui.scene.data.repository.SceneContainerRepository
|
|||||||
import com.android.systemui.scene.domain.interactor.SceneInteractor
|
import com.android.systemui.scene.domain.interactor.SceneInteractor
|
||||||
import com.android.systemui.scene.shared.model.SceneContainerConfig
|
import com.android.systemui.scene.shared.model.SceneContainerConfig
|
||||||
import com.android.systemui.scene.shared.model.SceneKey
|
import com.android.systemui.scene.shared.model.SceneKey
|
||||||
|
import com.android.systemui.user.data.repository.FakeUserRepository
|
||||||
|
import com.android.systemui.util.mockito.mock
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.test.StandardTestDispatcher
|
||||||
|
import kotlinx.coroutines.test.TestDispatcher
|
||||||
import kotlinx.coroutines.test.TestScope
|
import kotlinx.coroutines.test.TestScope
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,9 +46,23 @@ import kotlinx.coroutines.test.TestScope
|
|||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
class SceneTestUtils(
|
class SceneTestUtils(
|
||||||
test: SysuiTestCase,
|
test: SysuiTestCase,
|
||||||
private val testScope: TestScope? = null,
|
|
||||||
) {
|
) {
|
||||||
|
val testDispatcher: TestDispatcher by lazy { StandardTestDispatcher() }
|
||||||
|
val testScope: TestScope by lazy { TestScope(testDispatcher) }
|
||||||
|
private var securityMode: SecurityMode =
|
||||||
|
FakeAuthenticationRepository.DEFAULT_AUTHENTICATION_METHOD.toSecurityMode()
|
||||||
|
val authenticationRepository: FakeAuthenticationRepository by lazy {
|
||||||
|
FakeAuthenticationRepository(
|
||||||
|
delegate =
|
||||||
|
AuthenticationRepositoryImpl(
|
||||||
|
getSecurityMode = { securityMode },
|
||||||
|
backgroundDispatcher = testDispatcher,
|
||||||
|
userRepository = FakeUserRepository(),
|
||||||
|
lockPatternUtils = mock(),
|
||||||
|
),
|
||||||
|
onSecurityModeChanged = { securityMode = it },
|
||||||
|
)
|
||||||
|
}
|
||||||
private val context = test.context
|
private val context = test.context
|
||||||
|
|
||||||
fun fakeSceneContainerRepository(
|
fun fakeSceneContainerRepository(
|
||||||
@@ -82,7 +103,7 @@ class SceneTestUtils(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun authenticationRepository(): AuthenticationRepository {
|
fun authenticationRepository(): AuthenticationRepository {
|
||||||
return AuthenticationRepositoryImpl()
|
return authenticationRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
fun authenticationInteractor(
|
fun authenticationInteractor(
|
||||||
@@ -94,17 +115,6 @@ class SceneTestUtils(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun applicationScope(): CoroutineScope {
|
|
||||||
return checkNotNull(testScope) {
|
|
||||||
"""
|
|
||||||
TestScope not initialized, please create a TestScope and inject it into
|
|
||||||
SceneTestUtils.
|
|
||||||
"""
|
|
||||||
.trimIndent()
|
|
||||||
}
|
|
||||||
.backgroundScope
|
|
||||||
}
|
|
||||||
|
|
||||||
fun bouncerInteractor(
|
fun bouncerInteractor(
|
||||||
authenticationInteractor: AuthenticationInteractor,
|
authenticationInteractor: AuthenticationInteractor,
|
||||||
sceneInteractor: SceneInteractor,
|
sceneInteractor: SceneInteractor,
|
||||||
@@ -154,6 +164,10 @@ class SceneTestUtils(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun applicationScope(): CoroutineScope {
|
||||||
|
return testScope.backgroundScope
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val CONTAINER_1 = "container1"
|
const val CONTAINER_1 = "container1"
|
||||||
const val CONTAINER_2 = "container2"
|
const val CONTAINER_2 = "container2"
|
||||||
|
|||||||
Reference in New Issue
Block a user