[DO NOT MERGE] Transitions - Smooth out bouncer -> gone
If the device unlocks while the bouncer is in transit, the bouncer will remain visible over the launcher for half a second while the appear animation completes while the scrim immediately disappears (while also undergoing numerous bad requests to transition to invalid states). To fix, control this animation using the transition repo instead and ignore all other incoming requests while it is running. Also, support a new mode for canceling transitions. Some transitions may want to continue from the canceled point, others may want to run the starting transition in full. Fixes: 268596047 Test: ScrimControllerTest KeyguardRepositoryImplTest NotificationShadeWindowViewControllerTest KeyguardTransitionScenariosTest KeyguardTransitionRepositoryTest Test: manual - Tested all bouncer variations, with and without face unlock Change-Id: I6fdd0b796e8833539d06c8534182f1298c7e3a58
This commit is contained in:
@@ -78,7 +78,7 @@
|
|||||||
<!-- The vertical margin between the date and the owner info. -->
|
<!-- The vertical margin between the date and the owner info. -->
|
||||||
|
|
||||||
<!-- The translation for disappearing security views after having solved them. -->
|
<!-- The translation for disappearing security views after having solved them. -->
|
||||||
<dimen name="disappear_y_translation">-32dp</dimen>
|
<dimen name="disappear_y_translation">-50dp</dimen>
|
||||||
|
|
||||||
<!-- Dimens for animation for the Bouncer PIN view -->
|
<!-- Dimens for animation for the Bouncer PIN view -->
|
||||||
<dimen name="pin_view_trans_y_entry">120dp</dimen>
|
<dimen name="pin_view_trans_y_entry">120dp</dimen>
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ import static java.lang.Integer.max;
|
|||||||
|
|
||||||
import android.animation.Animator;
|
import android.animation.Animator;
|
||||||
import android.animation.AnimatorListenerAdapter;
|
import android.animation.AnimatorListenerAdapter;
|
||||||
import android.animation.AnimatorSet;
|
|
||||||
import android.animation.ObjectAnimator;
|
import android.animation.ObjectAnimator;
|
||||||
import android.animation.ValueAnimator;
|
import android.animation.ValueAnimator;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
@@ -1044,13 +1043,10 @@ public class KeyguardSecurityContainer extends ConstraintLayout {
|
|||||||
|
|
||||||
int yTranslation = mResources.getDimensionPixelSize(R.dimen.disappear_y_translation);
|
int yTranslation = mResources.getDimensionPixelSize(R.dimen.disappear_y_translation);
|
||||||
|
|
||||||
AnimatorSet anims = new AnimatorSet();
|
|
||||||
ObjectAnimator yAnim = ObjectAnimator.ofFloat(mView, View.TRANSLATION_Y, yTranslation);
|
ObjectAnimator yAnim = ObjectAnimator.ofFloat(mView, View.TRANSLATION_Y, yTranslation);
|
||||||
ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(mView, View.ALPHA, 0f);
|
yAnim.setInterpolator(Interpolators.STANDARD_ACCELERATE);
|
||||||
|
yAnim.setDuration(500);
|
||||||
anims.setInterpolator(Interpolators.STANDARD_ACCELERATE);
|
yAnim.start();
|
||||||
anims.playTogether(alphaAnim, yAnim);
|
|
||||||
anims.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupUserSwitcher() {
|
private void setupUserSwitcher() {
|
||||||
|
|||||||
@@ -636,12 +636,17 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
|
|||||||
|
|
||||||
public void startAppearAnimation() {
|
public void startAppearAnimation() {
|
||||||
if (mCurrentSecurityMode != SecurityMode.None) {
|
if (mCurrentSecurityMode != SecurityMode.None) {
|
||||||
mView.setAlpha(1f);
|
setAlpha(1f);
|
||||||
mView.startAppearAnimation(mCurrentSecurityMode);
|
mView.startAppearAnimation(mCurrentSecurityMode);
|
||||||
getCurrentSecurityController().startAppearAnimation();
|
getCurrentSecurityController().startAppearAnimation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Set the alpha of the security container view */
|
||||||
|
public void setAlpha(float alpha) {
|
||||||
|
mView.setAlpha(alpha);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean startDisappearAnimation(Runnable onFinishRunnable) {
|
public boolean startDisappearAnimation(Runnable onFinishRunnable) {
|
||||||
boolean didRunAnimation = false;
|
boolean didRunAnimation = false;
|
||||||
|
|
||||||
|
|||||||
@@ -80,6 +80,9 @@ interface KeyguardRepository {
|
|||||||
*/
|
*/
|
||||||
val isKeyguardShowing: Flow<Boolean>
|
val isKeyguardShowing: Flow<Boolean>
|
||||||
|
|
||||||
|
/** Is the keyguard in a unlocked state? */
|
||||||
|
val isKeyguardUnlocked: Flow<Boolean>
|
||||||
|
|
||||||
/** Is an activity showing over the keyguard? */
|
/** Is an activity showing over the keyguard? */
|
||||||
val isKeyguardOccluded: Flow<Boolean>
|
val isKeyguardOccluded: Flow<Boolean>
|
||||||
|
|
||||||
@@ -278,6 +281,31 @@ constructor(
|
|||||||
}
|
}
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
|
|
||||||
|
override val isKeyguardUnlocked: Flow<Boolean> =
|
||||||
|
conflatedCallbackFlow {
|
||||||
|
val callback =
|
||||||
|
object : KeyguardStateController.Callback {
|
||||||
|
override fun onUnlockedChanged() {
|
||||||
|
trySendWithFailureLogging(
|
||||||
|
keyguardStateController.isUnlocked,
|
||||||
|
TAG,
|
||||||
|
"updated isKeyguardUnlocked"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
keyguardStateController.addCallback(callback)
|
||||||
|
// Adding the callback does not send an initial update.
|
||||||
|
trySendWithFailureLogging(
|
||||||
|
keyguardStateController.isUnlocked,
|
||||||
|
TAG,
|
||||||
|
"initial isKeyguardUnlocked"
|
||||||
|
)
|
||||||
|
|
||||||
|
awaitClose { keyguardStateController.removeCallback(callback) }
|
||||||
|
}
|
||||||
|
.distinctUntilChanged()
|
||||||
|
|
||||||
override val isKeyguardGoingAway: Flow<Boolean> = conflatedCallbackFlow {
|
override val isKeyguardGoingAway: Flow<Boolean> = conflatedCallbackFlow {
|
||||||
val callback =
|
val callback =
|
||||||
object : KeyguardStateController.Callback {
|
object : KeyguardStateController.Callback {
|
||||||
|
|||||||
@@ -68,8 +68,11 @@ interface KeyguardTransitionRepository {
|
|||||||
/**
|
/**
|
||||||
* Begin a transition from one state to another. Transitions are interruptible, and will issue a
|
* Begin a transition from one state to another. Transitions are interruptible, and will issue a
|
||||||
* [TransitionStep] with state = [TransitionState.CANCELED] before beginning the next one.
|
* [TransitionStep] with state = [TransitionState.CANCELED] before beginning the next one.
|
||||||
|
*
|
||||||
|
* When canceled, there are two options: to continue from the current position of the prior
|
||||||
|
* transition, or to reset the position. When [resetIfCanceled] == true, it will do the latter.
|
||||||
*/
|
*/
|
||||||
fun startTransition(info: TransitionInfo): UUID?
|
fun startTransition(info: TransitionInfo, resetIfCanceled: Boolean = false): UUID?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows manual control of a transition. When calling [startTransition], the consumer must pass
|
* Allows manual control of a transition. When calling [startTransition], the consumer must pass
|
||||||
@@ -130,7 +133,10 @@ class KeyguardTransitionRepositoryImpl @Inject constructor() : KeyguardTransitio
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun startTransition(info: TransitionInfo): UUID? {
|
override fun startTransition(
|
||||||
|
info: TransitionInfo,
|
||||||
|
resetIfCanceled: Boolean,
|
||||||
|
): UUID? {
|
||||||
if (lastStep.from == info.from && lastStep.to == info.to) {
|
if (lastStep.from == info.from && lastStep.to == info.to) {
|
||||||
Log.i(TAG, "Duplicate call to start the transition, rejecting: $info")
|
Log.i(TAG, "Duplicate call to start the transition, rejecting: $info")
|
||||||
return null
|
return null
|
||||||
@@ -138,7 +144,11 @@ class KeyguardTransitionRepositoryImpl @Inject constructor() : KeyguardTransitio
|
|||||||
val startingValue =
|
val startingValue =
|
||||||
if (lastStep.transitionState != TransitionState.FINISHED) {
|
if (lastStep.transitionState != TransitionState.FINISHED) {
|
||||||
Log.i(TAG, "Transition still active: $lastStep, canceling")
|
Log.i(TAG, "Transition still active: $lastStep, canceling")
|
||||||
lastStep.value
|
if (resetIfCanceled) {
|
||||||
|
0f
|
||||||
|
} else {
|
||||||
|
lastStep.value
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
0f
|
0f
|
||||||
}
|
}
|
||||||
@@ -227,10 +237,7 @@ class KeyguardTransitionRepositoryImpl @Inject constructor() : KeyguardTransitio
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun trace(step: TransitionStep, isManual: Boolean) {
|
private fun trace(step: TransitionStep, isManual: Boolean) {
|
||||||
if (
|
if (step.transitionState == TransitionState.RUNNING) {
|
||||||
step.transitionState != TransitionState.STARTED &&
|
|
||||||
step.transitionState != TransitionState.FINISHED
|
|
||||||
) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val traceName =
|
val traceName =
|
||||||
@@ -243,7 +250,10 @@ class KeyguardTransitionRepositoryImpl @Inject constructor() : KeyguardTransitio
|
|||||||
val traceCookie = traceName.hashCode()
|
val traceCookie = traceName.hashCode()
|
||||||
if (step.transitionState == TransitionState.STARTED) {
|
if (step.transitionState == TransitionState.STARTED) {
|
||||||
Trace.beginAsyncSection(traceName, traceCookie)
|
Trace.beginAsyncSection(traceName, traceCookie)
|
||||||
} else if (step.transitionState == TransitionState.FINISHED) {
|
} else if (
|
||||||
|
step.transitionState == TransitionState.FINISHED ||
|
||||||
|
step.transitionState == TransitionState.CANCELED
|
||||||
|
) {
|
||||||
Trace.endAsyncSection(traceName, traceCookie)
|
Trace.endAsyncSection(traceName, traceCookie)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import kotlinx.coroutines.CoroutineScope
|
|||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.flow.collect
|
import kotlinx.coroutines.flow.collect
|
||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@@ -57,14 +56,7 @@ constructor(
|
|||||||
|
|
||||||
private fun listenForDreamingToLockscreen() {
|
private fun listenForDreamingToLockscreen() {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
// Dependending on the dream, either dream state or occluded change will change first,
|
keyguardInteractor.isAbleToDream
|
||||||
// so listen for both
|
|
||||||
combine(keyguardInteractor.isAbleToDream, keyguardInteractor.isKeyguardOccluded) {
|
|
||||||
isAbleToDream,
|
|
||||||
isKeyguardOccluded ->
|
|
||||||
isAbleToDream && isKeyguardOccluded
|
|
||||||
}
|
|
||||||
.distinctUntilChanged()
|
|
||||||
.sample(
|
.sample(
|
||||||
combine(
|
combine(
|
||||||
keyguardInteractor.dozeTransitionModel,
|
keyguardInteractor.dozeTransitionModel,
|
||||||
|
|||||||
@@ -130,55 +130,59 @@ constructor(
|
|||||||
shadeRepository.shadeModel
|
shadeRepository.shadeModel
|
||||||
.sample(
|
.sample(
|
||||||
combine(
|
combine(
|
||||||
keyguardTransitionInteractor.finishedKeyguardState,
|
keyguardTransitionInteractor.startedKeyguardTransitionStep,
|
||||||
keyguardInteractor.statusBarState,
|
keyguardInteractor.statusBarState,
|
||||||
::Pair
|
keyguardInteractor.isKeyguardUnlocked,
|
||||||
|
::toTriple
|
||||||
),
|
),
|
||||||
::toTriple
|
::toQuad
|
||||||
)
|
)
|
||||||
.collect { (shadeModel, keyguardState, statusBarState) ->
|
.collect { (shadeModel, keyguardState, statusBarState, isKeyguardUnlocked) ->
|
||||||
val id = transitionId
|
val id = transitionId
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
// An existing `id` means a transition is started, and calls to
|
if (keyguardState.to == KeyguardState.PRIMARY_BOUNCER) {
|
||||||
// `updateTransition` will control it until FINISHED or CANCELED
|
// An existing `id` means a transition is started, and calls to
|
||||||
var nextState =
|
// `updateTransition` will control it until FINISHED or CANCELED
|
||||||
if (shadeModel.expansionAmount == 0f) {
|
var nextState =
|
||||||
TransitionState.FINISHED
|
if (shadeModel.expansionAmount == 0f) {
|
||||||
} else if (shadeModel.expansionAmount == 1f) {
|
TransitionState.FINISHED
|
||||||
TransitionState.CANCELED
|
} else if (shadeModel.expansionAmount == 1f) {
|
||||||
} else {
|
TransitionState.CANCELED
|
||||||
TransitionState.RUNNING
|
} else {
|
||||||
}
|
TransitionState.RUNNING
|
||||||
keyguardTransitionRepository.updateTransition(
|
}
|
||||||
id,
|
keyguardTransitionRepository.updateTransition(
|
||||||
1f - shadeModel.expansionAmount,
|
id,
|
||||||
nextState,
|
1f - shadeModel.expansionAmount,
|
||||||
)
|
nextState,
|
||||||
|
|
||||||
if (
|
|
||||||
nextState == TransitionState.CANCELED ||
|
|
||||||
nextState == TransitionState.FINISHED
|
|
||||||
) {
|
|
||||||
transitionId = null
|
|
||||||
}
|
|
||||||
|
|
||||||
// If canceled, just put the state back
|
|
||||||
if (nextState == TransitionState.CANCELED) {
|
|
||||||
keyguardTransitionRepository.startTransition(
|
|
||||||
TransitionInfo(
|
|
||||||
ownerName = name,
|
|
||||||
from = KeyguardState.PRIMARY_BOUNCER,
|
|
||||||
to = KeyguardState.LOCKSCREEN,
|
|
||||||
animator = getAnimator(0.milliseconds)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (
|
||||||
|
nextState == TransitionState.CANCELED ||
|
||||||
|
nextState == TransitionState.FINISHED
|
||||||
|
) {
|
||||||
|
transitionId = null
|
||||||
|
}
|
||||||
|
|
||||||
|
// If canceled, just put the state back
|
||||||
|
if (nextState == TransitionState.CANCELED) {
|
||||||
|
keyguardTransitionRepository.startTransition(
|
||||||
|
TransitionInfo(
|
||||||
|
ownerName = name,
|
||||||
|
from = KeyguardState.PRIMARY_BOUNCER,
|
||||||
|
to = KeyguardState.LOCKSCREEN,
|
||||||
|
animator = getAnimator(0.milliseconds)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// TODO (b/251849525): Remove statusbarstate check when that state is
|
// TODO (b/251849525): Remove statusbarstate check when that state is
|
||||||
// integrated into KeyguardTransitionRepository
|
// integrated into KeyguardTransitionRepository
|
||||||
if (
|
if (
|
||||||
keyguardState == KeyguardState.LOCKSCREEN &&
|
keyguardState.to == KeyguardState.LOCKSCREEN &&
|
||||||
shadeModel.isUserDragging &&
|
shadeModel.isUserDragging &&
|
||||||
|
!isKeyguardUnlocked &&
|
||||||
statusBarState == KEYGUARD
|
statusBarState == KEYGUARD
|
||||||
) {
|
) {
|
||||||
transitionId =
|
transitionId =
|
||||||
|
|||||||
@@ -17,6 +17,9 @@
|
|||||||
package com.android.systemui.keyguard.domain.interactor
|
package com.android.systemui.keyguard.domain.interactor
|
||||||
|
|
||||||
import android.animation.ValueAnimator
|
import android.animation.ValueAnimator
|
||||||
|
import com.android.keyguard.KeyguardSecurityModel
|
||||||
|
import com.android.keyguard.KeyguardSecurityModel.SecurityMode.Password
|
||||||
|
import com.android.keyguard.KeyguardUpdateMonitor
|
||||||
import com.android.systemui.animation.Interpolators
|
import com.android.systemui.animation.Interpolators
|
||||||
import com.android.systemui.dagger.SysUISingleton
|
import com.android.systemui.dagger.SysUISingleton
|
||||||
import com.android.systemui.dagger.qualifiers.Application
|
import com.android.systemui.dagger.qualifiers.Application
|
||||||
@@ -26,6 +29,8 @@ 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.util.kotlin.sample
|
import com.android.systemui.util.kotlin.sample
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import kotlin.time.Duration
|
||||||
|
import kotlin.time.Duration.Companion.milliseconds
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -37,7 +42,8 @@ constructor(
|
|||||||
@Application private val scope: CoroutineScope,
|
@Application private val scope: CoroutineScope,
|
||||||
private val keyguardInteractor: KeyguardInteractor,
|
private val keyguardInteractor: KeyguardInteractor,
|
||||||
private val keyguardTransitionRepository: KeyguardTransitionRepository,
|
private val keyguardTransitionRepository: KeyguardTransitionRepository,
|
||||||
private val keyguardTransitionInteractor: KeyguardTransitionInteractor
|
private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
|
||||||
|
private val keyguardSecurityModel: KeyguardSecurityModel,
|
||||||
) : TransitionInteractor(FromPrimaryBouncerTransitionInteractor::class.simpleName!!) {
|
) : TransitionInteractor(FromPrimaryBouncerTransitionInteractor::class.simpleName!!) {
|
||||||
|
|
||||||
override fun start() {
|
override fun start() {
|
||||||
@@ -93,31 +99,47 @@ constructor(
|
|||||||
private fun listenForPrimaryBouncerToGone() {
|
private fun listenForPrimaryBouncerToGone() {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
keyguardInteractor.isKeyguardGoingAway
|
keyguardInteractor.isKeyguardGoingAway
|
||||||
.sample(keyguardTransitionInteractor.finishedKeyguardState) { a, b -> Pair(a, b) }
|
.sample(keyguardTransitionInteractor.startedKeyguardTransitionStep, ::Pair)
|
||||||
.collect { pair ->
|
.collect { (isKeyguardGoingAway, lastStartedTransitionStep) ->
|
||||||
val (isKeyguardGoingAway, keyguardState) = pair
|
if (
|
||||||
if (isKeyguardGoingAway && keyguardState == KeyguardState.PRIMARY_BOUNCER) {
|
isKeyguardGoingAway &&
|
||||||
|
lastStartedTransitionStep.to == KeyguardState.PRIMARY_BOUNCER
|
||||||
|
) {
|
||||||
|
val securityMode =
|
||||||
|
keyguardSecurityModel.getSecurityMode(
|
||||||
|
KeyguardUpdateMonitor.getCurrentUser()
|
||||||
|
)
|
||||||
|
// IME for password requires a slightly faster animation
|
||||||
|
val duration =
|
||||||
|
if (securityMode == Password) {
|
||||||
|
TO_GONE_SHORT_DURATION
|
||||||
|
} else {
|
||||||
|
TO_GONE_DURATION
|
||||||
|
}
|
||||||
keyguardTransitionRepository.startTransition(
|
keyguardTransitionRepository.startTransition(
|
||||||
TransitionInfo(
|
TransitionInfo(
|
||||||
ownerName = name,
|
ownerName = name,
|
||||||
from = KeyguardState.PRIMARY_BOUNCER,
|
from = KeyguardState.PRIMARY_BOUNCER,
|
||||||
to = KeyguardState.GONE,
|
to = KeyguardState.GONE,
|
||||||
animator = getAnimator(),
|
animator = getAnimator(duration),
|
||||||
)
|
),
|
||||||
|
resetIfCanceled = true,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getAnimator(): ValueAnimator {
|
private fun getAnimator(duration: Duration = DEFAULT_DURATION): ValueAnimator {
|
||||||
return ValueAnimator().apply {
|
return ValueAnimator().apply {
|
||||||
setInterpolator(Interpolators.LINEAR)
|
setInterpolator(Interpolators.LINEAR)
|
||||||
setDuration(TRANSITION_DURATION_MS)
|
setDuration(duration.inWholeMilliseconds)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val TRANSITION_DURATION_MS = 300L
|
private val DEFAULT_DURATION = 300.milliseconds
|
||||||
|
val TO_GONE_DURATION = 250.milliseconds
|
||||||
|
val TO_GONE_SHORT_DURATION = 200.milliseconds
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,9 @@ import com.android.systemui.keyguard.shared.model.DozeStateModel.Companion.isDoz
|
|||||||
import com.android.systemui.keyguard.shared.model.DozeTransitionModel
|
import com.android.systemui.keyguard.shared.model.DozeTransitionModel
|
||||||
import com.android.systemui.keyguard.shared.model.StatusBarState
|
import com.android.systemui.keyguard.shared.model.StatusBarState
|
||||||
import com.android.systemui.keyguard.shared.model.WakefulnessModel
|
import com.android.systemui.keyguard.shared.model.WakefulnessModel
|
||||||
|
import com.android.systemui.keyguard.shared.model.WakefulnessModel.Companion.isWakingOrStartingToWake
|
||||||
import com.android.systemui.statusbar.CommandQueue
|
import com.android.systemui.statusbar.CommandQueue
|
||||||
|
import com.android.systemui.util.kotlin.sample
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlinx.coroutines.channels.awaitClose
|
import kotlinx.coroutines.channels.awaitClose
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
@@ -95,6 +97,9 @@ constructor(
|
|||||||
awaitClose { commandQueue.removeCallback(callback) }
|
awaitClose { commandQueue.removeCallback(callback) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** The device wake/sleep state */
|
||||||
|
val wakefulnessModel: Flow<WakefulnessModel> = repository.wakefulness
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dozing and dreaming have overlapping events. If the doze state remains in FINISH, it means
|
* Dozing and dreaming have overlapping events. If the doze state remains in FINISH, it means
|
||||||
* that doze mode is not running and DREAMING is ok to commence.
|
* that doze mode is not running and DREAMING is ok to commence.
|
||||||
@@ -109,6 +114,12 @@ constructor(
|
|||||||
isDreaming && isDozeOff(dozeTransitionModel.to)
|
isDreaming && isDozeOff(dozeTransitionModel.to)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
.sample(
|
||||||
|
wakefulnessModel,
|
||||||
|
{ isAbleToDream, wakefulnessModel ->
|
||||||
|
isAbleToDream && isWakingOrStartingToWake(wakefulnessModel)
|
||||||
|
}
|
||||||
|
)
|
||||||
.flatMapLatest { isAbleToDream ->
|
.flatMapLatest { isAbleToDream ->
|
||||||
flow {
|
flow {
|
||||||
delay(50)
|
delay(50)
|
||||||
@@ -119,6 +130,8 @@ constructor(
|
|||||||
|
|
||||||
/** Whether the keyguard is showing or not. */
|
/** Whether the keyguard is showing or not. */
|
||||||
val isKeyguardShowing: Flow<Boolean> = repository.isKeyguardShowing
|
val isKeyguardShowing: Flow<Boolean> = repository.isKeyguardShowing
|
||||||
|
/** Whether the keyguard is unlocked or not. */
|
||||||
|
val isKeyguardUnlocked: Flow<Boolean> = repository.isKeyguardUnlocked
|
||||||
/** Whether the keyguard is occluded (covered by an activity). */
|
/** Whether the keyguard is occluded (covered by an activity). */
|
||||||
val isKeyguardOccluded: Flow<Boolean> = repository.isKeyguardOccluded
|
val isKeyguardOccluded: Flow<Boolean> = repository.isKeyguardOccluded
|
||||||
/** Whether the keyguard is going away. */
|
/** Whether the keyguard is going away. */
|
||||||
@@ -127,8 +140,6 @@ constructor(
|
|||||||
val primaryBouncerShowing: Flow<Boolean> = bouncerRepository.primaryBouncerVisible
|
val primaryBouncerShowing: Flow<Boolean> = bouncerRepository.primaryBouncerVisible
|
||||||
/** Whether the alternate bouncer is showing or not. */
|
/** Whether the alternate bouncer is showing or not. */
|
||||||
val alternateBouncerShowing: Flow<Boolean> = bouncerRepository.alternateBouncerVisible
|
val alternateBouncerShowing: Flow<Boolean> = bouncerRepository.alternateBouncerVisible
|
||||||
/** The device wake/sleep state */
|
|
||||||
val wakefulnessModel: Flow<WakefulnessModel> = repository.wakefulness
|
|
||||||
/** Observable for the [StatusBarState] */
|
/** Observable for the [StatusBarState] */
|
||||||
val statusBarState: Flow<StatusBarState> = repository.statusBarState
|
val statusBarState: Flow<StatusBarState> = repository.statusBarState
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -61,7 +61,15 @@ constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
scope.launch {
|
scope.launch {
|
||||||
keyguardInteractor.isDreaming.collect { logger.log(TAG, VERBOSE, "isDreaming", it) }
|
keyguardInteractor.isAbleToDream.collect {
|
||||||
|
logger.log(TAG, VERBOSE, "isAbleToDream", it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scope.launch {
|
||||||
|
keyguardInteractor.isKeyguardOccluded.collect {
|
||||||
|
logger.log(TAG, VERBOSE, "isOccluded", it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scope.launch {
|
scope.launch {
|
||||||
|
|||||||
@@ -78,6 +78,10 @@ constructor(
|
|||||||
val occludedToLockscreenTransition: Flow<TransitionStep> =
|
val occludedToLockscreenTransition: Flow<TransitionStep> =
|
||||||
repository.transition(OCCLUDED, LOCKSCREEN)
|
repository.transition(OCCLUDED, LOCKSCREEN)
|
||||||
|
|
||||||
|
/** PRIMARY_BOUNCER->GONE transition information. */
|
||||||
|
val primaryBouncerToGoneTransition: Flow<TransitionStep> =
|
||||||
|
repository.transition(PRIMARY_BOUNCER, GONE)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AOD<->LOCKSCREEN transition information, mapped to dozeAmount range of AOD (1f) <->
|
* AOD<->LOCKSCREEN transition information, mapped to dozeAmount range of AOD (1f) <->
|
||||||
* Lockscreen (0f).
|
* Lockscreen (0f).
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import com.android.settingslib.Utils
|
|||||||
import com.android.systemui.keyguard.data.BouncerViewDelegate
|
import com.android.systemui.keyguard.data.BouncerViewDelegate
|
||||||
import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.EXPANSION_VISIBLE
|
import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.EXPANSION_VISIBLE
|
||||||
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel
|
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel
|
||||||
|
import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel
|
||||||
import com.android.systemui.lifecycle.repeatWhenAttached
|
import com.android.systemui.lifecycle.repeatWhenAttached
|
||||||
import com.android.systemui.plugins.ActivityStarter
|
import com.android.systemui.plugins.ActivityStarter
|
||||||
import kotlinx.coroutines.awaitCancellation
|
import kotlinx.coroutines.awaitCancellation
|
||||||
@@ -44,6 +45,7 @@ object KeyguardBouncerViewBinder {
|
|||||||
fun bind(
|
fun bind(
|
||||||
view: ViewGroup,
|
view: ViewGroup,
|
||||||
viewModel: KeyguardBouncerViewModel,
|
viewModel: KeyguardBouncerViewModel,
|
||||||
|
primaryBouncerToGoneTransitionViewModel: PrimaryBouncerToGoneTransitionViewModel,
|
||||||
componentFactory: KeyguardBouncerComponent.Factory
|
componentFactory: KeyguardBouncerComponent.Factory
|
||||||
) {
|
) {
|
||||||
// Builds the KeyguardSecurityContainerController from bouncer view group.
|
// Builds the KeyguardSecurityContainerController from bouncer view group.
|
||||||
@@ -144,6 +146,12 @@ object KeyguardBouncerViewBinder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
launch {
|
||||||
|
primaryBouncerToGoneTransitionViewModel.bouncerAlpha.collect { alpha ->
|
||||||
|
securityContainerController.setAlpha(alpha)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
launch {
|
launch {
|
||||||
viewModel.bouncerExpansionAmount
|
viewModel.bouncerExpansionAmount
|
||||||
.filter { it == EXPANSION_VISIBLE }
|
.filter { it == EXPANSION_VISIBLE }
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* 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.ui.viewmodel
|
||||||
|
|
||||||
|
import com.android.systemui.animation.Interpolators.EMPHASIZED_ACCELERATE
|
||||||
|
import com.android.systemui.dagger.SysUISingleton
|
||||||
|
import com.android.systemui.keyguard.domain.interactor.FromPrimaryBouncerTransitionInteractor.Companion.TO_GONE_DURATION
|
||||||
|
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
|
||||||
|
import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
|
||||||
|
import javax.inject.Inject
|
||||||
|
import kotlin.time.Duration.Companion.milliseconds
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Breaks down PRIMARY_BOUNCER->GONE transition into discrete steps for corresponding views to
|
||||||
|
* consume.
|
||||||
|
*/
|
||||||
|
@SysUISingleton
|
||||||
|
class PrimaryBouncerToGoneTransitionViewModel
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
|
private val interactor: KeyguardTransitionInteractor,
|
||||||
|
) {
|
||||||
|
private val transitionAnimation =
|
||||||
|
KeyguardTransitionAnimationFlow(
|
||||||
|
transitionDuration = TO_GONE_DURATION,
|
||||||
|
transitionFlow = interactor.primaryBouncerToGoneTransition,
|
||||||
|
)
|
||||||
|
|
||||||
|
/** Bouncer container alpha */
|
||||||
|
val bouncerAlpha: Flow<Float> =
|
||||||
|
transitionAnimation.createFlow(
|
||||||
|
duration = 200.milliseconds,
|
||||||
|
onStep = { 1f - it },
|
||||||
|
)
|
||||||
|
|
||||||
|
/** Scrim alpha */
|
||||||
|
val scrimAlpha: Flow<Float> =
|
||||||
|
transitionAnimation.createFlow(
|
||||||
|
duration = TO_GONE_DURATION,
|
||||||
|
interpolator = EMPHASIZED_ACCELERATE,
|
||||||
|
onStep = { 1f - it },
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -45,6 +45,7 @@ import com.android.systemui.keyguard.shared.model.TransitionState;
|
|||||||
import com.android.systemui.keyguard.shared.model.TransitionStep;
|
import com.android.systemui.keyguard.shared.model.TransitionStep;
|
||||||
import com.android.systemui.keyguard.ui.binder.KeyguardBouncerViewBinder;
|
import com.android.systemui.keyguard.ui.binder.KeyguardBouncerViewBinder;
|
||||||
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel;
|
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel;
|
||||||
|
import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel;
|
||||||
import com.android.systemui.statusbar.DragDownHelper;
|
import com.android.systemui.statusbar.DragDownHelper;
|
||||||
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
|
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
|
||||||
import com.android.systemui.statusbar.NotificationInsetsController;
|
import com.android.systemui.statusbar.NotificationInsetsController;
|
||||||
@@ -133,7 +134,8 @@ public class NotificationShadeWindowViewController {
|
|||||||
KeyguardBouncerViewModel keyguardBouncerViewModel,
|
KeyguardBouncerViewModel keyguardBouncerViewModel,
|
||||||
KeyguardBouncerComponent.Factory keyguardBouncerComponentFactory,
|
KeyguardBouncerComponent.Factory keyguardBouncerComponentFactory,
|
||||||
AlternateBouncerInteractor alternateBouncerInteractor,
|
AlternateBouncerInteractor alternateBouncerInteractor,
|
||||||
KeyguardTransitionInteractor keyguardTransitionInteractor
|
KeyguardTransitionInteractor keyguardTransitionInteractor,
|
||||||
|
PrimaryBouncerToGoneTransitionViewModel primaryBouncerToGoneTransitionViewModel
|
||||||
) {
|
) {
|
||||||
mLockscreenShadeTransitionController = transitionController;
|
mLockscreenShadeTransitionController = transitionController;
|
||||||
mFalsingCollector = falsingCollector;
|
mFalsingCollector = falsingCollector;
|
||||||
@@ -160,6 +162,7 @@ public class NotificationShadeWindowViewController {
|
|||||||
KeyguardBouncerViewBinder.bind(
|
KeyguardBouncerViewBinder.bind(
|
||||||
mView.findViewById(R.id.keyguard_bouncer_container),
|
mView.findViewById(R.id.keyguard_bouncer_container),
|
||||||
keyguardBouncerViewModel,
|
keyguardBouncerViewModel,
|
||||||
|
primaryBouncerToGoneTransitionViewModel,
|
||||||
keyguardBouncerComponentFactory);
|
keyguardBouncerComponentFactory);
|
||||||
|
|
||||||
collectFlow(mView, keyguardTransitionInteractor.getLockscreenToDreamingTransition(),
|
collectFlow(mView, keyguardTransitionInteractor.getLockscreenToDreamingTransition(),
|
||||||
|
|||||||
@@ -3695,6 +3695,12 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
|
|||||||
@Override
|
@Override
|
||||||
public void notifyBiometricAuthModeChanged() {
|
public void notifyBiometricAuthModeChanged() {
|
||||||
mDozeServiceHost.updateDozing();
|
mDozeServiceHost.updateDozing();
|
||||||
|
if (mBiometricUnlockController.getMode()
|
||||||
|
== BiometricUnlockController.MODE_DISMISS_BOUNCER) {
|
||||||
|
// Don't update the scrim controller at this time, in favor of the transition repository
|
||||||
|
// updating the scrim
|
||||||
|
return;
|
||||||
|
}
|
||||||
updateScrimController();
|
updateScrimController();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package com.android.systemui.statusbar.phone;
|
package com.android.systemui.statusbar.phone;
|
||||||
|
|
||||||
|
import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;
|
||||||
|
|
||||||
import static java.lang.Float.isNaN;
|
import static java.lang.Float.isNaN;
|
||||||
|
|
||||||
import android.animation.Animator;
|
import android.animation.Animator;
|
||||||
@@ -53,7 +55,11 @@ import com.android.systemui.dagger.SysUISingleton;
|
|||||||
import com.android.systemui.dagger.qualifiers.Main;
|
import com.android.systemui.dagger.qualifiers.Main;
|
||||||
import com.android.systemui.dock.DockManager;
|
import com.android.systemui.dock.DockManager;
|
||||||
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
||||||
|
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
|
||||||
import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants;
|
import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants;
|
||||||
|
import com.android.systemui.keyguard.shared.model.TransitionState;
|
||||||
|
import com.android.systemui.keyguard.shared.model.TransitionStep;
|
||||||
|
import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel;
|
||||||
import com.android.systemui.scrim.ScrimView;
|
import com.android.systemui.scrim.ScrimView;
|
||||||
import com.android.systemui.shade.NotificationPanelViewController;
|
import com.android.systemui.shade.NotificationPanelViewController;
|
||||||
import com.android.systemui.statusbar.notification.stack.ViewState;
|
import com.android.systemui.statusbar.notification.stack.ViewState;
|
||||||
@@ -71,6 +77,8 @@ import java.util.function.Consumer;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import kotlinx.coroutines.CoroutineDispatcher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controls both the scrim behind the notifications and in front of the notifications (when a
|
* Controls both the scrim behind the notifications and in front of the notifications (when a
|
||||||
* security method gets shown).
|
* security method gets shown).
|
||||||
@@ -251,6 +259,28 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
|
|||||||
private boolean mWakeLockHeld;
|
private boolean mWakeLockHeld;
|
||||||
private boolean mKeyguardOccluded;
|
private boolean mKeyguardOccluded;
|
||||||
|
|
||||||
|
private KeyguardTransitionInteractor mKeyguardTransitionInteractor;
|
||||||
|
private CoroutineDispatcher mMainDispatcher;
|
||||||
|
private boolean mIsBouncerToGoneTransitionStarted = false;
|
||||||
|
private boolean mIsBouncerToGoneTransitionRunning = false;
|
||||||
|
private PrimaryBouncerToGoneTransitionViewModel mPrimaryBouncerToGoneTransitionViewModel;
|
||||||
|
private final Consumer<Float> mScrimAlphaConsumer =
|
||||||
|
(Float alpha) -> {
|
||||||
|
mScrimInFront.setViewAlpha(0f);
|
||||||
|
mNotificationsScrim.setViewAlpha(0f);
|
||||||
|
mScrimBehind.setViewAlpha(alpha);
|
||||||
|
};
|
||||||
|
final Consumer<TransitionStep> mPrimaryBouncerToGoneTransition =
|
||||||
|
(TransitionStep step) -> {
|
||||||
|
mIsBouncerToGoneTransitionRunning =
|
||||||
|
step.getTransitionState() == TransitionState.RUNNING;
|
||||||
|
mIsBouncerToGoneTransitionStarted =
|
||||||
|
step.getTransitionState() == TransitionState.STARTED;
|
||||||
|
if (mIsBouncerToGoneTransitionStarted) {
|
||||||
|
transitionTo(ScrimState.UNLOCKED);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ScrimController(
|
public ScrimController(
|
||||||
LightBarController lightBarController,
|
LightBarController lightBarController,
|
||||||
@@ -265,7 +295,10 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
|
|||||||
@Main Executor mainExecutor,
|
@Main Executor mainExecutor,
|
||||||
ScreenOffAnimationController screenOffAnimationController,
|
ScreenOffAnimationController screenOffAnimationController,
|
||||||
KeyguardUnlockAnimationController keyguardUnlockAnimationController,
|
KeyguardUnlockAnimationController keyguardUnlockAnimationController,
|
||||||
StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
|
StatusBarKeyguardViewManager statusBarKeyguardViewManager,
|
||||||
|
PrimaryBouncerToGoneTransitionViewModel primaryBouncerToGoneTransitionViewModel,
|
||||||
|
KeyguardTransitionInteractor keyguardTransitionInteractor,
|
||||||
|
@Main CoroutineDispatcher mainDispatcher) {
|
||||||
mScrimStateListener = lightBarController::setScrimState;
|
mScrimStateListener = lightBarController::setScrimState;
|
||||||
mDefaultScrimAlpha = BUSY_SCRIM_ALPHA;
|
mDefaultScrimAlpha = BUSY_SCRIM_ALPHA;
|
||||||
|
|
||||||
@@ -304,6 +337,9 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
mColors = new GradientColors();
|
mColors = new GradientColors();
|
||||||
|
mPrimaryBouncerToGoneTransitionViewModel = primaryBouncerToGoneTransitionViewModel;
|
||||||
|
mKeyguardTransitionInteractor = keyguardTransitionInteractor;
|
||||||
|
mMainDispatcher = mainDispatcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -343,6 +379,11 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
|
|||||||
for (ScrimState state : ScrimState.values()) {
|
for (ScrimState state : ScrimState.values()) {
|
||||||
state.prepare(state);
|
state.prepare(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
collectFlow(behindScrim, mKeyguardTransitionInteractor.getPrimaryBouncerToGoneTransition(),
|
||||||
|
mPrimaryBouncerToGoneTransition, mMainDispatcher);
|
||||||
|
collectFlow(behindScrim, mPrimaryBouncerToGoneTransitionViewModel.getScrimAlpha(),
|
||||||
|
mScrimAlphaConsumer, mMainDispatcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -365,6 +406,11 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void transitionTo(ScrimState state, Callback callback) {
|
public void transitionTo(ScrimState state, Callback callback) {
|
||||||
|
if (mIsBouncerToGoneTransitionRunning) {
|
||||||
|
Log.i(TAG, "Skipping transition to: " + state
|
||||||
|
+ " while mIsBouncerToGoneTransitionRunning");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (state == mState) {
|
if (state == mState) {
|
||||||
// Call the callback anyway, unless it's already enqueued
|
// Call the callback anyway, unless it's already enqueued
|
||||||
if (callback != null && mCallback != callback) {
|
if (callback != null && mCallback != callback) {
|
||||||
@@ -784,10 +830,11 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
|
|||||||
mBehindAlpha = 0;
|
mBehindAlpha = 0;
|
||||||
mNotificationsAlpha = 0;
|
mNotificationsAlpha = 0;
|
||||||
} else {
|
} else {
|
||||||
// Behind scrim will finish fading in at 30% expansion.
|
|
||||||
float behindFraction = MathUtils
|
float behindFraction = MathUtils
|
||||||
.constrainedMap(0f, 1f, 0f, 0.3f, mPanelExpansionFraction);
|
.constrainedMap(0f, 1f, 0f, 0.3f, mPanelExpansionFraction);
|
||||||
mBehindAlpha = behindFraction * mDefaultScrimAlpha;
|
if (!mIsBouncerToGoneTransitionStarted) {
|
||||||
|
mBehindAlpha = behindFraction * mDefaultScrimAlpha;
|
||||||
|
}
|
||||||
// Delay fade-in of notification scrim a bit further, to coincide with the
|
// Delay fade-in of notification scrim a bit further, to coincide with the
|
||||||
// behind scrim finishing fading in.
|
// behind scrim finishing fading in.
|
||||||
// Also to coincide with the view starting to fade in, otherwise the empty
|
// Also to coincide with the view starting to fade in, otherwise the empty
|
||||||
@@ -1125,7 +1172,9 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
|
|||||||
Trace.traceCounter(Trace.TRACE_TAG_APP, getScrimName(scrimView) + "_tint",
|
Trace.traceCounter(Trace.TRACE_TAG_APP, getScrimName(scrimView) + "_tint",
|
||||||
Color.alpha(tint));
|
Color.alpha(tint));
|
||||||
scrimView.setTint(tint);
|
scrimView.setTint(tint);
|
||||||
scrimView.setViewAlpha(alpha);
|
if (!mIsBouncerToGoneTransitionRunning) {
|
||||||
|
scrimView.setViewAlpha(alpha);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
scrim.setAlpha(alpha);
|
scrim.setAlpha(alpha);
|
||||||
}
|
}
|
||||||
@@ -1473,6 +1522,9 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setKeyguardOccluded(boolean keyguardOccluded) {
|
public void setKeyguardOccluded(boolean keyguardOccluded) {
|
||||||
|
if (mKeyguardOccluded == keyguardOccluded) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
mKeyguardOccluded = keyguardOccluded;
|
mKeyguardOccluded = keyguardOccluded;
|
||||||
updateScrims();
|
updateScrims();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -218,6 +218,29 @@ class KeyguardRepositoryImplTest : SysuiTestCase() {
|
|||||||
job.cancel()
|
job.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun isKeyguardUnlocked() =
|
||||||
|
runTest(UnconfinedTestDispatcher()) {
|
||||||
|
whenever(keyguardStateController.isUnlocked).thenReturn(false)
|
||||||
|
var latest: Boolean? = null
|
||||||
|
val job = underTest.isKeyguardUnlocked.onEach { latest = it }.launchIn(this)
|
||||||
|
|
||||||
|
assertThat(latest).isFalse()
|
||||||
|
|
||||||
|
val captor = argumentCaptor<KeyguardStateController.Callback>()
|
||||||
|
verify(keyguardStateController).addCallback(captor.capture())
|
||||||
|
|
||||||
|
whenever(keyguardStateController.isUnlocked).thenReturn(true)
|
||||||
|
captor.value.onUnlockedChanged()
|
||||||
|
assertThat(latest).isTrue()
|
||||||
|
|
||||||
|
whenever(keyguardStateController.isUnlocked).thenReturn(false)
|
||||||
|
captor.value.onUnlockedChanged()
|
||||||
|
assertThat(latest).isFalse()
|
||||||
|
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun isDozing() =
|
fun isDozing() =
|
||||||
runTest(UnconfinedTestDispatcher()) {
|
runTest(UnconfinedTestDispatcher()) {
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ package com.android.systemui.keyguard.domain.interactor
|
|||||||
import android.animation.ValueAnimator
|
import android.animation.ValueAnimator
|
||||||
import androidx.test.filters.FlakyTest
|
import androidx.test.filters.FlakyTest
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
|
import com.android.keyguard.KeyguardSecurityModel
|
||||||
|
import com.android.keyguard.KeyguardSecurityModel.SecurityMode.PIN
|
||||||
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
|
||||||
@@ -40,6 +42,7 @@ import com.android.systemui.keyguard.util.KeyguardTransitionRunner
|
|||||||
import com.android.systemui.shade.data.repository.FakeShadeRepository
|
import com.android.systemui.shade.data.repository.FakeShadeRepository
|
||||||
import com.android.systemui.shade.data.repository.ShadeRepository
|
import com.android.systemui.shade.data.repository.ShadeRepository
|
||||||
import com.android.systemui.statusbar.CommandQueue
|
import com.android.systemui.statusbar.CommandQueue
|
||||||
|
import com.android.systemui.util.mockito.whenever
|
||||||
import com.android.systemui.util.mockito.withArgCaptor
|
import com.android.systemui.util.mockito.withArgCaptor
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import kotlinx.coroutines.cancelChildren
|
import kotlinx.coroutines.cancelChildren
|
||||||
@@ -51,6 +54,8 @@ import org.junit.Before
|
|||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.junit.runners.JUnit4
|
import org.junit.runners.JUnit4
|
||||||
|
import org.mockito.ArgumentMatchers.anyBoolean
|
||||||
|
import org.mockito.ArgumentMatchers.anyInt
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
import org.mockito.Mockito.reset
|
import org.mockito.Mockito.reset
|
||||||
import org.mockito.Mockito.verify
|
import org.mockito.Mockito.verify
|
||||||
@@ -77,6 +82,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
|||||||
// Used to verify transition requests for test output
|
// Used to verify transition requests for test output
|
||||||
@Mock private lateinit var mockTransitionRepository: KeyguardTransitionRepository
|
@Mock private lateinit var mockTransitionRepository: KeyguardTransitionRepository
|
||||||
@Mock private lateinit var commandQueue: CommandQueue
|
@Mock private lateinit var commandQueue: CommandQueue
|
||||||
|
@Mock private lateinit var keyguardSecurityModel: KeyguardSecurityModel
|
||||||
|
|
||||||
private lateinit var fromLockscreenTransitionInteractor: FromLockscreenTransitionInteractor
|
private lateinit var fromLockscreenTransitionInteractor: FromLockscreenTransitionInteractor
|
||||||
private lateinit var fromDreamingTransitionInteractor: FromDreamingTransitionInteractor
|
private lateinit var fromDreamingTransitionInteractor: FromDreamingTransitionInteractor
|
||||||
@@ -102,6 +108,8 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
|||||||
transitionRepository = KeyguardTransitionRepositoryImpl()
|
transitionRepository = KeyguardTransitionRepositoryImpl()
|
||||||
runner = KeyguardTransitionRunner(transitionRepository)
|
runner = KeyguardTransitionRunner(transitionRepository)
|
||||||
|
|
||||||
|
whenever(keyguardSecurityModel.getSecurityMode(anyInt())).thenReturn(PIN)
|
||||||
|
|
||||||
val featureFlags = FakeFeatureFlags().apply { set(Flags.FACE_AUTH_REFACTOR, true) }
|
val featureFlags = FakeFeatureFlags().apply { set(Flags.FACE_AUTH_REFACTOR, true) }
|
||||||
fromLockscreenTransitionInteractor =
|
fromLockscreenTransitionInteractor =
|
||||||
FromLockscreenTransitionInteractor(
|
FromLockscreenTransitionInteractor(
|
||||||
@@ -173,16 +181,17 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
|||||||
keyguardInteractor = createKeyguardInteractor(featureFlags),
|
keyguardInteractor = createKeyguardInteractor(featureFlags),
|
||||||
keyguardTransitionRepository = mockTransitionRepository,
|
keyguardTransitionRepository = mockTransitionRepository,
|
||||||
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
|
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
|
||||||
|
keyguardSecurityModel = keyguardSecurityModel,
|
||||||
)
|
)
|
||||||
fromPrimaryBouncerTransitionInteractor.start()
|
fromPrimaryBouncerTransitionInteractor.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `DREAMING to LOCKSCREEN - dreaming state changes first`() =
|
fun `DREAMING to LOCKSCREEN`() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
// GIVEN a device is dreaming and occluded
|
// GIVEN a device is dreaming
|
||||||
keyguardRepository.setDreamingWithOverlay(true)
|
keyguardRepository.setDreamingWithOverlay(true)
|
||||||
keyguardRepository.setKeyguardOccluded(true)
|
keyguardRepository.setWakefulnessModel(startingToWake())
|
||||||
runCurrent()
|
runCurrent()
|
||||||
|
|
||||||
// GIVEN a prior transition has run to DREAMING
|
// GIVEN a prior transition has run to DREAMING
|
||||||
@@ -215,56 +224,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
|||||||
|
|
||||||
val info =
|
val info =
|
||||||
withArgCaptor<TransitionInfo> {
|
withArgCaptor<TransitionInfo> {
|
||||||
verify(mockTransitionRepository).startTransition(capture())
|
verify(mockTransitionRepository).startTransition(capture(), anyBoolean())
|
||||||
}
|
|
||||||
// THEN a transition to BOUNCER should occur
|
|
||||||
assertThat(info.ownerName).isEqualTo("FromDreamingTransitionInteractor")
|
|
||||||
assertThat(info.from).isEqualTo(KeyguardState.DREAMING)
|
|
||||||
assertThat(info.to).isEqualTo(KeyguardState.LOCKSCREEN)
|
|
||||||
assertThat(info.animator).isNotNull()
|
|
||||||
|
|
||||||
coroutineContext.cancelChildren()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `DREAMING to LOCKSCREEN - occluded state changes first`() =
|
|
||||||
testScope.runTest {
|
|
||||||
// GIVEN a device is dreaming and occluded
|
|
||||||
keyguardRepository.setDreamingWithOverlay(true)
|
|
||||||
keyguardRepository.setKeyguardOccluded(true)
|
|
||||||
runCurrent()
|
|
||||||
|
|
||||||
// GIVEN a prior transition has run to DREAMING
|
|
||||||
runner.startTransition(
|
|
||||||
testScope,
|
|
||||||
TransitionInfo(
|
|
||||||
ownerName = "",
|
|
||||||
from = KeyguardState.LOCKSCREEN,
|
|
||||||
to = KeyguardState.DREAMING,
|
|
||||||
animator =
|
|
||||||
ValueAnimator().apply {
|
|
||||||
duration = 10
|
|
||||||
interpolator = Interpolators.LINEAR
|
|
||||||
},
|
|
||||||
)
|
|
||||||
)
|
|
||||||
runCurrent()
|
|
||||||
reset(mockTransitionRepository)
|
|
||||||
|
|
||||||
// WHEN doze is complete
|
|
||||||
keyguardRepository.setDozeTransitionModel(
|
|
||||||
DozeTransitionModel(from = DozeStateModel.DOZE, to = DozeStateModel.FINISH)
|
|
||||||
)
|
|
||||||
// AND occluded has stopped
|
|
||||||
keyguardRepository.setKeyguardOccluded(false)
|
|
||||||
advanceUntilIdle()
|
|
||||||
// AND then dreaming has stopped
|
|
||||||
keyguardRepository.setDreamingWithOverlay(false)
|
|
||||||
advanceUntilIdle()
|
|
||||||
|
|
||||||
val info =
|
|
||||||
withArgCaptor<TransitionInfo> {
|
|
||||||
verify(mockTransitionRepository).startTransition(capture())
|
|
||||||
}
|
}
|
||||||
// THEN a transition to BOUNCER should occur
|
// THEN a transition to BOUNCER should occur
|
||||||
assertThat(info.ownerName).isEqualTo("FromDreamingTransitionInteractor")
|
assertThat(info.ownerName).isEqualTo("FromDreamingTransitionInteractor")
|
||||||
@@ -304,7 +264,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
|||||||
|
|
||||||
val info =
|
val info =
|
||||||
withArgCaptor<TransitionInfo> {
|
withArgCaptor<TransitionInfo> {
|
||||||
verify(mockTransitionRepository).startTransition(capture())
|
verify(mockTransitionRepository).startTransition(capture(), anyBoolean())
|
||||||
}
|
}
|
||||||
// THEN a transition to PRIMARY_BOUNCER should occur
|
// THEN a transition to PRIMARY_BOUNCER should occur
|
||||||
assertThat(info.ownerName).isEqualTo("FromLockscreenTransitionInteractor")
|
assertThat(info.ownerName).isEqualTo("FromLockscreenTransitionInteractor")
|
||||||
@@ -345,7 +305,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
|||||||
|
|
||||||
val info =
|
val info =
|
||||||
withArgCaptor<TransitionInfo> {
|
withArgCaptor<TransitionInfo> {
|
||||||
verify(mockTransitionRepository).startTransition(capture())
|
verify(mockTransitionRepository).startTransition(capture(), anyBoolean())
|
||||||
}
|
}
|
||||||
// THEN a transition to DOZING should occur
|
// THEN a transition to DOZING should occur
|
||||||
assertThat(info.ownerName).isEqualTo("FromOccludedTransitionInteractor")
|
assertThat(info.ownerName).isEqualTo("FromOccludedTransitionInteractor")
|
||||||
@@ -386,7 +346,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
|||||||
|
|
||||||
val info =
|
val info =
|
||||||
withArgCaptor<TransitionInfo> {
|
withArgCaptor<TransitionInfo> {
|
||||||
verify(mockTransitionRepository).startTransition(capture())
|
verify(mockTransitionRepository).startTransition(capture(), anyBoolean())
|
||||||
}
|
}
|
||||||
// THEN a transition to DOZING should occur
|
// THEN a transition to DOZING should occur
|
||||||
assertThat(info.ownerName).isEqualTo("FromOccludedTransitionInteractor")
|
assertThat(info.ownerName).isEqualTo("FromOccludedTransitionInteractor")
|
||||||
@@ -427,7 +387,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
|||||||
|
|
||||||
val info =
|
val info =
|
||||||
withArgCaptor<TransitionInfo> {
|
withArgCaptor<TransitionInfo> {
|
||||||
verify(mockTransitionRepository).startTransition(capture())
|
verify(mockTransitionRepository).startTransition(capture(), anyBoolean())
|
||||||
}
|
}
|
||||||
// THEN a transition to DOZING should occur
|
// THEN a transition to DOZING should occur
|
||||||
assertThat(info.ownerName).isEqualTo("FromLockscreenTransitionInteractor")
|
assertThat(info.ownerName).isEqualTo("FromLockscreenTransitionInteractor")
|
||||||
@@ -468,7 +428,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
|||||||
|
|
||||||
val info =
|
val info =
|
||||||
withArgCaptor<TransitionInfo> {
|
withArgCaptor<TransitionInfo> {
|
||||||
verify(mockTransitionRepository).startTransition(capture())
|
verify(mockTransitionRepository).startTransition(capture(), anyBoolean())
|
||||||
}
|
}
|
||||||
// THEN a transition to DOZING should occur
|
// THEN a transition to DOZING should occur
|
||||||
assertThat(info.ownerName).isEqualTo("FromLockscreenTransitionInteractor")
|
assertThat(info.ownerName).isEqualTo("FromLockscreenTransitionInteractor")
|
||||||
@@ -505,7 +465,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
|||||||
|
|
||||||
val info =
|
val info =
|
||||||
withArgCaptor<TransitionInfo> {
|
withArgCaptor<TransitionInfo> {
|
||||||
verify(mockTransitionRepository).startTransition(capture())
|
verify(mockTransitionRepository).startTransition(capture(), anyBoolean())
|
||||||
}
|
}
|
||||||
// THEN a transition to DOZING should occur
|
// THEN a transition to DOZING should occur
|
||||||
assertThat(info.ownerName).isEqualTo("FromDozingTransitionInteractor")
|
assertThat(info.ownerName).isEqualTo("FromDozingTransitionInteractor")
|
||||||
@@ -542,7 +502,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
|||||||
|
|
||||||
val info =
|
val info =
|
||||||
withArgCaptor<TransitionInfo> {
|
withArgCaptor<TransitionInfo> {
|
||||||
verify(mockTransitionRepository).startTransition(capture())
|
verify(mockTransitionRepository).startTransition(capture(), anyBoolean())
|
||||||
}
|
}
|
||||||
// THEN a transition to DOZING should occur
|
// THEN a transition to DOZING should occur
|
||||||
assertThat(info.ownerName).isEqualTo("FromDozingTransitionInteractor")
|
assertThat(info.ownerName).isEqualTo("FromDozingTransitionInteractor")
|
||||||
@@ -583,7 +543,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
|||||||
|
|
||||||
val info =
|
val info =
|
||||||
withArgCaptor<TransitionInfo> {
|
withArgCaptor<TransitionInfo> {
|
||||||
verify(mockTransitionRepository).startTransition(capture())
|
verify(mockTransitionRepository).startTransition(capture(), anyBoolean())
|
||||||
}
|
}
|
||||||
// THEN a transition to DOZING should occur
|
// THEN a transition to DOZING should occur
|
||||||
assertThat(info.ownerName).isEqualTo("FromGoneTransitionInteractor")
|
assertThat(info.ownerName).isEqualTo("FromGoneTransitionInteractor")
|
||||||
@@ -624,7 +584,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
|||||||
|
|
||||||
val info =
|
val info =
|
||||||
withArgCaptor<TransitionInfo> {
|
withArgCaptor<TransitionInfo> {
|
||||||
verify(mockTransitionRepository).startTransition(capture())
|
verify(mockTransitionRepository).startTransition(capture(), anyBoolean())
|
||||||
}
|
}
|
||||||
// THEN a transition to AOD should occur
|
// THEN a transition to AOD should occur
|
||||||
assertThat(info.ownerName).isEqualTo("FromGoneTransitionInteractor")
|
assertThat(info.ownerName).isEqualTo("FromGoneTransitionInteractor")
|
||||||
@@ -661,7 +621,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
|||||||
|
|
||||||
val info =
|
val info =
|
||||||
withArgCaptor<TransitionInfo> {
|
withArgCaptor<TransitionInfo> {
|
||||||
verify(mockTransitionRepository).startTransition(capture())
|
verify(mockTransitionRepository).startTransition(capture(), anyBoolean())
|
||||||
}
|
}
|
||||||
// THEN a transition to AOD should occur
|
// THEN a transition to AOD should occur
|
||||||
assertThat(info.ownerName).isEqualTo("FromGoneTransitionInteractor")
|
assertThat(info.ownerName).isEqualTo("FromGoneTransitionInteractor")
|
||||||
@@ -677,6 +637,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
// GIVEN a device that is not dreaming or dozing
|
// GIVEN a device that is not dreaming or dozing
|
||||||
keyguardRepository.setDreamingWithOverlay(false)
|
keyguardRepository.setDreamingWithOverlay(false)
|
||||||
|
keyguardRepository.setWakefulnessModel(startingToWake())
|
||||||
keyguardRepository.setDozeTransitionModel(
|
keyguardRepository.setDozeTransitionModel(
|
||||||
DozeTransitionModel(from = DozeStateModel.DOZE, to = DozeStateModel.FINISH)
|
DozeTransitionModel(from = DozeStateModel.DOZE, to = DozeStateModel.FINISH)
|
||||||
)
|
)
|
||||||
@@ -704,7 +665,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
|||||||
|
|
||||||
val info =
|
val info =
|
||||||
withArgCaptor<TransitionInfo> {
|
withArgCaptor<TransitionInfo> {
|
||||||
verify(mockTransitionRepository).startTransition(capture())
|
verify(mockTransitionRepository).startTransition(capture(), anyBoolean())
|
||||||
}
|
}
|
||||||
// THEN a transition to DREAMING should occur
|
// THEN a transition to DREAMING should occur
|
||||||
assertThat(info.ownerName).isEqualTo("FromGoneTransitionInteractor")
|
assertThat(info.ownerName).isEqualTo("FromGoneTransitionInteractor")
|
||||||
@@ -741,7 +702,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
|||||||
|
|
||||||
val info =
|
val info =
|
||||||
withArgCaptor<TransitionInfo> {
|
withArgCaptor<TransitionInfo> {
|
||||||
verify(mockTransitionRepository).startTransition(capture())
|
verify(mockTransitionRepository).startTransition(capture(), anyBoolean())
|
||||||
}
|
}
|
||||||
// THEN a transition to PRIMARY_BOUNCER should occur
|
// THEN a transition to PRIMARY_BOUNCER should occur
|
||||||
assertThat(info.ownerName).isEqualTo("FromAlternateBouncerTransitionInteractor")
|
assertThat(info.ownerName).isEqualTo("FromAlternateBouncerTransitionInteractor")
|
||||||
@@ -784,7 +745,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
|||||||
|
|
||||||
val info =
|
val info =
|
||||||
withArgCaptor<TransitionInfo> {
|
withArgCaptor<TransitionInfo> {
|
||||||
verify(mockTransitionRepository).startTransition(capture())
|
verify(mockTransitionRepository).startTransition(capture(), anyBoolean())
|
||||||
}
|
}
|
||||||
// THEN a transition to AOD should occur
|
// THEN a transition to AOD should occur
|
||||||
assertThat(info.ownerName).isEqualTo("FromAlternateBouncerTransitionInteractor")
|
assertThat(info.ownerName).isEqualTo("FromAlternateBouncerTransitionInteractor")
|
||||||
@@ -828,7 +789,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
|||||||
|
|
||||||
val info =
|
val info =
|
||||||
withArgCaptor<TransitionInfo> {
|
withArgCaptor<TransitionInfo> {
|
||||||
verify(mockTransitionRepository).startTransition(capture())
|
verify(mockTransitionRepository).startTransition(capture(), anyBoolean())
|
||||||
}
|
}
|
||||||
// THEN a transition to DOZING should occur
|
// THEN a transition to DOZING should occur
|
||||||
assertThat(info.ownerName).isEqualTo("FromAlternateBouncerTransitionInteractor")
|
assertThat(info.ownerName).isEqualTo("FromAlternateBouncerTransitionInteractor")
|
||||||
@@ -870,7 +831,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
|||||||
|
|
||||||
val info =
|
val info =
|
||||||
withArgCaptor<TransitionInfo> {
|
withArgCaptor<TransitionInfo> {
|
||||||
verify(mockTransitionRepository).startTransition(capture())
|
verify(mockTransitionRepository).startTransition(capture(), anyBoolean())
|
||||||
}
|
}
|
||||||
// THEN a transition to LOCKSCREEN should occur
|
// THEN a transition to LOCKSCREEN should occur
|
||||||
assertThat(info.ownerName).isEqualTo("FromAlternateBouncerTransitionInteractor")
|
assertThat(info.ownerName).isEqualTo("FromAlternateBouncerTransitionInteractor")
|
||||||
@@ -912,7 +873,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
|||||||
|
|
||||||
val info =
|
val info =
|
||||||
withArgCaptor<TransitionInfo> {
|
withArgCaptor<TransitionInfo> {
|
||||||
verify(mockTransitionRepository).startTransition(capture())
|
verify(mockTransitionRepository).startTransition(capture(), anyBoolean())
|
||||||
}
|
}
|
||||||
// THEN a transition to AOD should occur
|
// THEN a transition to AOD should occur
|
||||||
assertThat(info.ownerName).isEqualTo("FromPrimaryBouncerTransitionInteractor")
|
assertThat(info.ownerName).isEqualTo("FromPrimaryBouncerTransitionInteractor")
|
||||||
@@ -954,7 +915,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
|||||||
|
|
||||||
val info =
|
val info =
|
||||||
withArgCaptor<TransitionInfo> {
|
withArgCaptor<TransitionInfo> {
|
||||||
verify(mockTransitionRepository).startTransition(capture())
|
verify(mockTransitionRepository).startTransition(capture(), anyBoolean())
|
||||||
}
|
}
|
||||||
// THEN a transition to DOZING should occur
|
// THEN a transition to DOZING should occur
|
||||||
assertThat(info.ownerName).isEqualTo("FromPrimaryBouncerTransitionInteractor")
|
assertThat(info.ownerName).isEqualTo("FromPrimaryBouncerTransitionInteractor")
|
||||||
@@ -995,7 +956,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
|||||||
|
|
||||||
val info =
|
val info =
|
||||||
withArgCaptor<TransitionInfo> {
|
withArgCaptor<TransitionInfo> {
|
||||||
verify(mockTransitionRepository).startTransition(capture())
|
verify(mockTransitionRepository).startTransition(capture(), anyBoolean())
|
||||||
}
|
}
|
||||||
// THEN a transition to LOCKSCREEN should occur
|
// THEN a transition to LOCKSCREEN should occur
|
||||||
assertThat(info.ownerName).isEqualTo("FromPrimaryBouncerTransitionInteractor")
|
assertThat(info.ownerName).isEqualTo("FromPrimaryBouncerTransitionInteractor")
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteracto
|
|||||||
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
|
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
|
||||||
import com.android.systemui.keyguard.shared.model.TransitionStep
|
import com.android.systemui.keyguard.shared.model.TransitionStep
|
||||||
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel
|
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel
|
||||||
|
import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel
|
||||||
import com.android.systemui.shade.NotificationShadeWindowView.InteractionEventHandler
|
import com.android.systemui.shade.NotificationShadeWindowView.InteractionEventHandler
|
||||||
import com.android.systemui.statusbar.LockscreenShadeTransitionController
|
import com.android.systemui.statusbar.LockscreenShadeTransitionController
|
||||||
import com.android.systemui.statusbar.NotificationInsetsController
|
import com.android.systemui.statusbar.NotificationInsetsController
|
||||||
@@ -65,48 +66,32 @@ import org.mockito.MockitoAnnotations
|
|||||||
@RunWith(AndroidTestingRunner::class)
|
@RunWith(AndroidTestingRunner::class)
|
||||||
@RunWithLooper(setAsMainLooper = true)
|
@RunWithLooper(setAsMainLooper = true)
|
||||||
class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
|
class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
|
||||||
@Mock
|
@Mock private lateinit var view: NotificationShadeWindowView
|
||||||
private lateinit var view: NotificationShadeWindowView
|
@Mock private lateinit var sysuiStatusBarStateController: SysuiStatusBarStateController
|
||||||
@Mock
|
@Mock private lateinit var centralSurfaces: CentralSurfaces
|
||||||
private lateinit var sysuiStatusBarStateController: SysuiStatusBarStateController
|
@Mock private lateinit var dockManager: DockManager
|
||||||
@Mock
|
@Mock private lateinit var notificationPanelViewController: NotificationPanelViewController
|
||||||
private lateinit var centralSurfaces: CentralSurfaces
|
@Mock private lateinit var notificationShadeDepthController: NotificationShadeDepthController
|
||||||
@Mock
|
@Mock private lateinit var notificationShadeWindowController: NotificationShadeWindowController
|
||||||
private lateinit var dockManager: DockManager
|
@Mock private lateinit var keyguardUnlockAnimationController: KeyguardUnlockAnimationController
|
||||||
@Mock
|
@Mock private lateinit var ambientState: AmbientState
|
||||||
private lateinit var notificationPanelViewController: NotificationPanelViewController
|
@Mock private lateinit var keyguardBouncerViewModel: KeyguardBouncerViewModel
|
||||||
@Mock
|
@Mock private lateinit var stackScrollLayoutController: NotificationStackScrollLayoutController
|
||||||
private lateinit var notificationShadeDepthController: NotificationShadeDepthController
|
@Mock private lateinit var statusBarKeyguardViewManager: StatusBarKeyguardViewManager
|
||||||
@Mock
|
@Mock private lateinit var statusBarWindowStateController: StatusBarWindowStateController
|
||||||
private lateinit var notificationShadeWindowController: NotificationShadeWindowController
|
|
||||||
@Mock
|
|
||||||
private lateinit var keyguardUnlockAnimationController: KeyguardUnlockAnimationController
|
|
||||||
@Mock
|
|
||||||
private lateinit var ambientState: AmbientState
|
|
||||||
@Mock
|
|
||||||
private lateinit var keyguardBouncerViewModel: KeyguardBouncerViewModel
|
|
||||||
@Mock
|
|
||||||
private lateinit var stackScrollLayoutController: NotificationStackScrollLayoutController
|
|
||||||
@Mock
|
|
||||||
private lateinit var statusBarKeyguardViewManager: StatusBarKeyguardViewManager
|
|
||||||
@Mock
|
|
||||||
private lateinit var statusBarWindowStateController: StatusBarWindowStateController
|
|
||||||
@Mock
|
@Mock
|
||||||
private lateinit var lockscreenShadeTransitionController: LockscreenShadeTransitionController
|
private lateinit var lockscreenShadeTransitionController: LockscreenShadeTransitionController
|
||||||
@Mock
|
@Mock private lateinit var lockIconViewController: LockIconViewController
|
||||||
private lateinit var lockIconViewController: LockIconViewController
|
@Mock private lateinit var phoneStatusBarViewController: PhoneStatusBarViewController
|
||||||
@Mock
|
@Mock private lateinit var pulsingGestureListener: PulsingGestureListener
|
||||||
private lateinit var phoneStatusBarViewController: PhoneStatusBarViewController
|
@Mock private lateinit var notificationInsetsController: NotificationInsetsController
|
||||||
@Mock
|
@Mock private lateinit var alternateBouncerInteractor: AlternateBouncerInteractor
|
||||||
private lateinit var pulsingGestureListener: PulsingGestureListener
|
|
||||||
@Mock
|
|
||||||
private lateinit var notificationInsetsController: NotificationInsetsController
|
|
||||||
@Mock
|
|
||||||
private lateinit var alternateBouncerInteractor: AlternateBouncerInteractor
|
|
||||||
@Mock lateinit var keyguardBouncerComponentFactory: KeyguardBouncerComponent.Factory
|
@Mock lateinit var keyguardBouncerComponentFactory: KeyguardBouncerComponent.Factory
|
||||||
@Mock lateinit var keyguardBouncerComponent: KeyguardBouncerComponent
|
@Mock lateinit var keyguardBouncerComponent: KeyguardBouncerComponent
|
||||||
@Mock lateinit var keyguardSecurityContainerController: KeyguardSecurityContainerController
|
@Mock lateinit var keyguardSecurityContainerController: KeyguardSecurityContainerController
|
||||||
@Mock lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor
|
@Mock lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor
|
||||||
|
@Mock
|
||||||
|
lateinit var primaryBouncerToGoneTransitionViewModel: PrimaryBouncerToGoneTransitionViewModel
|
||||||
|
|
||||||
private lateinit var interactionEventHandlerCaptor: ArgumentCaptor<InteractionEventHandler>
|
private lateinit var interactionEventHandlerCaptor: ArgumentCaptor<InteractionEventHandler>
|
||||||
private lateinit var interactionEventHandler: InteractionEventHandler
|
private lateinit var interactionEventHandler: InteractionEventHandler
|
||||||
@@ -118,43 +103,44 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
|
|||||||
MockitoAnnotations.initMocks(this)
|
MockitoAnnotations.initMocks(this)
|
||||||
whenever(view.bottom).thenReturn(VIEW_BOTTOM)
|
whenever(view.bottom).thenReturn(VIEW_BOTTOM)
|
||||||
whenever(view.findViewById<ViewGroup>(R.id.keyguard_bouncer_container))
|
whenever(view.findViewById<ViewGroup>(R.id.keyguard_bouncer_container))
|
||||||
.thenReturn(mock(ViewGroup::class.java))
|
.thenReturn(mock(ViewGroup::class.java))
|
||||||
whenever(keyguardBouncerComponentFactory.create(any(ViewGroup::class.java)))
|
whenever(keyguardBouncerComponentFactory.create(any(ViewGroup::class.java)))
|
||||||
.thenReturn(keyguardBouncerComponent)
|
.thenReturn(keyguardBouncerComponent)
|
||||||
whenever(keyguardBouncerComponent.securityContainerController)
|
whenever(keyguardBouncerComponent.securityContainerController)
|
||||||
.thenReturn(keyguardSecurityContainerController)
|
.thenReturn(keyguardSecurityContainerController)
|
||||||
whenever(keyguardTransitionInteractor.lockscreenToDreamingTransition)
|
whenever(keyguardTransitionInteractor.lockscreenToDreamingTransition)
|
||||||
.thenReturn(emptyFlow<TransitionStep>())
|
.thenReturn(emptyFlow<TransitionStep>())
|
||||||
underTest = NotificationShadeWindowViewController(
|
underTest =
|
||||||
lockscreenShadeTransitionController,
|
NotificationShadeWindowViewController(
|
||||||
FalsingCollectorFake(),
|
lockscreenShadeTransitionController,
|
||||||
sysuiStatusBarStateController,
|
FalsingCollectorFake(),
|
||||||
dockManager,
|
sysuiStatusBarStateController,
|
||||||
notificationShadeDepthController,
|
dockManager,
|
||||||
view,
|
notificationShadeDepthController,
|
||||||
notificationPanelViewController,
|
view,
|
||||||
ShadeExpansionStateManager(),
|
notificationPanelViewController,
|
||||||
stackScrollLayoutController,
|
ShadeExpansionStateManager(),
|
||||||
statusBarKeyguardViewManager,
|
stackScrollLayoutController,
|
||||||
statusBarWindowStateController,
|
statusBarKeyguardViewManager,
|
||||||
lockIconViewController,
|
statusBarWindowStateController,
|
||||||
centralSurfaces,
|
lockIconViewController,
|
||||||
notificationShadeWindowController,
|
centralSurfaces,
|
||||||
keyguardUnlockAnimationController,
|
notificationShadeWindowController,
|
||||||
notificationInsetsController,
|
keyguardUnlockAnimationController,
|
||||||
ambientState,
|
notificationInsetsController,
|
||||||
pulsingGestureListener,
|
ambientState,
|
||||||
keyguardBouncerViewModel,
|
pulsingGestureListener,
|
||||||
keyguardBouncerComponentFactory,
|
keyguardBouncerViewModel,
|
||||||
alternateBouncerInteractor,
|
keyguardBouncerComponentFactory,
|
||||||
keyguardTransitionInteractor,
|
alternateBouncerInteractor,
|
||||||
)
|
keyguardTransitionInteractor,
|
||||||
|
primaryBouncerToGoneTransitionViewModel,
|
||||||
|
)
|
||||||
underTest.setupExpandedStatusBar()
|
underTest.setupExpandedStatusBar()
|
||||||
|
|
||||||
interactionEventHandlerCaptor =
|
interactionEventHandlerCaptor = ArgumentCaptor.forClass(InteractionEventHandler::class.java)
|
||||||
ArgumentCaptor.forClass(InteractionEventHandler::class.java)
|
|
||||||
verify(view).setInteractionEventHandler(interactionEventHandlerCaptor.capture())
|
verify(view).setInteractionEventHandler(interactionEventHandlerCaptor.capture())
|
||||||
interactionEventHandler = interactionEventHandlerCaptor.value
|
interactionEventHandler = interactionEventHandlerCaptor.value
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: So far, these tests only cover interactions with the status bar view controller. More
|
// Note: So far, these tests only cover interactions with the status bar view controller. More
|
||||||
@@ -184,14 +170,11 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun handleDispatchTouchEvent_downTouchBelowViewThenAnotherTouch_sendsTouchToSb() {
|
fun handleDispatchTouchEvent_downTouchBelowViewThenAnotherTouch_sendsTouchToSb() {
|
||||||
underTest.setStatusBarViewController(phoneStatusBarViewController)
|
underTest.setStatusBarViewController(phoneStatusBarViewController)
|
||||||
val downEvBelow = MotionEvent.obtain(
|
val downEvBelow =
|
||||||
0L, 0L, MotionEvent.ACTION_DOWN, 0f, VIEW_BOTTOM + 4f, 0
|
MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, VIEW_BOTTOM + 4f, 0)
|
||||||
)
|
|
||||||
interactionEventHandler.handleDispatchTouchEvent(downEvBelow)
|
interactionEventHandler.handleDispatchTouchEvent(downEvBelow)
|
||||||
|
|
||||||
val nextEvent = MotionEvent.obtain(
|
val nextEvent = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, VIEW_BOTTOM + 5f, 0)
|
||||||
0L, 0L, MotionEvent.ACTION_MOVE, 0f, VIEW_BOTTOM + 5f, 0
|
|
||||||
)
|
|
||||||
whenever(phoneStatusBarViewController.sendTouchToView(nextEvent)).thenReturn(true)
|
whenever(phoneStatusBarViewController.sendTouchToView(nextEvent)).thenReturn(true)
|
||||||
|
|
||||||
val returnVal = interactionEventHandler.handleDispatchTouchEvent(nextEvent)
|
val returnVal = interactionEventHandler.handleDispatchTouchEvent(nextEvent)
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
|||||||
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
|
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
|
||||||
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
|
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
|
||||||
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel;
|
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel;
|
||||||
|
import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel;
|
||||||
import com.android.systemui.statusbar.DragDownHelper;
|
import com.android.systemui.statusbar.DragDownHelper;
|
||||||
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
|
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
|
||||||
import com.android.systemui.statusbar.NotificationInsetsController;
|
import com.android.systemui.statusbar.NotificationInsetsController;
|
||||||
@@ -101,6 +102,7 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase {
|
|||||||
@Mock private NotificationInsetsController mNotificationInsetsController;
|
@Mock private NotificationInsetsController mNotificationInsetsController;
|
||||||
@Mock private AlternateBouncerInteractor mAlternateBouncerInteractor;
|
@Mock private AlternateBouncerInteractor mAlternateBouncerInteractor;
|
||||||
@Mock private KeyguardTransitionInteractor mKeyguardTransitionInteractor;
|
@Mock private KeyguardTransitionInteractor mKeyguardTransitionInteractor;
|
||||||
|
@Mock private PrimaryBouncerToGoneTransitionViewModel mPrimaryBouncerToGoneTransitionViewModel;
|
||||||
|
|
||||||
@Captor private ArgumentCaptor<NotificationShadeWindowView.InteractionEventHandler>
|
@Captor private ArgumentCaptor<NotificationShadeWindowView.InteractionEventHandler>
|
||||||
mInteractionEventHandlerCaptor;
|
mInteractionEventHandlerCaptor;
|
||||||
@@ -150,7 +152,8 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase {
|
|||||||
mKeyguardBouncerViewModel,
|
mKeyguardBouncerViewModel,
|
||||||
mKeyguardBouncerComponentFactory,
|
mKeyguardBouncerComponentFactory,
|
||||||
mAlternateBouncerInteractor,
|
mAlternateBouncerInteractor,
|
||||||
mKeyguardTransitionInteractor
|
mKeyguardTransitionInteractor,
|
||||||
|
mPrimaryBouncerToGoneTransitionViewModel
|
||||||
);
|
);
|
||||||
mController.setupExpandedStatusBar();
|
mController.setupExpandedStatusBar();
|
||||||
mController.setDragDownHelper(mDragDownHelper);
|
mController.setDragDownHelper(mDragDownHelper);
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ import static com.android.systemui.statusbar.phone.ScrimState.SHADE_LOCKED;
|
|||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import static kotlinx.coroutines.flow.FlowKt.emptyFlow;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyFloat;
|
import static org.mockito.ArgumentMatchers.anyFloat;
|
||||||
@@ -58,7 +60,12 @@ import com.android.systemui.SysuiTestCase;
|
|||||||
import com.android.systemui.animation.ShadeInterpolation;
|
import com.android.systemui.animation.ShadeInterpolation;
|
||||||
import com.android.systemui.dock.DockManager;
|
import com.android.systemui.dock.DockManager;
|
||||||
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
||||||
|
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
|
||||||
import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants;
|
import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants;
|
||||||
|
import com.android.systemui.keyguard.shared.model.KeyguardState;
|
||||||
|
import com.android.systemui.keyguard.shared.model.TransitionState;
|
||||||
|
import com.android.systemui.keyguard.shared.model.TransitionStep;
|
||||||
|
import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel;
|
||||||
import com.android.systemui.scrim.ScrimView;
|
import com.android.systemui.scrim.ScrimView;
|
||||||
import com.android.systemui.statusbar.policy.FakeConfigurationController;
|
import com.android.systemui.statusbar.policy.FakeConfigurationController;
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||||
@@ -85,8 +92,10 @@ import java.util.HashMap;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import kotlinx.coroutines.CoroutineDispatcher;
|
||||||
|
|
||||||
@RunWith(AndroidTestingRunner.class)
|
@RunWith(AndroidTestingRunner.class)
|
||||||
@TestableLooper.RunWithLooper
|
@TestableLooper.RunWithLooper(setAsMainLooper = true)
|
||||||
@SmallTest
|
@SmallTest
|
||||||
public class ScrimControllerTest extends SysuiTestCase {
|
public class ScrimControllerTest extends SysuiTestCase {
|
||||||
|
|
||||||
@@ -115,6 +124,10 @@ public class ScrimControllerTest extends SysuiTestCase {
|
|||||||
@Mock private DockManager mDockManager;
|
@Mock private DockManager mDockManager;
|
||||||
@Mock private ScreenOffAnimationController mScreenOffAnimationController;
|
@Mock private ScreenOffAnimationController mScreenOffAnimationController;
|
||||||
@Mock private KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
|
@Mock private KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
|
||||||
|
@Mock private PrimaryBouncerToGoneTransitionViewModel mPrimaryBouncerToGoneTransitionViewModel;
|
||||||
|
@Mock private KeyguardTransitionInteractor mKeyguardTransitionInteractor;
|
||||||
|
@Mock private CoroutineDispatcher mMainDispatcher;
|
||||||
|
|
||||||
// TODO(b/204991468): Use a real PanelExpansionStateManager object once this bug is fixed. (The
|
// TODO(b/204991468): Use a real PanelExpansionStateManager object once this bug is fixed. (The
|
||||||
// event-dispatch-on-registration pattern caused some of these unit tests to fail.)
|
// event-dispatch-on-registration pattern caused some of these unit tests to fail.)
|
||||||
@Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
|
@Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
|
||||||
@@ -225,13 +238,20 @@ public class ScrimControllerTest extends SysuiTestCase {
|
|||||||
when(mDelayedWakeLockBuilder.build()).thenReturn(mWakeLock);
|
when(mDelayedWakeLockBuilder.build()).thenReturn(mWakeLock);
|
||||||
when(mDockManager.isDocked()).thenReturn(false);
|
when(mDockManager.isDocked()).thenReturn(false);
|
||||||
|
|
||||||
|
when(mKeyguardTransitionInteractor.getPrimaryBouncerToGoneTransition())
|
||||||
|
.thenReturn(emptyFlow());
|
||||||
|
when(mPrimaryBouncerToGoneTransitionViewModel.getScrimAlpha()).thenReturn(emptyFlow());
|
||||||
|
|
||||||
mScrimController = new ScrimController(mLightBarController,
|
mScrimController = new ScrimController(mLightBarController,
|
||||||
mDozeParameters, mAlarmManager, mKeyguardStateController, mDelayedWakeLockBuilder,
|
mDozeParameters, mAlarmManager, mKeyguardStateController, mDelayedWakeLockBuilder,
|
||||||
new FakeHandler(mLooper.getLooper()), mKeyguardUpdateMonitor,
|
new FakeHandler(mLooper.getLooper()), mKeyguardUpdateMonitor,
|
||||||
mDockManager, mConfigurationController, new FakeExecutor(new FakeSystemClock()),
|
mDockManager, mConfigurationController, new FakeExecutor(new FakeSystemClock()),
|
||||||
mScreenOffAnimationController,
|
mScreenOffAnimationController,
|
||||||
mKeyguardUnlockAnimationController,
|
mKeyguardUnlockAnimationController,
|
||||||
mStatusBarKeyguardViewManager);
|
mStatusBarKeyguardViewManager,
|
||||||
|
mPrimaryBouncerToGoneTransitionViewModel,
|
||||||
|
mKeyguardTransitionInteractor,
|
||||||
|
mMainDispatcher);
|
||||||
mScrimController.setScrimVisibleListener(visible -> mScrimVisibility = visible);
|
mScrimController.setScrimVisibleListener(visible -> mScrimVisibility = visible);
|
||||||
mScrimController.attachViews(mScrimBehind, mNotificationsScrim, mScrimInFront);
|
mScrimController.attachViews(mScrimBehind, mNotificationsScrim, mScrimInFront);
|
||||||
mScrimController.setAnimatorListener(mAnimatorListener);
|
mScrimController.setAnimatorListener(mAnimatorListener);
|
||||||
@@ -861,7 +881,10 @@ public class ScrimControllerTest extends SysuiTestCase {
|
|||||||
mDockManager, mConfigurationController, new FakeExecutor(new FakeSystemClock()),
|
mDockManager, mConfigurationController, new FakeExecutor(new FakeSystemClock()),
|
||||||
mScreenOffAnimationController,
|
mScreenOffAnimationController,
|
||||||
mKeyguardUnlockAnimationController,
|
mKeyguardUnlockAnimationController,
|
||||||
mStatusBarKeyguardViewManager);
|
mStatusBarKeyguardViewManager,
|
||||||
|
mPrimaryBouncerToGoneTransitionViewModel,
|
||||||
|
mKeyguardTransitionInteractor,
|
||||||
|
mMainDispatcher);
|
||||||
mScrimController.setScrimVisibleListener(visible -> mScrimVisibility = visible);
|
mScrimController.setScrimVisibleListener(visible -> mScrimVisibility = visible);
|
||||||
mScrimController.attachViews(mScrimBehind, mNotificationsScrim, mScrimInFront);
|
mScrimController.attachViews(mScrimBehind, mNotificationsScrim, mScrimInFront);
|
||||||
mScrimController.setAnimatorListener(mAnimatorListener);
|
mScrimController.setAnimatorListener(mAnimatorListener);
|
||||||
@@ -1629,6 +1652,18 @@ public class ScrimControllerTest extends SysuiTestCase {
|
|||||||
assertScrimAlpha(mScrimBehind, 0);
|
assertScrimAlpha(mScrimBehind, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ignoreTransitionRequestWhileKeyguardTransitionRunning() {
|
||||||
|
mScrimController.transitionTo(ScrimState.UNLOCKED);
|
||||||
|
mScrimController.mPrimaryBouncerToGoneTransition.accept(
|
||||||
|
new TransitionStep(KeyguardState.PRIMARY_BOUNCER, KeyguardState.GONE, 0f,
|
||||||
|
TransitionState.RUNNING, "ScrimControllerTest"));
|
||||||
|
|
||||||
|
// This request should not happen
|
||||||
|
mScrimController.transitionTo(ScrimState.BOUNCER);
|
||||||
|
assertThat(mScrimController.getState()).isEqualTo(ScrimState.UNLOCKED);
|
||||||
|
}
|
||||||
|
|
||||||
private void assertAlphaAfterExpansion(ScrimView scrim, float expectedAlpha, float expansion) {
|
private void assertAlphaAfterExpansion(ScrimView scrim, float expectedAlpha, float expansion) {
|
||||||
mScrimController.setRawPanelExpansionFraction(expansion);
|
mScrimController.setRawPanelExpansionFraction(expansion);
|
||||||
finishAnimationsImmediately();
|
finishAnimationsImmediately();
|
||||||
|
|||||||
@@ -47,6 +47,9 @@ class FakeKeyguardRepository : KeyguardRepository {
|
|||||||
private val _isKeyguardShowing = MutableStateFlow(false)
|
private val _isKeyguardShowing = MutableStateFlow(false)
|
||||||
override val isKeyguardShowing: Flow<Boolean> = _isKeyguardShowing
|
override val isKeyguardShowing: Flow<Boolean> = _isKeyguardShowing
|
||||||
|
|
||||||
|
private val _isKeyguardUnlocked = MutableStateFlow(false)
|
||||||
|
override val isKeyguardUnlocked: Flow<Boolean> = _isKeyguardUnlocked
|
||||||
|
|
||||||
private val _isKeyguardOccluded = MutableStateFlow(false)
|
private val _isKeyguardOccluded = MutableStateFlow(false)
|
||||||
override val isKeyguardOccluded: Flow<Boolean> = _isKeyguardOccluded
|
override val isKeyguardOccluded: Flow<Boolean> = _isKeyguardOccluded
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ class FakeKeyguardTransitionRepository : KeyguardTransitionRepository {
|
|||||||
_transitions.emit(step)
|
_transitions.emit(step)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun startTransition(info: TransitionInfo): UUID? {
|
override fun startTransition(info: TransitionInfo, resetIfCanceled: Boolean): UUID? {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user