Merge "Transitions - Add ALTERNATE_BOUNCER support" into tm-qpr-dev

This commit is contained in:
Beverly Tai
2023-02-15 15:12:29 +00:00
committed by Android (Google) Code Review
38 changed files with 698 additions and 176 deletions

View File

@@ -933,7 +933,7 @@ class KeyguardUnlockAnimationController @Inject constructor(
} }
// The smartspace is not visible if the bouncer is showing, so don't shared element it. // The smartspace is not visible if the bouncer is showing, so don't shared element it.
if (keyguardStateController.isBouncerShowing) { if (keyguardStateController.isPrimaryBouncerShowing) {
return false return false
} }

View File

@@ -1148,12 +1148,12 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
private final KeyguardStateController.Callback mKeyguardStateControllerCallback = private final KeyguardStateController.Callback mKeyguardStateControllerCallback =
new KeyguardStateController.Callback() { new KeyguardStateController.Callback() {
@Override @Override
public void onBouncerShowingChanged() { public void onPrimaryBouncerShowingChanged() {
synchronized (KeyguardViewMediator.this) { synchronized (KeyguardViewMediator.this) {
if (mKeyguardStateController.isBouncerShowing()) { if (mKeyguardStateController.isPrimaryBouncerShowing()) {
mPendingPinLock = false; mPendingPinLock = false;
} }
adjustStatusBarLocked(mKeyguardStateController.isBouncerShowing(), false); adjustStatusBarLocked(mKeyguardStateController.isPrimaryBouncerShowing(), false);
} }
} }
}; };

View File

@@ -68,8 +68,8 @@ interface KeyguardBouncerRepository {
val resourceUpdateRequests: StateFlow<Boolean> val resourceUpdateRequests: StateFlow<Boolean>
val bouncerPromptReason: Int val bouncerPromptReason: Int
val bouncerErrorMessage: CharSequence? val bouncerErrorMessage: CharSequence?
val isAlternateBouncerVisible: StateFlow<Boolean> val alternateBouncerVisible: StateFlow<Boolean>
val isAlternateBouncerUIAvailable: StateFlow<Boolean> val alternateBouncerUIAvailable: StateFlow<Boolean>
var lastAlternateBouncerVisibleTime: Long var lastAlternateBouncerVisibleTime: Long
fun setPrimaryScrimmed(isScrimmed: Boolean) fun setPrimaryScrimmed(isScrimmed: Boolean)
@@ -159,12 +159,12 @@ constructor(
get() = viewMediatorCallback.consumeCustomMessage() get() = viewMediatorCallback.consumeCustomMessage()
/** Values associated with the AlternateBouncer */ /** Values associated with the AlternateBouncer */
private val _isAlternateBouncerVisible = MutableStateFlow(false) private val _alternateBouncerVisible = MutableStateFlow(false)
override val isAlternateBouncerVisible = _isAlternateBouncerVisible.asStateFlow() override val alternateBouncerVisible = _alternateBouncerVisible.asStateFlow()
override var lastAlternateBouncerVisibleTime: Long = NOT_VISIBLE override var lastAlternateBouncerVisibleTime: Long = NOT_VISIBLE
private val _isAlternateBouncerUIAvailable = MutableStateFlow(false) private val _alternateBouncerUIAvailable = MutableStateFlow(false)
override val isAlternateBouncerUIAvailable: StateFlow<Boolean> = override val alternateBouncerUIAvailable: StateFlow<Boolean> =
_isAlternateBouncerUIAvailable.asStateFlow() _alternateBouncerUIAvailable.asStateFlow()
init { init {
setUpLogging() setUpLogging()
@@ -179,16 +179,16 @@ constructor(
} }
override fun setAlternateVisible(isVisible: Boolean) { override fun setAlternateVisible(isVisible: Boolean) {
if (isVisible && !_isAlternateBouncerVisible.value) { if (isVisible && !_alternateBouncerVisible.value) {
lastAlternateBouncerVisibleTime = clock.uptimeMillis() lastAlternateBouncerVisibleTime = clock.uptimeMillis()
} else if (!isVisible) { } else if (!isVisible) {
lastAlternateBouncerVisibleTime = NOT_VISIBLE lastAlternateBouncerVisibleTime = NOT_VISIBLE
} }
_isAlternateBouncerVisible.value = isVisible _alternateBouncerVisible.value = isVisible
} }
override fun setAlternateBouncerUIAvailable(isAvailable: Boolean) { override fun setAlternateBouncerUIAvailable(isAvailable: Boolean) {
_isAlternateBouncerUIAvailable.value = isAvailable _alternateBouncerUIAvailable.value = isAvailable
} }
override fun setPrimaryShow(keyguardBouncerModel: KeyguardBouncerModel?) { override fun setPrimaryShow(keyguardBouncerModel: KeyguardBouncerModel?) {
@@ -290,7 +290,7 @@ constructor(
resourceUpdateRequests resourceUpdateRequests
.logDiffsForTable(buffer, "", "ResourceUpdateRequests", false) .logDiffsForTable(buffer, "", "ResourceUpdateRequests", false)
.launchIn(applicationScope) .launchIn(applicationScope)
isAlternateBouncerUIAvailable alternateBouncerUIAvailable
.logDiffsForTable(buffer, "", "IsAlternateBouncerUIAvailable", false) .logDiffsForTable(buffer, "", "IsAlternateBouncerUIAvailable", false)
.launchIn(applicationScope) .launchIn(applicationScope)
} }

View File

@@ -86,9 +86,6 @@ interface KeyguardRepository {
/** Observable for the signal that keyguard is about to go away. */ /** Observable for the signal that keyguard is about to go away. */
val isKeyguardGoingAway: Flow<Boolean> val isKeyguardGoingAway: Flow<Boolean>
/** Observable for whether the bouncer is showing. */
val isBouncerShowing: Flow<Boolean>
/** Is the always-on display available to be used? */ /** Is the always-on display available to be used? */
val isAodAvailable: Flow<Boolean> val isAodAvailable: Flow<Boolean>
@@ -304,29 +301,6 @@ constructor(
awaitClose { keyguardStateController.removeCallback(callback) } awaitClose { keyguardStateController.removeCallback(callback) }
} }
override val isBouncerShowing: Flow<Boolean> = conflatedCallbackFlow {
val callback =
object : KeyguardStateController.Callback {
override fun onBouncerShowingChanged() {
trySendWithFailureLogging(
keyguardStateController.isBouncerShowing,
TAG,
"updated isBouncerShowing"
)
}
}
keyguardStateController.addCallback(callback)
// Adding the callback does not send an initial update.
trySendWithFailureLogging(
keyguardStateController.isBouncerShowing,
TAG,
"initial isBouncerShowing"
)
awaitClose { keyguardStateController.removeCallback(callback) }
}
override val isDozing: Flow<Boolean> = override val isDozing: Flow<Boolean> =
conflatedCallbackFlow { conflatedCallbackFlow {
val callback = val callback =

View File

@@ -44,7 +44,7 @@ constructor(
var legacyAlternateBouncer: LegacyAlternateBouncer? = null var legacyAlternateBouncer: LegacyAlternateBouncer? = null
var legacyAlternateBouncerVisibleTime: Long = NOT_VISIBLE var legacyAlternateBouncerVisibleTime: Long = NOT_VISIBLE
val isVisible: Flow<Boolean> = bouncerRepository.isAlternateBouncerVisible val isVisible: Flow<Boolean> = bouncerRepository.alternateBouncerVisible
/** /**
* Sets the correct bouncer states to show the alternate bouncer if it can show. * Sets the correct bouncer states to show the alternate bouncer if it can show.
@@ -86,7 +86,7 @@ constructor(
fun isVisibleState(): Boolean { fun isVisibleState(): Boolean {
return if (isModernAlternateBouncerEnabled) { return if (isModernAlternateBouncerEnabled) {
bouncerRepository.isAlternateBouncerVisible.value bouncerRepository.alternateBouncerVisible.value
} else { } else {
legacyAlternateBouncer?.isShowingAlternateBouncer ?: false legacyAlternateBouncer?.isShowingAlternateBouncer ?: false
} }
@@ -98,7 +98,7 @@ constructor(
fun canShowAlternateBouncerForFingerprint(): Boolean { fun canShowAlternateBouncerForFingerprint(): Boolean {
return if (isModernAlternateBouncerEnabled) { return if (isModernAlternateBouncerEnabled) {
bouncerRepository.isAlternateBouncerUIAvailable.value && bouncerRepository.alternateBouncerUIAvailable.value &&
biometricSettingsRepository.isFingerprintEnrolled.value && biometricSettingsRepository.isFingerprintEnrolled.value &&
biometricSettingsRepository.isStrongBiometricAllowed.value && biometricSettingsRepository.isStrongBiometricAllowed.value &&
biometricSettingsRepository.isFingerprintEnabledByDevicePolicy.value && biometricSettingsRepository.isFingerprintEnabledByDevicePolicy.value &&

View File

@@ -0,0 +1,158 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package com.android.systemui.keyguard.domain.interactor
import android.animation.ValueAnimator
import com.android.systemui.animation.Interpolators
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionInfo
import com.android.systemui.keyguard.shared.model.WakefulnessState
import com.android.systemui.util.kotlin.sample
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
@SysUISingleton
class FromAlternateBouncerTransitionInteractor
@Inject
constructor(
@Application private val scope: CoroutineScope,
private val keyguardInteractor: KeyguardInteractor,
private val keyguardTransitionRepository: KeyguardTransitionRepository,
private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
) : TransitionInteractor(FromAlternateBouncerTransitionInteractor::class.simpleName!!) {
override fun start() {
listenForAlternateBouncerToGone()
listenForAlternateBouncerToLockscreenAodOrDozing()
listenForAlternateBouncerToPrimaryBouncer()
}
private fun listenForAlternateBouncerToLockscreenAodOrDozing() {
scope.launch {
keyguardInteractor.alternateBouncerShowing
// Add a slight delay, as alternateBouncer and primaryBouncer showing event changes
// will arrive with a small gap in time. This prevents a transition to LOCKSCREEN
// happening prematurely.
.onEach { delay(50) }
.sample(
combine(
keyguardInteractor.primaryBouncerShowing,
keyguardTransitionInteractor.startedKeyguardTransitionStep,
keyguardInteractor.wakefulnessModel,
keyguardInteractor.isAodAvailable,
::toQuad
),
::toQuint
)
.collect {
(
isAlternateBouncerShowing,
isPrimaryBouncerShowing,
lastStartedTransitionStep,
wakefulnessState,
isAodAvailable
) ->
if (
!isAlternateBouncerShowing &&
!isPrimaryBouncerShowing &&
lastStartedTransitionStep.to == KeyguardState.ALTERNATE_BOUNCER
) {
val to =
if (
wakefulnessState.state == WakefulnessState.STARTING_TO_SLEEP ||
wakefulnessState.state == WakefulnessState.ASLEEP
) {
if (isAodAvailable) {
KeyguardState.AOD
} else {
KeyguardState.DOZING
}
} else {
KeyguardState.LOCKSCREEN
}
keyguardTransitionRepository.startTransition(
TransitionInfo(
ownerName = name,
from = KeyguardState.ALTERNATE_BOUNCER,
to = to,
animator = getAnimator(),
)
)
}
}
}
}
private fun listenForAlternateBouncerToGone() {
scope.launch {
keyguardInteractor.isKeyguardGoingAway
.sample(keyguardTransitionInteractor.finishedKeyguardState, ::Pair)
.collect { (isKeyguardGoingAway, keyguardState) ->
if (isKeyguardGoingAway && keyguardState == KeyguardState.ALTERNATE_BOUNCER) {
keyguardTransitionRepository.startTransition(
TransitionInfo(
ownerName = name,
from = KeyguardState.ALTERNATE_BOUNCER,
to = KeyguardState.GONE,
animator = getAnimator(),
)
)
}
}
}
}
private fun listenForAlternateBouncerToPrimaryBouncer() {
scope.launch {
keyguardInteractor.primaryBouncerShowing
.sample(keyguardTransitionInteractor.startedKeyguardTransitionStep, ::Pair)
.collect { (isPrimaryBouncerShowing, startedKeyguardState) ->
if (
isPrimaryBouncerShowing &&
startedKeyguardState.to == KeyguardState.ALTERNATE_BOUNCER
) {
keyguardTransitionRepository.startTransition(
TransitionInfo(
ownerName = name,
from = KeyguardState.ALTERNATE_BOUNCER,
to = KeyguardState.PRIMARY_BOUNCER,
animator = getAnimator(),
)
)
}
}
}
}
private fun getAnimator(): ValueAnimator {
return ValueAnimator().apply {
interpolator = Interpolators.LINEAR
duration = TRANSITION_DURATION_MS
}
}
companion object {
private const val TRANSITION_DURATION_MS = 300L
}
}

View File

@@ -33,7 +33,6 @@ import javax.inject.Inject
import kotlin.time.Duration import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@@ -53,9 +52,10 @@ constructor(
listenForLockscreenToOccluded() listenForLockscreenToOccluded()
listenForLockscreenToCamera() listenForLockscreenToCamera()
listenForLockscreenToAodOrDozing() listenForLockscreenToAodOrDozing()
listenForLockscreenToBouncer() listenForLockscreenToPrimaryBouncer()
listenForLockscreenToDreaming() listenForLockscreenToDreaming()
listenForLockscreenToBouncerDragging() listenForLockscreenToPrimaryBouncerDragging()
listenForLockscreenToAlternateBouncer()
} }
private fun listenForLockscreenToDreaming() { private fun listenForLockscreenToDreaming() {
@@ -78,9 +78,9 @@ constructor(
} }
} }
private fun listenForLockscreenToBouncer() { private fun listenForLockscreenToPrimaryBouncer() {
scope.launch { scope.launch {
keyguardInteractor.isBouncerShowing keyguardInteractor.primaryBouncerShowing
.sample(keyguardTransitionInteractor.startedKeyguardTransitionStep, ::Pair) .sample(keyguardTransitionInteractor.startedKeyguardTransitionStep, ::Pair)
.collect { pair -> .collect { pair ->
val (isBouncerShowing, lastStartedTransitionStep) = pair val (isBouncerShowing, lastStartedTransitionStep) = pair
@@ -91,7 +91,30 @@ constructor(
TransitionInfo( TransitionInfo(
ownerName = name, ownerName = name,
from = KeyguardState.LOCKSCREEN, from = KeyguardState.LOCKSCREEN,
to = KeyguardState.BOUNCER, to = KeyguardState.PRIMARY_BOUNCER,
animator = getAnimator(),
)
)
}
}
}
}
private fun listenForLockscreenToAlternateBouncer() {
scope.launch {
keyguardInteractor.alternateBouncerShowing
.sample(keyguardTransitionInteractor.startedKeyguardTransitionStep, ::Pair)
.collect { pair ->
val (isAlternateBouncerShowing, lastStartedTransitionStep) = pair
if (
isAlternateBouncerShowing &&
lastStartedTransitionStep.to == KeyguardState.LOCKSCREEN
) {
keyguardTransitionRepository.startTransition(
TransitionInfo(
ownerName = name,
from = KeyguardState.LOCKSCREEN,
to = KeyguardState.ALTERNATE_BOUNCER,
animator = getAnimator(), animator = getAnimator(),
) )
) )
@@ -101,7 +124,7 @@ constructor(
} }
/* Starts transitions when manually dragging up the bouncer from the lockscreen. */ /* Starts transitions when manually dragging up the bouncer from the lockscreen. */
private fun listenForLockscreenToBouncerDragging() { private fun listenForLockscreenToPrimaryBouncerDragging() {
var transitionId: UUID? = null var transitionId: UUID? = null
scope.launch { scope.launch {
shadeRepository.shadeModel shadeRepository.shadeModel
@@ -144,7 +167,7 @@ constructor(
keyguardTransitionRepository.startTransition( keyguardTransitionRepository.startTransition(
TransitionInfo( TransitionInfo(
ownerName = name, ownerName = name,
from = KeyguardState.BOUNCER, from = KeyguardState.PRIMARY_BOUNCER,
to = KeyguardState.LOCKSCREEN, to = KeyguardState.LOCKSCREEN,
animator = getAnimator(0.milliseconds) animator = getAnimator(0.milliseconds)
) )
@@ -163,7 +186,7 @@ constructor(
TransitionInfo( TransitionInfo(
ownerName = name, ownerName = name,
from = KeyguardState.LOCKSCREEN, from = KeyguardState.LOCKSCREEN,
to = KeyguardState.BOUNCER, to = KeyguardState.PRIMARY_BOUNCER,
animator = null, animator = null,
) )
) )

View File

@@ -24,62 +24,63 @@ import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepositor
import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionInfo import com.android.systemui.keyguard.shared.model.TransitionInfo
import com.android.systemui.keyguard.shared.model.WakefulnessState import com.android.systemui.keyguard.shared.model.WakefulnessState
import com.android.systemui.shade.data.repository.ShadeRepository
import com.android.systemui.util.kotlin.sample import com.android.systemui.util.kotlin.sample
import java.util.UUID
import javax.inject.Inject import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@SysUISingleton @SysUISingleton
class FromBouncerTransitionInteractor class FromPrimaryBouncerTransitionInteractor
@Inject @Inject
constructor( constructor(
@Application private val scope: CoroutineScope, @Application private val scope: CoroutineScope,
private val keyguardInteractor: KeyguardInteractor, private val keyguardInteractor: KeyguardInteractor,
private val shadeRepository: ShadeRepository,
private val keyguardTransitionRepository: KeyguardTransitionRepository, private val keyguardTransitionRepository: KeyguardTransitionRepository,
private val keyguardTransitionInteractor: KeyguardTransitionInteractor private val keyguardTransitionInteractor: KeyguardTransitionInteractor
) : TransitionInteractor(FromBouncerTransitionInteractor::class.simpleName!!) { ) : TransitionInteractor(FromPrimaryBouncerTransitionInteractor::class.simpleName!!) {
private var transitionId: UUID? = null
override fun start() { override fun start() {
listenForBouncerToGone() listenForPrimaryBouncerToGone()
listenForBouncerToLockscreenOrAod() listenForPrimaryBouncerToLockscreenAodOrDozing()
} }
private fun listenForBouncerToLockscreenOrAod() { private fun listenForPrimaryBouncerToLockscreenAodOrDozing() {
scope.launch { scope.launch {
keyguardInteractor.isBouncerShowing keyguardInteractor.primaryBouncerShowing
.sample( .sample(
combine( combine(
keyguardInteractor.wakefulnessModel, keyguardInteractor.wakefulnessModel,
keyguardTransitionInteractor.startedKeyguardTransitionStep, keyguardTransitionInteractor.startedKeyguardTransitionStep,
::Pair keyguardInteractor.isAodAvailable,
::toTriple
), ),
::toTriple ::toQuad
) )
.collect { triple -> .collect {
val (isBouncerShowing, wakefulnessState, lastStartedTransitionStep) = triple (isBouncerShowing, wakefulnessState, lastStartedTransitionStep, isAodAvailable)
->
if ( if (
!isBouncerShowing && lastStartedTransitionStep.to == KeyguardState.BOUNCER !isBouncerShowing &&
lastStartedTransitionStep.to == KeyguardState.PRIMARY_BOUNCER
) { ) {
val to = val to =
if ( if (
wakefulnessState.state == WakefulnessState.STARTING_TO_SLEEP || wakefulnessState.state == WakefulnessState.STARTING_TO_SLEEP ||
wakefulnessState.state == WakefulnessState.ASLEEP wakefulnessState.state == WakefulnessState.ASLEEP
) { ) {
KeyguardState.AOD if (isAodAvailable) {
KeyguardState.AOD
} else {
KeyguardState.DOZING
}
} else { } else {
KeyguardState.LOCKSCREEN KeyguardState.LOCKSCREEN
} }
keyguardTransitionRepository.startTransition( keyguardTransitionRepository.startTransition(
TransitionInfo( TransitionInfo(
ownerName = name, ownerName = name,
from = KeyguardState.BOUNCER, from = KeyguardState.PRIMARY_BOUNCER,
to = to, to = to,
animator = getAnimator(), animator = getAnimator(),
) )
@@ -89,17 +90,17 @@ constructor(
} }
} }
private fun listenForBouncerToGone() { private fun listenForPrimaryBouncerToGone() {
scope.launch { scope.launch {
keyguardInteractor.isKeyguardGoingAway keyguardInteractor.isKeyguardGoingAway
.sample(keyguardTransitionInteractor.finishedKeyguardState, { a, b -> Pair(a, b) }) .sample(keyguardTransitionInteractor.finishedKeyguardState) { a, b -> Pair(a, b) }
.collect { pair -> .collect { pair ->
val (isKeyguardGoingAway, keyguardState) = pair val (isKeyguardGoingAway, keyguardState) = pair
if (isKeyguardGoingAway && keyguardState == KeyguardState.BOUNCER) { if (isKeyguardGoingAway && keyguardState == KeyguardState.PRIMARY_BOUNCER) {
keyguardTransitionRepository.startTransition( keyguardTransitionRepository.startTransition(
TransitionInfo( TransitionInfo(
ownerName = name, ownerName = name,
from = KeyguardState.BOUNCER, from = KeyguardState.PRIMARY_BOUNCER,
to = KeyguardState.GONE, to = KeyguardState.GONE,
animator = getAnimator(), animator = getAnimator(),
) )

View File

@@ -24,6 +24,7 @@ import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCall
import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.data.repository.KeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.KeyguardRepository import com.android.systemui.keyguard.data.repository.KeyguardRepository
import com.android.systemui.keyguard.shared.model.BiometricUnlockModel import com.android.systemui.keyguard.shared.model.BiometricUnlockModel
import com.android.systemui.keyguard.shared.model.CameraLaunchSourceModel import com.android.systemui.keyguard.shared.model.CameraLaunchSourceModel
@@ -56,6 +57,7 @@ constructor(
private val repository: KeyguardRepository, private val repository: KeyguardRepository,
private val commandQueue: CommandQueue, private val commandQueue: CommandQueue,
featureFlags: FeatureFlags, featureFlags: FeatureFlags,
bouncerRepository: KeyguardBouncerRepository,
) { ) {
/** /**
* The amount of doze the system is in, where `1.0` is fully dozing and `0.0` is not dozing at * The amount of doze the system is in, where `1.0` is fully dozing and `0.0` is not dozing at
@@ -121,8 +123,10 @@ constructor(
val isKeyguardOccluded: Flow<Boolean> = repository.isKeyguardOccluded val isKeyguardOccluded: Flow<Boolean> = repository.isKeyguardOccluded
/** Whether the keyguard is going away. */ /** Whether the keyguard is going away. */
val isKeyguardGoingAway: Flow<Boolean> = repository.isKeyguardGoingAway val isKeyguardGoingAway: Flow<Boolean> = repository.isKeyguardGoingAway
/** Whether the bouncer is showing or not. */ /** Whether the primary bouncer is showing or not. */
val isBouncerShowing: Flow<Boolean> = repository.isBouncerShowing val primaryBouncerShowing: Flow<Boolean> = bouncerRepository.primaryBouncerVisible
/** Whether the alternate bouncer is showing or not. */
val alternateBouncerShowing: Flow<Boolean> = bouncerRepository.alternateBouncerVisible
/** The device wake/sleep state */ /** The device wake/sleep state */
val wakefulnessModel: Flow<WakefulnessModel> = repository.wakefulness val wakefulnessModel: Flow<WakefulnessModel> = repository.wakefulness
/** Observable for the [StatusBarState] */ /** Observable for the [StatusBarState] */
@@ -142,12 +146,12 @@ constructor(
if (featureFlags.isEnabled(Flags.FACE_AUTH_REFACTOR)) { if (featureFlags.isEnabled(Flags.FACE_AUTH_REFACTOR)) {
combine( combine(
isKeyguardVisible, isKeyguardVisible,
repository.isBouncerShowing, bouncerRepository.primaryBouncerVisible,
onCameraLaunchDetected, onCameraLaunchDetected,
) { isKeyguardVisible, isBouncerShowing, cameraLaunchEvent -> ) { isKeyguardVisible, isPrimaryBouncerShowing, cameraLaunchEvent ->
when { when {
isKeyguardVisible -> false isKeyguardVisible -> false
isBouncerShowing -> false isPrimaryBouncerShowing -> false
else -> cameraLaunchEvent == CameraLaunchSourceModel.POWER_DOUBLE_TAP else -> cameraLaunchEvent == CameraLaunchSourceModel.POWER_DOUBLE_TAP
} }
} }

View File

@@ -22,7 +22,6 @@ import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.plugins.log.LogLevel.VERBOSE import com.android.systemui.plugins.log.LogLevel.VERBOSE
import javax.inject.Inject import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
private val TAG = KeyguardTransitionAuditLogger::class.simpleName!! private val TAG = KeyguardTransitionAuditLogger::class.simpleName!!
@@ -46,8 +45,14 @@ constructor(
} }
scope.launch { scope.launch {
keyguardInteractor.isBouncerShowing.collect { keyguardInteractor.primaryBouncerShowing.collect {
logger.log(TAG, VERBOSE, "Bouncer showing", it) logger.log(TAG, VERBOSE, "Primary bouncer showing", it)
}
}
scope.launch {
keyguardInteractor.alternateBouncerShowing.collect {
logger.log(TAG, VERBOSE, "Alternate bouncer showing", it)
} }
} }

View File

@@ -37,13 +37,14 @@ constructor(
// exhaustive // exhaustive
val ret = val ret =
when (it) { when (it) {
is FromBouncerTransitionInteractor -> Log.d(TAG, "Started $it") is FromPrimaryBouncerTransitionInteractor -> Log.d(TAG, "Started $it")
is FromAodTransitionInteractor -> Log.d(TAG, "Started $it") is FromAodTransitionInteractor -> Log.d(TAG, "Started $it")
is FromGoneTransitionInteractor -> Log.d(TAG, "Started $it") is FromGoneTransitionInteractor -> Log.d(TAG, "Started $it")
is FromLockscreenTransitionInteractor -> Log.d(TAG, "Started $it") is FromLockscreenTransitionInteractor -> Log.d(TAG, "Started $it")
is FromDreamingTransitionInteractor -> Log.d(TAG, "Started $it") is FromDreamingTransitionInteractor -> Log.d(TAG, "Started $it")
is FromOccludedTransitionInteractor -> Log.d(TAG, "Started $it") is FromOccludedTransitionInteractor -> Log.d(TAG, "Started $it")
is FromDozingTransitionInteractor -> Log.d(TAG, "Started $it") is FromDozingTransitionInteractor -> Log.d(TAG, "Started $it")
is FromAlternateBouncerTransitionInteractor -> Log.d(TAG, "Started $it")
} }
it.start() it.start()
} }

View File

@@ -21,13 +21,12 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.KeyguardState.AOD import com.android.systemui.keyguard.shared.model.KeyguardState.AOD
import com.android.systemui.keyguard.shared.model.KeyguardState.BOUNCER
import com.android.systemui.keyguard.shared.model.KeyguardState.DREAMING import com.android.systemui.keyguard.shared.model.KeyguardState.DREAMING
import com.android.systemui.keyguard.shared.model.KeyguardState.GONE import com.android.systemui.keyguard.shared.model.KeyguardState.GONE
import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
import com.android.systemui.keyguard.shared.model.KeyguardState.OCCLUDED import com.android.systemui.keyguard.shared.model.KeyguardState.OCCLUDED
import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionState.STARTED
import com.android.systemui.keyguard.shared.model.TransitionStep import com.android.systemui.keyguard.shared.model.TransitionStep
import javax.inject.Inject import javax.inject.Inject
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
@@ -63,9 +62,9 @@ constructor(
/** LOCKSCREEN->AOD transition information. */ /** LOCKSCREEN->AOD transition information. */
val lockscreenToAodTransition: Flow<TransitionStep> = repository.transition(LOCKSCREEN, AOD) val lockscreenToAodTransition: Flow<TransitionStep> = repository.transition(LOCKSCREEN, AOD)
/** LOCKSCREEN->BOUNCER transition information. */ /** LOCKSCREEN->PRIMARY_BOUNCER transition information. */
val lockscreenToBouncerTransition: Flow<TransitionStep> = val mLockscreenToPrimaryBouncerTransition: Flow<TransitionStep> =
repository.transition(LOCKSCREEN, BOUNCER) repository.transition(LOCKSCREEN, PRIMARY_BOUNCER)
/** LOCKSCREEN->DREAMING transition information. */ /** LOCKSCREEN->DREAMING transition information. */
val lockscreenToDreamingTransition: Flow<TransitionStep> = val lockscreenToDreamingTransition: Flow<TransitionStep> =

View File

@@ -86,7 +86,8 @@ constructor(
KeyguardState.DOZING -> false KeyguardState.DOZING -> false
KeyguardState.AOD -> false KeyguardState.AOD -> false
KeyguardState.DREAMING -> true KeyguardState.DREAMING -> true
KeyguardState.BOUNCER -> true KeyguardState.ALTERNATE_BOUNCER -> true
KeyguardState.PRIMARY_BOUNCER -> true
KeyguardState.LOCKSCREEN -> true KeyguardState.LOCKSCREEN -> true
KeyguardState.GONE -> true KeyguardState.GONE -> true
KeyguardState.OCCLUDED -> true KeyguardState.OCCLUDED -> true

View File

@@ -164,7 +164,7 @@ constructor(
} else { } else {
DejankUtils.postAfterTraversal(showRunnable) DejankUtils.postAfterTraversal(showRunnable)
} }
keyguardStateController.notifyBouncerShowing(true) keyguardStateController.notifyPrimaryBouncerShowing(true)
primaryBouncerCallbackInteractor.dispatchStartingToShow() primaryBouncerCallbackInteractor.dispatchStartingToShow()
Trace.endSection() Trace.endSection()
} }
@@ -181,7 +181,7 @@ constructor(
} }
falsingCollector.onBouncerHidden() falsingCollector.onBouncerHidden()
keyguardStateController.notifyBouncerShowing(false /* showing */) keyguardStateController.notifyPrimaryBouncerShowing(false /* showing */)
cancelShowRunnable() cancelShowRunnable()
repository.setPrimaryShowingSoon(false) repository.setPrimaryShowingSoon(false)
repository.setPrimaryVisible(false) repository.setPrimaryVisible(false)

View File

@@ -32,7 +32,9 @@ abstract class StartKeyguardTransitionModule {
@Binds @Binds
@IntoSet @IntoSet
abstract fun fromBouncer(impl: FromBouncerTransitionInteractor): TransitionInteractor abstract fun fromPrimaryBouncer(
impl: FromPrimaryBouncerTransitionInteractor
): TransitionInteractor
@Binds @Binds
@IntoSet @IntoSet
@@ -53,4 +55,10 @@ abstract class StartKeyguardTransitionModule {
@Binds @Binds
@IntoSet @IntoSet
abstract fun fromDozing(impl: FromDozingTransitionInteractor): TransitionInteractor abstract fun fromDozing(impl: FromDozingTransitionInteractor): TransitionInteractor
@Binds
@IntoSet
abstract fun fromAlternateBouncer(
impl: FromAlternateBouncerTransitionInteractor
): TransitionInteractor
} }

View File

@@ -30,7 +30,26 @@ sealed class TransitionInteractor(val name: String) {
abstract fun start() abstract fun start()
fun <A, B, C> toTriple(a: A, b: B, c: C) = Triple(a, b, c)
fun <A, B, C> toTriple(a: A, bc: Pair<B, C>) = Triple(a, bc.first, bc.second) fun <A, B, C> toTriple(a: A, bc: Pair<B, C>) = Triple(a, bc.first, bc.second)
fun <A, B, C> toTriple(ab: Pair<A, B>, c: C) = Triple(ab.first, ab.second, c) fun <A, B, C> toTriple(ab: Pair<A, B>, c: C) = Triple(ab.first, ab.second, c)
fun <A, B, C, D> toQuad(a: A, b: B, c: C, d: D) = Quad(a, b, c, d)
fun <A, B, C, D> toQuad(a: A, bcd: Triple<B, C, D>) = Quad(a, bcd.first, bcd.second, bcd.third)
fun <A, B, C, D, E> toQuint(a: A, bcde: Quad<B, C, D, E>) =
Quint(a, bcde.first, bcde.second, bcde.third, bcde.fourth)
} }
data class Quad<A, B, C, D>(val first: A, val second: B, val third: C, val fourth: D)
data class Quint<A, B, C, D, E>(
val first: A,
val second: B,
val third: C,
val fourth: D,
val fifth: E
)

View File

@@ -42,10 +42,15 @@ enum class KeyguardState {
*/ */
AOD, AOD,
/* /*
* The security screen prompt UI, containing PIN, Password, Pattern, and all FPS * The security screen prompt containing UI to prompt the user to use a biometric credential
* (Fingerprint Sensor) variations, for the user to verify their credentials * (ie: fingerprint). When supported, this may show before showing the primary bouncer.
*/ */
BOUNCER, ALTERNATE_BOUNCER,
/*
* The security screen prompt UI, containing PIN, Password, Pattern for the user to verify their
* credentials.
*/
PRIMARY_BOUNCER,
/* /*
* Device is actively displaying keyguard UI and is not in low-power mode. Device may be * Device is actively displaying keyguard UI and is not in low-power mode. Device may be
* unlocked if SWIPE security method is used, or if face lockscreen bypass is false. * unlocked if SWIPE security method is used, or if face lockscreen bypass is false.

View File

@@ -56,7 +56,7 @@ public interface KeyguardStateController extends CallbackController<Callback> {
/** /**
* Whether the bouncer (PIN/password entry) is currently visible. * Whether the bouncer (PIN/password entry) is currently visible.
*/ */
boolean isBouncerShowing(); boolean isPrimaryBouncerShowing();
/** /**
* If swiping up will unlock without asking for a password. * If swiping up will unlock without asking for a password.
@@ -196,7 +196,7 @@ public interface KeyguardStateController extends CallbackController<Callback> {
/** **/ /** **/
default void notifyKeyguardState(boolean showing, boolean occluded) {} default void notifyKeyguardState(boolean showing, boolean occluded) {}
/** **/ /** **/
default void notifyBouncerShowing(boolean showing) {} default void notifyPrimaryBouncerShowing(boolean showing) {}
/** /**
* Updates the keyguard state to reflect that it's in the process of being dismissed, either by * Updates the keyguard state to reflect that it's in the process of being dismissed, either by
@@ -244,7 +244,7 @@ public interface KeyguardStateController extends CallbackController<Callback> {
/** /**
* Called when the bouncer (PIN/password entry) is shown or hidden. * Called when the bouncer (PIN/password entry) is shown or hidden.
*/ */
default void onBouncerShowingChanged() {} default void onPrimaryBouncerShowingChanged() {}
/** /**
* Triggered when the device was just unlocked and the lock screen is being dismissed. * Triggered when the device was just unlocked and the lock screen is being dismissed.

View File

@@ -65,7 +65,7 @@ public class KeyguardStateControllerImpl implements KeyguardStateController, Dum
private boolean mCanDismissLockScreen; private boolean mCanDismissLockScreen;
private boolean mShowing; private boolean mShowing;
private boolean mBouncerShowing; private boolean mPrimaryBouncerShowing;
private boolean mSecure; private boolean mSecure;
private boolean mOccluded; private boolean mOccluded;
@@ -157,8 +157,8 @@ public class KeyguardStateControllerImpl implements KeyguardStateController, Dum
} }
@Override @Override
public boolean isBouncerShowing() { public boolean isPrimaryBouncerShowing() {
return mBouncerShowing; return mPrimaryBouncerShowing;
} }
@Override @Override
@@ -339,11 +339,11 @@ public class KeyguardStateControllerImpl implements KeyguardStateController, Dum
} }
@Override @Override
public void notifyBouncerShowing(boolean showing) { public void notifyPrimaryBouncerShowing(boolean showing) {
if (mBouncerShowing != showing) { if (mPrimaryBouncerShowing != showing) {
mBouncerShowing = showing; mPrimaryBouncerShowing = showing;
new ArrayList<>(mCallbacks).forEach(Callback::onBouncerShowingChanged); new ArrayList<>(mCallbacks).forEach(Callback::onPrimaryBouncerShowingChanged);
} }
} }

View File

@@ -23,6 +23,7 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.FeatureFlags
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
@@ -85,6 +86,7 @@ class ClockEventControllerTest : SysuiTestCase() {
@Mock private lateinit var transitionRepository: KeyguardTransitionRepository @Mock private lateinit var transitionRepository: KeyguardTransitionRepository
@Mock private lateinit var commandQueue: CommandQueue @Mock private lateinit var commandQueue: CommandQueue
private lateinit var repository: FakeKeyguardRepository private lateinit var repository: FakeKeyguardRepository
private lateinit var bouncerRepository: FakeKeyguardBouncerRepository
@Mock private lateinit var smallLogBuffer: LogBuffer @Mock private lateinit var smallLogBuffer: LogBuffer
@Mock private lateinit var largeLogBuffer: LogBuffer @Mock private lateinit var largeLogBuffer: LogBuffer
private lateinit var underTest: ClockEventController private lateinit var underTest: ClockEventController
@@ -103,11 +105,15 @@ class ClockEventControllerTest : SysuiTestCase() {
whenever(largeClockEvents.tickRate).thenReturn(ClockTickRate.PER_MINUTE) whenever(largeClockEvents.tickRate).thenReturn(ClockTickRate.PER_MINUTE)
repository = FakeKeyguardRepository() repository = FakeKeyguardRepository()
bouncerRepository = FakeKeyguardBouncerRepository()
underTest = ClockEventController( underTest = ClockEventController(
KeyguardInteractor(repository = repository, KeyguardInteractor(
commandQueue = commandQueue, repository = repository,
featureFlags = featureFlags), commandQueue = commandQueue,
featureFlags = featureFlags,
bouncerRepository = bouncerRepository,
),
KeyguardTransitionInteractor(repository = transitionRepository), KeyguardTransitionInteractor(repository = transitionRepository),
broadcastDispatcher, broadcastDispatcher,
batteryController, batteryController,

View File

@@ -43,6 +43,7 @@ import com.android.systemui.biometrics.AuthRippleController;
import com.android.systemui.doze.util.BurnInHelperKt; import com.android.systemui.doze.util.BurnInHelperKt;
import com.android.systemui.dump.DumpManager; import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository;
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository; import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository;
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository; import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository;
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor; import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
@@ -159,9 +160,12 @@ public class LockIconViewControllerBaseTest extends SysuiTestCase {
mAuthRippleController, mAuthRippleController,
mResources, mResources,
new KeyguardTransitionInteractor(mTransitionRepository), new KeyguardTransitionInteractor(mTransitionRepository),
new KeyguardInteractor(new FakeKeyguardRepository(), new KeyguardInteractor(
new FakeKeyguardRepository(),
mCommandQueue, mCommandQueue,
mFeatureFlags), mFeatureFlags,
new FakeKeyguardBouncerRepository()
),
mFeatureFlags mFeatureFlags
); );
} }

View File

@@ -39,6 +39,7 @@ import com.android.systemui.keyguard.data.quickaffordance.FakeKeyguardQuickAffor
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLegacySettingSyncer import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLegacySettingSyncer
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLocalUserSelectionManager import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLocalUserSelectionManager
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceRemoteUserSelectionManager import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceRemoteUserSelectionManager
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
@@ -172,6 +173,7 @@ class CustomizationProviderTest : SysuiTestCase() {
repository = FakeKeyguardRepository(), repository = FakeKeyguardRepository(),
commandQueue = commandQueue, commandQueue = commandQueue,
featureFlags = featureFlags, featureFlags = featureFlags,
bouncerRepository = FakeKeyguardBouncerRepository(),
), ),
registry = mock(), registry = mock(),
lockPatternUtils = lockPatternUtils, lockPatternUtils = lockPatternUtils,

View File

@@ -323,29 +323,6 @@ class KeyguardRepositoryImplTest : SysuiTestCase() {
assertThat(underTest.isUdfpsSupported()).isFalse() assertThat(underTest.isUdfpsSupported()).isFalse()
} }
@Test
fun isBouncerShowing() =
runTest(UnconfinedTestDispatcher()) {
whenever(keyguardStateController.isBouncerShowing).thenReturn(false)
var latest: Boolean? = null
val job = underTest.isBouncerShowing.onEach { latest = it }.launchIn(this)
assertThat(latest).isFalse()
val captor = argumentCaptor<KeyguardStateController.Callback>()
verify(keyguardStateController).addCallback(captor.capture())
whenever(keyguardStateController.isBouncerShowing).thenReturn(true)
captor.value.onBouncerShowingChanged()
assertThat(latest).isTrue()
whenever(keyguardStateController.isBouncerShowing).thenReturn(false)
captor.value.onBouncerShowingChanged()
assertThat(latest).isFalse()
job.cancel()
}
@Test @Test
fun isKeyguardGoingAway() = fun isKeyguardGoingAway() =
runTest(UnconfinedTestDispatcher()) { runTest(UnconfinedTestDispatcher()) {

View File

@@ -130,7 +130,7 @@ class AlternateBouncerInteractorTest : SysuiTestCase() {
givenCanShowAlternateBouncer() givenCanShowAlternateBouncer()
assertTrue(underTest.show()) assertTrue(underTest.show())
assertTrue(bouncerRepository.isAlternateBouncerVisible.value) assertTrue(bouncerRepository.alternateBouncerVisible.value)
} }
@Test @Test
@@ -138,7 +138,7 @@ class AlternateBouncerInteractorTest : SysuiTestCase() {
givenCannotShowAlternateBouncer() givenCannotShowAlternateBouncer()
assertFalse(underTest.show()) assertFalse(underTest.show())
assertFalse(bouncerRepository.isAlternateBouncerVisible.value) assertFalse(bouncerRepository.alternateBouncerVisible.value)
} }
@Test @Test
@@ -146,7 +146,7 @@ class AlternateBouncerInteractorTest : SysuiTestCase() {
bouncerRepository.setAlternateVisible(true) bouncerRepository.setAlternateVisible(true)
assertTrue(underTest.hide()) assertTrue(underTest.hide())
assertFalse(bouncerRepository.isAlternateBouncerVisible.value) assertFalse(bouncerRepository.alternateBouncerVisible.value)
} }
@Test @Test
@@ -154,7 +154,7 @@ class AlternateBouncerInteractorTest : SysuiTestCase() {
bouncerRepository.setAlternateVisible(false) bouncerRepository.setAlternateVisible(false)
assertFalse(underTest.hide()) assertFalse(underTest.hide())
assertFalse(bouncerRepository.isAlternateBouncerVisible.value) assertFalse(bouncerRepository.alternateBouncerVisible.value)
} }
private fun givenCanShowAlternateBouncer() { private fun givenCanShowAlternateBouncer() {

View File

@@ -25,6 +25,7 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.flags.FakeFeatureFlags import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR import com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.shared.model.CameraLaunchSourceModel import com.android.systemui.keyguard.shared.model.CameraLaunchSourceModel
import com.android.systemui.settings.DisplayTracker import com.android.systemui.settings.DisplayTracker
@@ -38,7 +39,6 @@ import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.mockito.Mockito.mock import org.mockito.Mockito.mock
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations import org.mockito.MockitoAnnotations
@SmallTest @SmallTest
@@ -50,6 +50,7 @@ class KeyguardInteractorTest : SysuiTestCase() {
private lateinit var underTest: KeyguardInteractor private lateinit var underTest: KeyguardInteractor
private lateinit var repository: FakeKeyguardRepository private lateinit var repository: FakeKeyguardRepository
private lateinit var bouncerRepository: FakeKeyguardBouncerRepository
@Before @Before
fun setUp() { fun setUp() {
@@ -58,7 +59,14 @@ class KeyguardInteractorTest : SysuiTestCase() {
commandQueue = FakeCommandQueue(mock(Context::class.java), mock(DisplayTracker::class.java)) commandQueue = FakeCommandQueue(mock(Context::class.java), mock(DisplayTracker::class.java))
testScope = TestScope() testScope = TestScope()
repository = FakeKeyguardRepository() repository = FakeKeyguardRepository()
underTest = KeyguardInteractor(repository, commandQueue, featureFlags) bouncerRepository = FakeKeyguardBouncerRepository()
underTest =
KeyguardInteractor(
repository,
commandQueue,
featureFlags,
bouncerRepository,
)
} }
@Test @Test
@@ -137,7 +145,7 @@ class KeyguardInteractorTest : SysuiTestCase() {
repository.setKeyguardOccluded(true) repository.setKeyguardOccluded(true)
assertThat(secureCameraActive()).isTrue() assertThat(secureCameraActive()).isTrue()
repository.setBouncerShowing(true) bouncerRepository.setPrimaryVisible(true)
assertThat(secureCameraActive()).isFalse() assertThat(secureCameraActive()).isFalse()
} }

View File

@@ -36,6 +36,7 @@ import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanc
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLegacySettingSyncer import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLegacySettingSyncer
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLocalUserSelectionManager import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLocalUserSelectionManager
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceRemoteUserSelectionManager import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceRemoteUserSelectionManager
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository
import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceRegistry import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceRegistry
@@ -298,6 +299,7 @@ class KeyguardQuickAffordanceInteractorParameterizedTest : SysuiTestCase() {
repository = FakeKeyguardRepository(), repository = FakeKeyguardRepository(),
commandQueue = commandQueue, commandQueue = commandQueue,
featureFlags = featureFlags, featureFlags = featureFlags,
bouncerRepository = FakeKeyguardBouncerRepository(),
), ),
registry = registry =
FakeKeyguardQuickAffordanceRegistry( FakeKeyguardQuickAffordanceRegistry(

View File

@@ -36,6 +36,7 @@ import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanc
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLegacySettingSyncer import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLegacySettingSyncer
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLocalUserSelectionManager import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLocalUserSelectionManager
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceRemoteUserSelectionManager import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceRemoteUserSelectionManager
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordanceModel import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordanceModel
@@ -159,7 +160,8 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
KeyguardInteractor( KeyguardInteractor(
repository = repository, repository = repository,
commandQueue = commandQueue, commandQueue = commandQueue,
featureFlags = featureFlags featureFlags = featureFlags,
bouncerRepository = FakeKeyguardBouncerRepository(),
), ),
registry = registry =
FakeKeyguardQuickAffordanceRegistry( FakeKeyguardQuickAffordanceRegistry(

View File

@@ -22,7 +22,9 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.Interpolators import com.android.systemui.animation.Interpolators
import com.android.systemui.flags.FakeFeatureFlags import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepositoryImpl import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepositoryImpl
@@ -65,6 +67,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
private lateinit var testScope: TestScope private lateinit var testScope: TestScope
private lateinit var keyguardRepository: FakeKeyguardRepository private lateinit var keyguardRepository: FakeKeyguardRepository
private lateinit var bouncerRepository: FakeKeyguardBouncerRepository
private lateinit var shadeRepository: ShadeRepository private lateinit var shadeRepository: ShadeRepository
// Used to issue real transition steps for test input // Used to issue real transition steps for test input
@@ -81,6 +84,10 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
private lateinit var fromOccludedTransitionInteractor: FromOccludedTransitionInteractor private lateinit var fromOccludedTransitionInteractor: FromOccludedTransitionInteractor
private lateinit var fromGoneTransitionInteractor: FromGoneTransitionInteractor private lateinit var fromGoneTransitionInteractor: FromGoneTransitionInteractor
private lateinit var fromAodTransitionInteractor: FromAodTransitionInteractor private lateinit var fromAodTransitionInteractor: FromAodTransitionInteractor
private lateinit var fromAlternateBouncerTransitionInteractor:
FromAlternateBouncerTransitionInteractor
private lateinit var fromPrimaryBouncerTransitionInteractor:
FromPrimaryBouncerTransitionInteractor
@Before @Before
fun setUp() { fun setUp() {
@@ -88,6 +95,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
testScope = TestScope() testScope = TestScope()
keyguardRepository = FakeKeyguardRepository() keyguardRepository = FakeKeyguardRepository()
bouncerRepository = FakeKeyguardBouncerRepository()
shadeRepository = FakeShadeRepository() shadeRepository = FakeShadeRepository()
/* Used to issue full transition steps, to better simulate a real device */ /* Used to issue full transition steps, to better simulate a real device */
@@ -98,8 +106,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
fromLockscreenTransitionInteractor = fromLockscreenTransitionInteractor =
FromLockscreenTransitionInteractor( FromLockscreenTransitionInteractor(
scope = testScope, scope = testScope,
keyguardInteractor = keyguardInteractor = createKeyguardInteractor(featureFlags),
KeyguardInteractor(keyguardRepository, commandQueue, featureFlags),
shadeRepository = shadeRepository, shadeRepository = shadeRepository,
keyguardTransitionRepository = mockTransitionRepository, keyguardTransitionRepository = mockTransitionRepository,
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository), keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
@@ -109,8 +116,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
fromDreamingTransitionInteractor = fromDreamingTransitionInteractor =
FromDreamingTransitionInteractor( FromDreamingTransitionInteractor(
scope = testScope, scope = testScope,
keyguardInteractor = keyguardInteractor = createKeyguardInteractor(featureFlags),
KeyguardInteractor(keyguardRepository, commandQueue, featureFlags),
keyguardTransitionRepository = mockTransitionRepository, keyguardTransitionRepository = mockTransitionRepository,
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository), keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
) )
@@ -119,8 +125,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
fromAodTransitionInteractor = fromAodTransitionInteractor =
FromAodTransitionInteractor( FromAodTransitionInteractor(
scope = testScope, scope = testScope,
keyguardInteractor = keyguardInteractor = createKeyguardInteractor(featureFlags),
KeyguardInteractor(keyguardRepository, commandQueue, featureFlags),
keyguardTransitionRepository = mockTransitionRepository, keyguardTransitionRepository = mockTransitionRepository,
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository), keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
) )
@@ -129,8 +134,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
fromGoneTransitionInteractor = fromGoneTransitionInteractor =
FromGoneTransitionInteractor( FromGoneTransitionInteractor(
scope = testScope, scope = testScope,
keyguardInteractor = keyguardInteractor = createKeyguardInteractor(featureFlags),
KeyguardInteractor(keyguardRepository, commandQueue, featureFlags),
keyguardTransitionRepository = mockTransitionRepository, keyguardTransitionRepository = mockTransitionRepository,
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository), keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
) )
@@ -139,8 +143,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
fromDozingTransitionInteractor = fromDozingTransitionInteractor =
FromDozingTransitionInteractor( FromDozingTransitionInteractor(
scope = testScope, scope = testScope,
keyguardInteractor = keyguardInteractor = createKeyguardInteractor(featureFlags),
KeyguardInteractor(keyguardRepository, commandQueue, featureFlags),
keyguardTransitionRepository = mockTransitionRepository, keyguardTransitionRepository = mockTransitionRepository,
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository), keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
) )
@@ -149,12 +152,29 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
fromOccludedTransitionInteractor = fromOccludedTransitionInteractor =
FromOccludedTransitionInteractor( FromOccludedTransitionInteractor(
scope = testScope, scope = testScope,
keyguardInteractor = keyguardInteractor = createKeyguardInteractor(featureFlags),
KeyguardInteractor(keyguardRepository, commandQueue, featureFlags),
keyguardTransitionRepository = mockTransitionRepository, keyguardTransitionRepository = mockTransitionRepository,
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository), keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
) )
fromOccludedTransitionInteractor.start() fromOccludedTransitionInteractor.start()
fromAlternateBouncerTransitionInteractor =
FromAlternateBouncerTransitionInteractor(
scope = testScope,
keyguardInteractor = createKeyguardInteractor(featureFlags),
keyguardTransitionRepository = mockTransitionRepository,
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
)
fromAlternateBouncerTransitionInteractor.start()
fromPrimaryBouncerTransitionInteractor =
FromPrimaryBouncerTransitionInteractor(
scope = testScope,
keyguardInteractor = createKeyguardInteractor(featureFlags),
keyguardTransitionRepository = mockTransitionRepository,
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
)
fromPrimaryBouncerTransitionInteractor.start()
} }
@Test @Test
@@ -256,7 +276,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
} }
@Test @Test
fun `LOCKSCREEN to BOUNCER via bouncer showing call`() = fun `LOCKSCREEN to PRIMARY_BOUNCER via bouncer showing call`() =
testScope.runTest { testScope.runTest {
// GIVEN a device that has at least woken up // GIVEN a device that has at least woken up
keyguardRepository.setWakefulnessModel(startingToWake()) keyguardRepository.setWakefulnessModel(startingToWake())
@@ -278,18 +298,18 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
) )
runCurrent() runCurrent()
// WHEN the bouncer is set to show // WHEN the primary bouncer is set to show
keyguardRepository.setBouncerShowing(true) bouncerRepository.setPrimaryVisible(true)
runCurrent() runCurrent()
val info = val info =
withArgCaptor<TransitionInfo> { withArgCaptor<TransitionInfo> {
verify(mockTransitionRepository).startTransition(capture()) verify(mockTransitionRepository).startTransition(capture())
} }
// THEN a transition to BOUNCER should occur // THEN a transition to PRIMARY_BOUNCER should occur
assertThat(info.ownerName).isEqualTo("FromLockscreenTransitionInteractor") assertThat(info.ownerName).isEqualTo("FromLockscreenTransitionInteractor")
assertThat(info.from).isEqualTo(KeyguardState.LOCKSCREEN) assertThat(info.from).isEqualTo(KeyguardState.LOCKSCREEN)
assertThat(info.to).isEqualTo(KeyguardState.BOUNCER) assertThat(info.to).isEqualTo(KeyguardState.PRIMARY_BOUNCER)
assertThat(info.animator).isNotNull() assertThat(info.animator).isNotNull()
coroutineContext.cancelChildren() coroutineContext.cancelChildren()
@@ -695,6 +715,297 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
coroutineContext.cancelChildren() coroutineContext.cancelChildren()
} }
@Test
fun `ALTERNATE_BOUNCER to PRIMARY_BOUNCER`() =
testScope.runTest {
// GIVEN a prior transition has run to ALTERNATE_BOUNCER
runner.startTransition(
testScope,
TransitionInfo(
ownerName = "",
from = KeyguardState.LOCKSCREEN,
to = KeyguardState.ALTERNATE_BOUNCER,
animator =
ValueAnimator().apply {
duration = 10
interpolator = Interpolators.LINEAR
},
)
)
runCurrent()
reset(mockTransitionRepository)
// WHEN the alternateBouncer stops showing and then the primary bouncer shows
bouncerRepository.setPrimaryVisible(true)
runCurrent()
val info =
withArgCaptor<TransitionInfo> {
verify(mockTransitionRepository).startTransition(capture())
}
// THEN a transition to PRIMARY_BOUNCER should occur
assertThat(info.ownerName).isEqualTo("FromAlternateBouncerTransitionInteractor")
assertThat(info.from).isEqualTo(KeyguardState.ALTERNATE_BOUNCER)
assertThat(info.to).isEqualTo(KeyguardState.PRIMARY_BOUNCER)
assertThat(info.animator).isNotNull()
coroutineContext.cancelChildren()
}
@Test
fun `ALTERNATE_BOUNCER to AOD`() =
testScope.runTest {
// GIVEN a prior transition has run to ALTERNATE_BOUNCER
bouncerRepository.setAlternateVisible(true)
runner.startTransition(
testScope,
TransitionInfo(
ownerName = "",
from = KeyguardState.LOCKSCREEN,
to = KeyguardState.ALTERNATE_BOUNCER,
animator =
ValueAnimator().apply {
duration = 10
interpolator = Interpolators.LINEAR
},
)
)
runCurrent()
reset(mockTransitionRepository)
// GIVEN the primary bouncer isn't showing, aod available and starting to sleep
bouncerRepository.setPrimaryVisible(false)
keyguardRepository.setAodAvailable(true)
keyguardRepository.setWakefulnessModel(startingToSleep())
// WHEN the alternateBouncer stops showing
bouncerRepository.setAlternateVisible(false)
advanceUntilIdle()
val info =
withArgCaptor<TransitionInfo> {
verify(mockTransitionRepository).startTransition(capture())
}
// THEN a transition to AOD should occur
assertThat(info.ownerName).isEqualTo("FromAlternateBouncerTransitionInteractor")
assertThat(info.from).isEqualTo(KeyguardState.ALTERNATE_BOUNCER)
assertThat(info.to).isEqualTo(KeyguardState.AOD)
assertThat(info.animator).isNotNull()
coroutineContext.cancelChildren()
}
@Test
fun `ALTERNATE_BOUNCER to DOZING`() =
testScope.runTest {
// GIVEN a prior transition has run to ALTERNATE_BOUNCER
bouncerRepository.setAlternateVisible(true)
runner.startTransition(
testScope,
TransitionInfo(
ownerName = "",
from = KeyguardState.LOCKSCREEN,
to = KeyguardState.ALTERNATE_BOUNCER,
animator =
ValueAnimator().apply {
duration = 10
interpolator = Interpolators.LINEAR
},
)
)
runCurrent()
reset(mockTransitionRepository)
// GIVEN the primary bouncer isn't showing, aod not available and starting to sleep
// to sleep
bouncerRepository.setPrimaryVisible(false)
keyguardRepository.setAodAvailable(false)
keyguardRepository.setWakefulnessModel(startingToSleep())
// WHEN the alternateBouncer stops showing
bouncerRepository.setAlternateVisible(false)
advanceUntilIdle()
val info =
withArgCaptor<TransitionInfo> {
verify(mockTransitionRepository).startTransition(capture())
}
// THEN a transition to DOZING should occur
assertThat(info.ownerName).isEqualTo("FromAlternateBouncerTransitionInteractor")
assertThat(info.from).isEqualTo(KeyguardState.ALTERNATE_BOUNCER)
assertThat(info.to).isEqualTo(KeyguardState.DOZING)
assertThat(info.animator).isNotNull()
coroutineContext.cancelChildren()
}
@Test
fun `ALTERNATE_BOUNCER to LOCKSCREEN`() =
testScope.runTest {
// GIVEN a prior transition has run to ALTERNATE_BOUNCER
bouncerRepository.setAlternateVisible(true)
runner.startTransition(
testScope,
TransitionInfo(
ownerName = "",
from = KeyguardState.LOCKSCREEN,
to = KeyguardState.ALTERNATE_BOUNCER,
animator =
ValueAnimator().apply {
duration = 10
interpolator = Interpolators.LINEAR
},
)
)
runCurrent()
reset(mockTransitionRepository)
// GIVEN the primary bouncer isn't showing and device not sleeping
bouncerRepository.setPrimaryVisible(false)
keyguardRepository.setWakefulnessModel(startingToWake())
// WHEN the alternateBouncer stops showing
bouncerRepository.setAlternateVisible(false)
advanceUntilIdle()
val info =
withArgCaptor<TransitionInfo> {
verify(mockTransitionRepository).startTransition(capture())
}
// THEN a transition to LOCKSCREEN should occur
assertThat(info.ownerName).isEqualTo("FromAlternateBouncerTransitionInteractor")
assertThat(info.from).isEqualTo(KeyguardState.ALTERNATE_BOUNCER)
assertThat(info.to).isEqualTo(KeyguardState.LOCKSCREEN)
assertThat(info.animator).isNotNull()
coroutineContext.cancelChildren()
}
@Test
fun `PRIMARY_BOUNCER to AOD`() =
testScope.runTest {
// GIVEN a prior transition has run to PRIMARY_BOUNCER
bouncerRepository.setPrimaryVisible(true)
runner.startTransition(
testScope,
TransitionInfo(
ownerName = "",
from = KeyguardState.LOCKSCREEN,
to = KeyguardState.PRIMARY_BOUNCER,
animator =
ValueAnimator().apply {
duration = 10
interpolator = Interpolators.LINEAR
},
)
)
runCurrent()
reset(mockTransitionRepository)
// GIVEN aod available and starting to sleep
keyguardRepository.setAodAvailable(true)
keyguardRepository.setWakefulnessModel(startingToSleep())
// WHEN the primaryBouncer stops showing
bouncerRepository.setPrimaryVisible(false)
runCurrent()
val info =
withArgCaptor<TransitionInfo> {
verify(mockTransitionRepository).startTransition(capture())
}
// THEN a transition to AOD should occur
assertThat(info.ownerName).isEqualTo("FromPrimaryBouncerTransitionInteractor")
assertThat(info.from).isEqualTo(KeyguardState.PRIMARY_BOUNCER)
assertThat(info.to).isEqualTo(KeyguardState.AOD)
assertThat(info.animator).isNotNull()
coroutineContext.cancelChildren()
}
@Test
fun `PRIMARY_BOUNCER to DOZING`() =
testScope.runTest {
// GIVEN a prior transition has run to PRIMARY_BOUNCER
bouncerRepository.setPrimaryVisible(true)
runner.startTransition(
testScope,
TransitionInfo(
ownerName = "",
from = KeyguardState.LOCKSCREEN,
to = KeyguardState.PRIMARY_BOUNCER,
animator =
ValueAnimator().apply {
duration = 10
interpolator = Interpolators.LINEAR
},
)
)
runCurrent()
reset(mockTransitionRepository)
// GIVEN aod not available and starting to sleep to sleep
keyguardRepository.setAodAvailable(false)
keyguardRepository.setWakefulnessModel(startingToSleep())
// WHEN the primaryBouncer stops showing
bouncerRepository.setPrimaryVisible(false)
runCurrent()
val info =
withArgCaptor<TransitionInfo> {
verify(mockTransitionRepository).startTransition(capture())
}
// THEN a transition to DOZING should occur
assertThat(info.ownerName).isEqualTo("FromPrimaryBouncerTransitionInteractor")
assertThat(info.from).isEqualTo(KeyguardState.PRIMARY_BOUNCER)
assertThat(info.to).isEqualTo(KeyguardState.DOZING)
assertThat(info.animator).isNotNull()
coroutineContext.cancelChildren()
}
@Test
fun `PRIMARY_BOUNCER to LOCKSCREEN`() =
testScope.runTest {
// GIVEN a prior transition has run to PRIMARY_BOUNCER
bouncerRepository.setPrimaryVisible(true)
runner.startTransition(
testScope,
TransitionInfo(
ownerName = "",
from = KeyguardState.LOCKSCREEN,
to = KeyguardState.PRIMARY_BOUNCER,
animator =
ValueAnimator().apply {
duration = 10
interpolator = Interpolators.LINEAR
},
)
)
runCurrent()
reset(mockTransitionRepository)
// GIVEN device not sleeping
keyguardRepository.setWakefulnessModel(startingToWake())
// WHEN the alternateBouncer stops showing
bouncerRepository.setPrimaryVisible(false)
runCurrent()
val info =
withArgCaptor<TransitionInfo> {
verify(mockTransitionRepository).startTransition(capture())
}
// THEN a transition to LOCKSCREEN should occur
assertThat(info.ownerName).isEqualTo("FromPrimaryBouncerTransitionInteractor")
assertThat(info.from).isEqualTo(KeyguardState.PRIMARY_BOUNCER)
assertThat(info.to).isEqualTo(KeyguardState.LOCKSCREEN)
assertThat(info.animator).isNotNull()
coroutineContext.cancelChildren()
}
private fun startingToWake() = private fun startingToWake() =
WakefulnessModel( WakefulnessModel(
WakefulnessState.STARTING_TO_WAKE, WakefulnessState.STARTING_TO_WAKE,
@@ -710,4 +1021,13 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
WakeSleepReason.OTHER, WakeSleepReason.OTHER,
WakeSleepReason.OTHER WakeSleepReason.OTHER
) )
private fun createKeyguardInteractor(featureFlags: FeatureFlags): KeyguardInteractor {
return KeyguardInteractor(
keyguardRepository,
commandQueue,
featureFlags,
bouncerRepository,
)
}
} }

View File

@@ -102,7 +102,7 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() {
verify(repository).setPrimaryScrimmed(true) verify(repository).setPrimaryScrimmed(true)
verify(repository).setPanelExpansion(EXPANSION_VISIBLE) verify(repository).setPanelExpansion(EXPANSION_VISIBLE)
verify(repository).setPrimaryShowingSoon(true) verify(repository).setPrimaryShowingSoon(true)
verify(keyguardStateController).notifyBouncerShowing(true) verify(keyguardStateController).notifyPrimaryBouncerShowing(true)
verify(mPrimaryBouncerCallbackInteractor).dispatchStartingToShow() verify(mPrimaryBouncerCallbackInteractor).dispatchStartingToShow()
verify(repository).setPrimaryVisible(true) verify(repository).setPrimaryVisible(true)
verify(repository).setPrimaryShow(any(KeyguardBouncerModel::class.java)) verify(repository).setPrimaryShow(any(KeyguardBouncerModel::class.java))
@@ -118,7 +118,7 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() {
@Test @Test
fun testShow_keyguardIsDone() { fun testShow_keyguardIsDone() {
`when`(bouncerView.delegate?.showNextSecurityScreenOrFinish()).thenReturn(true) `when`(bouncerView.delegate?.showNextSecurityScreenOrFinish()).thenReturn(true)
verify(keyguardStateController, never()).notifyBouncerShowing(true) verify(keyguardStateController, never()).notifyPrimaryBouncerShowing(true)
verify(mPrimaryBouncerCallbackInteractor, never()).dispatchStartingToShow() verify(mPrimaryBouncerCallbackInteractor, never()).dispatchStartingToShow()
} }
@@ -126,7 +126,7 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() {
fun testHide() { fun testHide() {
underTest.hide() underTest.hide()
verify(falsingCollector).onBouncerHidden() verify(falsingCollector).onBouncerHidden()
verify(keyguardStateController).notifyBouncerShowing(false) verify(keyguardStateController).notifyPrimaryBouncerShowing(false)
verify(repository).setPrimaryShowingSoon(false) verify(repository).setPrimaryShowingSoon(false)
verify(repository).setPrimaryVisible(false) verify(repository).setPrimaryVisible(false)
verify(repository).setPrimaryHide(true) verify(repository).setPrimaryHide(true)

View File

@@ -35,6 +35,7 @@ import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanc
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLegacySettingSyncer import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLegacySettingSyncer
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLocalUserSelectionManager import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLocalUserSelectionManager
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceRemoteUserSelectionManager import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceRemoteUserSelectionManager
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor
@@ -136,6 +137,7 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
repository = repository, repository = repository,
commandQueue = commandQueue, commandQueue = commandQueue,
featureFlags = featureFlags, featureFlags = featureFlags,
bouncerRepository = FakeKeyguardBouncerRepository(),
) )
whenever(userTracker.userHandle).thenReturn(mock()) whenever(userTracker.userHandle).thenReturn(mock())
whenever(lockPatternUtils.getStrongAuthForUser(anyInt())) whenever(lockPatternUtils.getStrongAuthForUser(anyInt()))

View File

@@ -53,7 +53,7 @@ public class FakeKeyguardStateController implements KeyguardStateController {
} }
@Override @Override
public boolean isBouncerShowing() { public boolean isPrimaryBouncerShowing() {
return false; return false;
} }

View File

@@ -28,6 +28,7 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.flags.FakeFeatureFlags import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR import com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR
import com.android.systemui.keyguard.WakefulnessLifecycle import com.android.systemui.keyguard.WakefulnessLifecycle
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.shade.NotificationPanelViewController import com.android.systemui.shade.NotificationPanelViewController
@@ -112,7 +113,8 @@ class FoldAodAnimationControllerTest : SysuiTestCase() {
KeyguardInteractor( KeyguardInteractor(
repository = keyguardRepository, repository = keyguardRepository,
commandQueue = commandQueue, commandQueue = commandQueue,
featureFlags = featureFlags featureFlags = featureFlags,
bouncerRepository = FakeKeyguardBouncerRepository(),
) )
// Needs to be run on the main thread // Needs to be run on the main thread

View File

@@ -38,6 +38,7 @@ import com.android.systemui.common.shared.model.Text
import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.flags.FakeFeatureFlags import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.ActivityStarter
@@ -143,6 +144,7 @@ class UserInteractorTest : SysuiTestCase() {
repository = keyguardRepository, repository = keyguardRepository,
commandQueue = commandQueue, commandQueue = commandQueue,
featureFlags = featureFlags, featureFlags = featureFlags,
bouncerRepository = FakeKeyguardBouncerRepository(),
), ),
manager = manager, manager = manager,
headlessSystemUserMode = headlessSystemUserMode, headlessSystemUserMode = headlessSystemUserMode,

View File

@@ -31,6 +31,7 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.Text import com.android.systemui.common.shared.model.Text
import com.android.systemui.flags.FakeFeatureFlags import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.ActivityStarter
@@ -251,6 +252,7 @@ class StatusBarUserChipViewModelTest : SysuiTestCase() {
repository = keyguardRepository, repository = keyguardRepository,
commandQueue = commandQueue, commandQueue = commandQueue,
featureFlags = featureFlags, featureFlags = featureFlags,
bouncerRepository = FakeKeyguardBouncerRepository(),
), ),
featureFlags = featureFlags, featureFlags = featureFlags,
manager = manager, manager = manager,

View File

@@ -29,6 +29,7 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.Text import com.android.systemui.common.shared.model.Text
import com.android.systemui.flags.FakeFeatureFlags import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.ActivityStarter
@@ -152,7 +153,8 @@ class UserSwitcherViewModelTest : SysuiTestCase() {
KeyguardInteractor( KeyguardInteractor(
repository = keyguardRepository, repository = keyguardRepository,
commandQueue = commandQueue, commandQueue = commandQueue,
featureFlags = featureFlags featureFlags = featureFlags,
bouncerRepository = FakeKeyguardBouncerRepository(),
), ),
featureFlags = featureFlags, featureFlags = featureFlags,
manager = manager, manager = manager,

View File

@@ -57,10 +57,10 @@ class FakeKeyguardBouncerRepository : KeyguardBouncerRepository {
override val bouncerPromptReason = 0 override val bouncerPromptReason = 0
override val bouncerErrorMessage: CharSequence? = null override val bouncerErrorMessage: CharSequence? = null
private val _isAlternateBouncerVisible = MutableStateFlow(false) private val _isAlternateBouncerVisible = MutableStateFlow(false)
override val isAlternateBouncerVisible = _isAlternateBouncerVisible.asStateFlow() override val alternateBouncerVisible = _isAlternateBouncerVisible.asStateFlow()
override var lastAlternateBouncerVisibleTime: Long = 0L override var lastAlternateBouncerVisibleTime: Long = 0L
private val _isAlternateBouncerUIAvailable = MutableStateFlow<Boolean>(false) private val _isAlternateBouncerUIAvailable = MutableStateFlow<Boolean>(false)
override val isAlternateBouncerUIAvailable = _isAlternateBouncerUIAvailable.asStateFlow() override val alternateBouncerUIAvailable = _isAlternateBouncerUIAvailable.asStateFlow()
override fun setPrimaryScrimmed(isScrimmed: Boolean) { override fun setPrimaryScrimmed(isScrimmed: Boolean) {
_primaryBouncerScrimmed.value = isScrimmed _primaryBouncerScrimmed.value = isScrimmed

View File

@@ -84,9 +84,6 @@ class FakeKeyguardRepository : KeyguardRepository {
private val _isUdfpsSupported = MutableStateFlow(false) private val _isUdfpsSupported = MutableStateFlow(false)
private val _isBouncerShowing = MutableStateFlow(false)
override val isBouncerShowing: Flow<Boolean> = _isBouncerShowing
private val _isKeyguardGoingAway = MutableStateFlow(false) private val _isKeyguardGoingAway = MutableStateFlow(false)
override val isKeyguardGoingAway: Flow<Boolean> = _isKeyguardGoingAway override val isKeyguardGoingAway: Flow<Boolean> = _isKeyguardGoingAway
@@ -153,10 +150,6 @@ class FakeKeyguardRepository : KeyguardRepository {
_wakefulnessModel.value = model _wakefulnessModel.value = model
} }
fun setBouncerShowing(isShowing: Boolean) {
_isBouncerShowing.value = isShowing
}
fun setBiometricUnlockState(state: BiometricUnlockModel) { fun setBiometricUnlockState(state: BiometricUnlockModel) {
_biometricUnlockState.tryEmit(state) _biometricUnlockState.tryEmit(state)
} }

View File

@@ -49,7 +49,7 @@ public class FakeKeyguardStateController implements KeyguardStateController {
} }
@Override @Override
public boolean isBouncerShowing() { public boolean isPrimaryBouncerShowing() {
return false; return false;
} }