Merge "Transitions - Better dozing/aod support" into tm-qpr-dev
This commit is contained in:
@@ -114,8 +114,6 @@ object Flags {
|
|||||||
// ** Flag retired **
|
// ** Flag retired **
|
||||||
// public static final BooleanFlag KEYGUARD_LAYOUT =
|
// public static final BooleanFlag KEYGUARD_LAYOUT =
|
||||||
// new BooleanFlag(200, true);
|
// new BooleanFlag(200, true);
|
||||||
// TODO(b/254512713): Tracking Bug
|
|
||||||
@JvmField val LOCKSCREEN_ANIMATIONS = releasedFlag(201, "lockscreen_animations")
|
|
||||||
|
|
||||||
// TODO(b/254512750): Tracking Bug
|
// TODO(b/254512750): Tracking Bug
|
||||||
val NEW_UNLOCK_SWIPE_ANIMATION = releasedFlag(202, "new_unlock_swipe_animation")
|
val NEW_UNLOCK_SWIPE_ANIMATION = releasedFlag(202, "new_unlock_swipe_animation")
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import com.android.systemui.keyguard.shared.model.WakefulnessModel
|
|||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
||||||
import com.android.systemui.statusbar.phone.BiometricUnlockController
|
import com.android.systemui.statusbar.phone.BiometricUnlockController
|
||||||
import com.android.systemui.statusbar.phone.BiometricUnlockController.WakeAndUnlockMode
|
import com.android.systemui.statusbar.phone.BiometricUnlockController.WakeAndUnlockMode
|
||||||
|
import com.android.systemui.statusbar.phone.DozeParameters
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlinx.coroutines.channels.awaitClose
|
import kotlinx.coroutines.channels.awaitClose
|
||||||
@@ -88,6 +89,9 @@ interface KeyguardRepository {
|
|||||||
/** Observable for whether the bouncer is showing. */
|
/** Observable for whether the bouncer is showing. */
|
||||||
val isBouncerShowing: Flow<Boolean>
|
val isBouncerShowing: Flow<Boolean>
|
||||||
|
|
||||||
|
/** Is the always-on display available to be used? */
|
||||||
|
val isAodAvailable: Flow<Boolean>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Observable for whether we are in doze state.
|
* Observable for whether we are in doze state.
|
||||||
*
|
*
|
||||||
@@ -182,6 +186,7 @@ constructor(
|
|||||||
private val keyguardStateController: KeyguardStateController,
|
private val keyguardStateController: KeyguardStateController,
|
||||||
private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
|
private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
|
||||||
private val dozeTransitionListener: DozeTransitionListener,
|
private val dozeTransitionListener: DozeTransitionListener,
|
||||||
|
private val dozeParameters: DozeParameters,
|
||||||
private val authController: AuthController,
|
private val authController: AuthController,
|
||||||
private val dreamOverlayCallbackController: DreamOverlayCallbackController,
|
private val dreamOverlayCallbackController: DreamOverlayCallbackController,
|
||||||
) : KeyguardRepository {
|
) : KeyguardRepository {
|
||||||
@@ -220,6 +225,31 @@ constructor(
|
|||||||
}
|
}
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
|
|
||||||
|
override val isAodAvailable: Flow<Boolean> =
|
||||||
|
conflatedCallbackFlow {
|
||||||
|
val callback =
|
||||||
|
object : DozeParameters.Callback {
|
||||||
|
override fun onAlwaysOnChange() {
|
||||||
|
trySendWithFailureLogging(
|
||||||
|
dozeParameters.getAlwaysOn(),
|
||||||
|
TAG,
|
||||||
|
"updated isAodAvailable"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dozeParameters.addCallback(callback)
|
||||||
|
// Adding the callback does not send an initial update.
|
||||||
|
trySendWithFailureLogging(
|
||||||
|
dozeParameters.getAlwaysOn(),
|
||||||
|
TAG,
|
||||||
|
"initial isAodAvailable"
|
||||||
|
)
|
||||||
|
|
||||||
|
awaitClose { dozeParameters.removeCallback(callback) }
|
||||||
|
}
|
||||||
|
.distinctUntilChanged()
|
||||||
|
|
||||||
override val isKeyguardOccluded: Flow<Boolean> =
|
override val isKeyguardOccluded: Flow<Boolean> =
|
||||||
conflatedCallbackFlow {
|
conflatedCallbackFlow {
|
||||||
val callback =
|
val callback =
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ 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
|
||||||
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
|
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
|
||||||
import com.android.systemui.keyguard.shared.model.DozeStateModel.Companion.isDozeOff
|
|
||||||
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.WakefulnessModel.Companion.isWakingOrStartingToWake
|
||||||
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
|
||||||
@@ -48,12 +48,11 @@ constructor(
|
|||||||
|
|
||||||
private fun listenForDozingToLockscreen() {
|
private fun listenForDozingToLockscreen() {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
keyguardInteractor.dozeTransitionModel
|
keyguardInteractor.wakefulnessModel
|
||||||
.sample(keyguardTransitionInteractor.startedKeyguardTransitionStep, ::Pair)
|
.sample(keyguardTransitionInteractor.startedKeyguardTransitionStep, ::Pair)
|
||||||
.collect { pair ->
|
.collect { (wakefulnessModel, lastStartedTransition) ->
|
||||||
val (dozeTransitionModel, lastStartedTransition) = pair
|
|
||||||
if (
|
if (
|
||||||
isDozeOff(dozeTransitionModel.to) &&
|
isWakingOrStartingToWake(wakefulnessModel) &&
|
||||||
lastStartedTransition.to == KeyguardState.DOZING
|
lastStartedTransition.to == KeyguardState.DOZING
|
||||||
) {
|
) {
|
||||||
keyguardTransitionRepository.startTransition(
|
keyguardTransitionRepository.startTransition(
|
||||||
|
|||||||
@@ -26,7 +26,10 @@ 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.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@SysUISingleton
|
@SysUISingleton
|
||||||
@@ -40,7 +43,7 @@ constructor(
|
|||||||
) : TransitionInteractor(FromGoneTransitionInteractor::class.simpleName!!) {
|
) : TransitionInteractor(FromGoneTransitionInteractor::class.simpleName!!) {
|
||||||
|
|
||||||
override fun start() {
|
override fun start() {
|
||||||
listenForGoneToAod()
|
listenForGoneToAodOrDozing()
|
||||||
listenForGoneToDreaming()
|
listenForGoneToDreaming()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +59,7 @@ constructor(
|
|||||||
name,
|
name,
|
||||||
KeyguardState.GONE,
|
KeyguardState.GONE,
|
||||||
KeyguardState.DREAMING,
|
KeyguardState.DREAMING,
|
||||||
getAnimator(),
|
getAnimator(TO_DREAMING_DURATION),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -64,12 +67,18 @@ constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun listenForGoneToAod() {
|
private fun listenForGoneToAodOrDozing() {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
keyguardInteractor.wakefulnessModel
|
keyguardInteractor.wakefulnessModel
|
||||||
.sample(keyguardTransitionInteractor.finishedKeyguardState, ::Pair)
|
.sample(
|
||||||
.collect { pair ->
|
combine(
|
||||||
val (wakefulnessState, keyguardState) = pair
|
keyguardTransitionInteractor.finishedKeyguardState,
|
||||||
|
keyguardInteractor.isAodAvailable,
|
||||||
|
::Pair
|
||||||
|
),
|
||||||
|
::toTriple
|
||||||
|
)
|
||||||
|
.collect { (wakefulnessState, keyguardState, isAodAvailable) ->
|
||||||
if (
|
if (
|
||||||
keyguardState == KeyguardState.GONE &&
|
keyguardState == KeyguardState.GONE &&
|
||||||
wakefulnessState.state == WakefulnessState.STARTING_TO_SLEEP
|
wakefulnessState.state == WakefulnessState.STARTING_TO_SLEEP
|
||||||
@@ -78,7 +87,11 @@ constructor(
|
|||||||
TransitionInfo(
|
TransitionInfo(
|
||||||
name,
|
name,
|
||||||
KeyguardState.GONE,
|
KeyguardState.GONE,
|
||||||
KeyguardState.AOD,
|
if (isAodAvailable) {
|
||||||
|
KeyguardState.AOD
|
||||||
|
} else {
|
||||||
|
KeyguardState.DOZING
|
||||||
|
},
|
||||||
getAnimator(),
|
getAnimator(),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -87,14 +100,15 @@ constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 = 500L
|
private val DEFAULT_DURATION = 500.milliseconds
|
||||||
|
val TO_DREAMING_DURATION = 933.milliseconds
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,11 +21,11 @@ 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
|
||||||
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
|
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
|
||||||
import com.android.systemui.keyguard.shared.model.DozeStateModel
|
|
||||||
import com.android.systemui.keyguard.shared.model.KeyguardState
|
import com.android.systemui.keyguard.shared.model.KeyguardState
|
||||||
import com.android.systemui.keyguard.shared.model.StatusBarState.KEYGUARD
|
import com.android.systemui.keyguard.shared.model.StatusBarState.KEYGUARD
|
||||||
import com.android.systemui.keyguard.shared.model.TransitionInfo
|
import com.android.systemui.keyguard.shared.model.TransitionInfo
|
||||||
import com.android.systemui.keyguard.shared.model.TransitionState
|
import com.android.systemui.keyguard.shared.model.TransitionState
|
||||||
|
import com.android.systemui.keyguard.shared.model.WakefulnessState
|
||||||
import com.android.systemui.shade.data.repository.ShadeRepository
|
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 java.util.UUID
|
||||||
@@ -54,7 +54,7 @@ constructor(
|
|||||||
listenForLockscreenToGone()
|
listenForLockscreenToGone()
|
||||||
listenForLockscreenToOccluded()
|
listenForLockscreenToOccluded()
|
||||||
listenForLockscreenToCamera()
|
listenForLockscreenToCamera()
|
||||||
listenForLockscreenToAod()
|
listenForLockscreenToAodOrDozing()
|
||||||
listenForLockscreenToBouncer()
|
listenForLockscreenToBouncer()
|
||||||
listenForLockscreenToDreaming()
|
listenForLockscreenToDreaming()
|
||||||
listenForLockscreenToBouncerDragging()
|
listenForLockscreenToBouncerDragging()
|
||||||
@@ -230,19 +230,31 @@ constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun listenForLockscreenToAod() {
|
private fun listenForLockscreenToAodOrDozing() {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
keyguardInteractor
|
keyguardInteractor.wakefulnessModel
|
||||||
.dozeTransitionTo(DozeStateModel.DOZE_AOD)
|
.sample(
|
||||||
.sample(keyguardTransitionInteractor.startedKeyguardTransitionStep, ::Pair)
|
combine(
|
||||||
.collect { pair ->
|
keyguardTransitionInteractor.startedKeyguardTransitionStep,
|
||||||
val (dozeToAod, lastStartedStep) = pair
|
keyguardInteractor.isAodAvailable,
|
||||||
if (lastStartedStep.to == KeyguardState.LOCKSCREEN) {
|
::Pair
|
||||||
|
),
|
||||||
|
::toTriple
|
||||||
|
)
|
||||||
|
.collect { (wakefulnessState, lastStartedStep, isAodAvailable) ->
|
||||||
|
if (
|
||||||
|
lastStartedStep.to == KeyguardState.LOCKSCREEN &&
|
||||||
|
wakefulnessState.state == WakefulnessState.STARTING_TO_SLEEP
|
||||||
|
) {
|
||||||
keyguardTransitionRepository.startTransition(
|
keyguardTransitionRepository.startTransition(
|
||||||
TransitionInfo(
|
TransitionInfo(
|
||||||
name,
|
name,
|
||||||
KeyguardState.LOCKSCREEN,
|
KeyguardState.LOCKSCREEN,
|
||||||
KeyguardState.AOD,
|
if (isAodAvailable) {
|
||||||
|
KeyguardState.AOD
|
||||||
|
} else {
|
||||||
|
KeyguardState.DOZING
|
||||||
|
},
|
||||||
getAnimator(),
|
getAnimator(),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -23,12 +23,14 @@ import com.android.systemui.dagger.qualifiers.Application
|
|||||||
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.TransitionInfo
|
import com.android.systemui.keyguard.shared.model.TransitionInfo
|
||||||
|
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
|
||||||
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.collect
|
||||||
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@SysUISingleton
|
@SysUISingleton
|
||||||
@@ -44,6 +46,7 @@ constructor(
|
|||||||
override fun start() {
|
override fun start() {
|
||||||
listenForOccludedToLockscreen()
|
listenForOccludedToLockscreen()
|
||||||
listenForOccludedToDreaming()
|
listenForOccludedToDreaming()
|
||||||
|
listenForOccludedToAodOrDozing()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun listenForOccludedToDreaming() {
|
private fun listenForOccludedToDreaming() {
|
||||||
@@ -70,8 +73,7 @@ constructor(
|
|||||||
scope.launch {
|
scope.launch {
|
||||||
keyguardInteractor.isKeyguardOccluded
|
keyguardInteractor.isKeyguardOccluded
|
||||||
.sample(keyguardTransitionInteractor.startedKeyguardTransitionStep, ::Pair)
|
.sample(keyguardTransitionInteractor.startedKeyguardTransitionStep, ::Pair)
|
||||||
.collect { pair ->
|
.collect { (isOccluded, lastStartedKeyguardState) ->
|
||||||
val (isOccluded, lastStartedKeyguardState) = pair
|
|
||||||
// Occlusion signals come from the framework, and should interrupt any
|
// Occlusion signals come from the framework, and should interrupt any
|
||||||
// existing transition
|
// existing transition
|
||||||
if (!isOccluded && lastStartedKeyguardState.to == KeyguardState.OCCLUDED) {
|
if (!isOccluded && lastStartedKeyguardState.to == KeyguardState.OCCLUDED) {
|
||||||
@@ -88,6 +90,39 @@ constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun listenForOccludedToAodOrDozing() {
|
||||||
|
scope.launch {
|
||||||
|
keyguardInteractor.wakefulnessModel
|
||||||
|
.sample(
|
||||||
|
combine(
|
||||||
|
keyguardTransitionInteractor.startedKeyguardTransitionStep,
|
||||||
|
keyguardInteractor.isAodAvailable,
|
||||||
|
::Pair
|
||||||
|
),
|
||||||
|
::toTriple
|
||||||
|
)
|
||||||
|
.collect { (wakefulnessState, lastStartedStep, isAodAvailable) ->
|
||||||
|
if (
|
||||||
|
lastStartedStep.to == KeyguardState.OCCLUDED &&
|
||||||
|
wakefulnessState.state == WakefulnessState.STARTING_TO_SLEEP
|
||||||
|
) {
|
||||||
|
keyguardTransitionRepository.startTransition(
|
||||||
|
TransitionInfo(
|
||||||
|
name,
|
||||||
|
KeyguardState.OCCLUDED,
|
||||||
|
if (isAodAvailable) {
|
||||||
|
KeyguardState.AOD
|
||||||
|
} else {
|
||||||
|
KeyguardState.DOZING
|
||||||
|
},
|
||||||
|
getAnimator(),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun getAnimator(duration: Duration = DEFAULT_DURATION): ValueAnimator {
|
private fun getAnimator(duration: Duration = DEFAULT_DURATION): ValueAnimator {
|
||||||
return ValueAnimator().apply {
|
return ValueAnimator().apply {
|
||||||
setInterpolator(Interpolators.LINEAR)
|
setInterpolator(Interpolators.LINEAR)
|
||||||
|
|||||||
@@ -57,6 +57,8 @@ constructor(
|
|||||||
val dozeAmount: Flow<Float> = repository.linearDozeAmount
|
val dozeAmount: Flow<Float> = repository.linearDozeAmount
|
||||||
/** Whether the system is in doze mode. */
|
/** Whether the system is in doze mode. */
|
||||||
val isDozing: Flow<Boolean> = repository.isDozing
|
val isDozing: Flow<Boolean> = repository.isDozing
|
||||||
|
/** Whether Always-on Display mode is available. */
|
||||||
|
val isAodAvailable: Flow<Boolean> = repository.isAodAvailable
|
||||||
/** Doze transition information. */
|
/** Doze transition information. */
|
||||||
val dozeTransitionModel: Flow<DozeTransitionModel> = repository.dozeTransitionModel
|
val dozeTransitionModel: Flow<DozeTransitionModel> = repository.dozeTransitionModel
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -4266,8 +4266,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDozeAmountChanged(float linear, float eased) {
|
public void onDozeAmountChanged(float linear, float eased) {
|
||||||
if (mFeatureFlags.isEnabled(Flags.LOCKSCREEN_ANIMATIONS)
|
if (!mFeatureFlags.isEnabled(Flags.LIGHT_REVEAL_MIGRATION)
|
||||||
&& !mFeatureFlags.isEnabled(Flags.LIGHT_REVEAL_MIGRATION)
|
|
||||||
&& !(mLightRevealScrim.getRevealEffect() instanceof CircleReveal)) {
|
&& !(mLightRevealScrim.getRevealEffect() instanceof CircleReveal)) {
|
||||||
mLightRevealScrim.setRevealAmount(1f - linear);
|
mLightRevealScrim.setRevealAmount(1f - linear);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,10 +44,9 @@ import com.android.systemui.dagger.qualifiers.Main;
|
|||||||
import com.android.systemui.doze.AlwaysOnDisplayPolicy;
|
import com.android.systemui.doze.AlwaysOnDisplayPolicy;
|
||||||
import com.android.systemui.doze.DozeScreenState;
|
import com.android.systemui.doze.DozeScreenState;
|
||||||
import com.android.systemui.dump.DumpManager;
|
import com.android.systemui.dump.DumpManager;
|
||||||
import com.android.systemui.flags.FeatureFlags;
|
|
||||||
import com.android.systemui.flags.Flags;
|
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||||
import com.android.systemui.statusbar.policy.BatteryController;
|
import com.android.systemui.statusbar.policy.BatteryController;
|
||||||
|
import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
|
||||||
import com.android.systemui.statusbar.policy.ConfigurationController;
|
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||||
import com.android.systemui.statusbar.policy.DevicePostureController;
|
import com.android.systemui.statusbar.policy.DevicePostureController;
|
||||||
import com.android.systemui.tuner.TunerService;
|
import com.android.systemui.tuner.TunerService;
|
||||||
@@ -82,7 +81,6 @@ public class DozeParameters implements
|
|||||||
private final AlwaysOnDisplayPolicy mAlwaysOnPolicy;
|
private final AlwaysOnDisplayPolicy mAlwaysOnPolicy;
|
||||||
private final Resources mResources;
|
private final Resources mResources;
|
||||||
private final BatteryController mBatteryController;
|
private final BatteryController mBatteryController;
|
||||||
private final FeatureFlags mFeatureFlags;
|
|
||||||
private final ScreenOffAnimationController mScreenOffAnimationController;
|
private final ScreenOffAnimationController mScreenOffAnimationController;
|
||||||
private final FoldAodAnimationController mFoldAodAnimationController;
|
private final FoldAodAnimationController mFoldAodAnimationController;
|
||||||
private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
|
private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
|
||||||
@@ -125,7 +123,6 @@ public class DozeParameters implements
|
|||||||
BatteryController batteryController,
|
BatteryController batteryController,
|
||||||
TunerService tunerService,
|
TunerService tunerService,
|
||||||
DumpManager dumpManager,
|
DumpManager dumpManager,
|
||||||
FeatureFlags featureFlags,
|
|
||||||
ScreenOffAnimationController screenOffAnimationController,
|
ScreenOffAnimationController screenOffAnimationController,
|
||||||
Optional<SysUIUnfoldComponent> sysUiUnfoldComponent,
|
Optional<SysUIUnfoldComponent> sysUiUnfoldComponent,
|
||||||
UnlockedScreenOffAnimationController unlockedScreenOffAnimationController,
|
UnlockedScreenOffAnimationController unlockedScreenOffAnimationController,
|
||||||
@@ -141,7 +138,6 @@ public class DozeParameters implements
|
|||||||
mControlScreenOffAnimation = !getDisplayNeedsBlanking();
|
mControlScreenOffAnimation = !getDisplayNeedsBlanking();
|
||||||
mPowerManager = powerManager;
|
mPowerManager = powerManager;
|
||||||
mPowerManager.setDozeAfterScreenOff(!mControlScreenOffAnimation);
|
mPowerManager.setDozeAfterScreenOff(!mControlScreenOffAnimation);
|
||||||
mFeatureFlags = featureFlags;
|
|
||||||
mScreenOffAnimationController = screenOffAnimationController;
|
mScreenOffAnimationController = screenOffAnimationController;
|
||||||
mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
|
mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
|
||||||
|
|
||||||
@@ -162,6 +158,13 @@ public class DozeParameters implements
|
|||||||
|
|
||||||
SettingsObserver quickPickupSettingsObserver = new SettingsObserver(context, handler);
|
SettingsObserver quickPickupSettingsObserver = new SettingsObserver(context, handler);
|
||||||
quickPickupSettingsObserver.observe();
|
quickPickupSettingsObserver.observe();
|
||||||
|
|
||||||
|
batteryController.addCallback(new BatteryStateChangeCallback() {
|
||||||
|
@Override
|
||||||
|
public void onPowerSaveChanged(boolean isPowerSave) {
|
||||||
|
dispatchAlwaysOnEvent();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateQuickPickupEnabled() {
|
private void updateQuickPickupEnabled() {
|
||||||
@@ -300,13 +303,10 @@ public class DozeParameters implements
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether we're capable of controlling the screen off animation if we want to. This isn't
|
* Whether we're capable of controlling the screen off animation if we want to. This isn't
|
||||||
* possible if AOD isn't even enabled or if the flag is disabled, or if the display needs
|
* possible if AOD isn't even enabled or if the display needs blanking.
|
||||||
* blanking.
|
|
||||||
*/
|
*/
|
||||||
public boolean canControlUnlockedScreenOff() {
|
public boolean canControlUnlockedScreenOff() {
|
||||||
return getAlwaysOn()
|
return getAlwaysOn() && !getDisplayNeedsBlanking();
|
||||||
&& mFeatureFlags.isEnabled(Flags.LOCKSCREEN_ANIMATIONS)
|
|
||||||
&& !getDisplayNeedsBlanking();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -424,9 +424,7 @@ public class DozeParameters implements
|
|||||||
updateControlScreenOff();
|
updateControlScreenOff();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Callback callback : mCallbacks) {
|
dispatchAlwaysOnEvent();
|
||||||
callback.onAlwaysOnChange();
|
|
||||||
}
|
|
||||||
mScreenOffAnimationController.onAlwaysOnChanged(getAlwaysOn());
|
mScreenOffAnimationController.onAlwaysOnChanged(getAlwaysOn());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -463,6 +461,12 @@ public class DozeParameters implements
|
|||||||
pw.print("isQuickPickupEnabled(): "); pw.println(isQuickPickupEnabled());
|
pw.print("isQuickPickupEnabled(): "); pw.println(isQuickPickupEnabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void dispatchAlwaysOnEvent() {
|
||||||
|
for (Callback callback : mCallbacks) {
|
||||||
|
callback.onAlwaysOnChange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private boolean getPostureSpecificBool(
|
private boolean getPostureSpecificBool(
|
||||||
int[] postureMapping,
|
int[] postureMapping,
|
||||||
boolean defaultSensorBool,
|
boolean defaultSensorBool,
|
||||||
@@ -477,7 +481,8 @@ public class DozeParameters implements
|
|||||||
return bool;
|
return bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Callback {
|
/** Callbacks for doze parameter related information */
|
||||||
|
public interface Callback {
|
||||||
/**
|
/**
|
||||||
* Invoked when the value of getAlwaysOn may have changed.
|
* Invoked when the value of getAlwaysOn may have changed.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback
|
|||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
import com.android.systemui.biometrics.AuthController
|
import com.android.systemui.biometrics.AuthController
|
||||||
import com.android.systemui.common.shared.model.Position
|
import com.android.systemui.common.shared.model.Position
|
||||||
|
import com.android.systemui.coroutines.collectLastValue
|
||||||
import com.android.systemui.doze.DozeHost
|
import com.android.systemui.doze.DozeHost
|
||||||
import com.android.systemui.doze.DozeMachine
|
import com.android.systemui.doze.DozeMachine
|
||||||
import com.android.systemui.doze.DozeTransitionCallback
|
import com.android.systemui.doze.DozeTransitionCallback
|
||||||
@@ -38,14 +39,17 @@ import com.android.systemui.keyguard.shared.model.WakefulnessModel
|
|||||||
import com.android.systemui.keyguard.shared.model.WakefulnessState
|
import com.android.systemui.keyguard.shared.model.WakefulnessState
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
||||||
import com.android.systemui.statusbar.phone.BiometricUnlockController
|
import com.android.systemui.statusbar.phone.BiometricUnlockController
|
||||||
|
import com.android.systemui.statusbar.phone.DozeParameters
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||||
import com.android.systemui.util.mockito.argumentCaptor
|
import com.android.systemui.util.mockito.argumentCaptor
|
||||||
import com.android.systemui.util.mockito.whenever
|
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.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
|
import kotlinx.coroutines.flow.onCompletion
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.test.UnconfinedTestDispatcher
|
import kotlinx.coroutines.test.UnconfinedTestDispatcher
|
||||||
|
import kotlinx.coroutines.test.runCurrent
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
@@ -68,6 +72,7 @@ class KeyguardRepositoryImplTest : SysuiTestCase() {
|
|||||||
@Mock private lateinit var authController: AuthController
|
@Mock private lateinit var authController: AuthController
|
||||||
@Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
|
@Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
|
||||||
@Mock private lateinit var dreamOverlayCallbackController: DreamOverlayCallbackController
|
@Mock private lateinit var dreamOverlayCallbackController: DreamOverlayCallbackController
|
||||||
|
@Mock private lateinit var dozeParameters: DozeParameters
|
||||||
|
|
||||||
private lateinit var underTest: KeyguardRepositoryImpl
|
private lateinit var underTest: KeyguardRepositoryImpl
|
||||||
|
|
||||||
@@ -84,6 +89,7 @@ class KeyguardRepositoryImplTest : SysuiTestCase() {
|
|||||||
keyguardStateController,
|
keyguardStateController,
|
||||||
keyguardUpdateMonitor,
|
keyguardUpdateMonitor,
|
||||||
dozeTransitionListener,
|
dozeTransitionListener,
|
||||||
|
dozeParameters,
|
||||||
authController,
|
authController,
|
||||||
dreamOverlayCallbackController,
|
dreamOverlayCallbackController,
|
||||||
)
|
)
|
||||||
@@ -169,6 +175,26 @@ class KeyguardRepositoryImplTest : SysuiTestCase() {
|
|||||||
job.cancel()
|
job.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun isAodAvailable() = runTest {
|
||||||
|
val flow = underTest.isAodAvailable
|
||||||
|
var isAodAvailable = collectLastValue(flow)
|
||||||
|
runCurrent()
|
||||||
|
|
||||||
|
val callback =
|
||||||
|
withArgCaptor<DozeParameters.Callback> { verify(dozeParameters).addCallback(capture()) }
|
||||||
|
|
||||||
|
whenever(dozeParameters.getAlwaysOn()).thenReturn(false)
|
||||||
|
callback.onAlwaysOnChange()
|
||||||
|
assertThat(isAodAvailable()).isEqualTo(false)
|
||||||
|
|
||||||
|
whenever(dozeParameters.getAlwaysOn()).thenReturn(true)
|
||||||
|
callback.onAlwaysOnChange()
|
||||||
|
assertThat(isAodAvailable()).isEqualTo(true)
|
||||||
|
|
||||||
|
flow.onCompletion { verify(dozeParameters).removeCallback(callback) }
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun isKeyguardOccluded() =
|
fun isKeyguardOccluded() =
|
||||||
runTest(UnconfinedTestDispatcher()) {
|
runTest(UnconfinedTestDispatcher()) {
|
||||||
|
|||||||
@@ -71,6 +71,10 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
|||||||
|
|
||||||
private lateinit var fromLockscreenTransitionInteractor: FromLockscreenTransitionInteractor
|
private lateinit var fromLockscreenTransitionInteractor: FromLockscreenTransitionInteractor
|
||||||
private lateinit var fromDreamingTransitionInteractor: FromDreamingTransitionInteractor
|
private lateinit var fromDreamingTransitionInteractor: FromDreamingTransitionInteractor
|
||||||
|
private lateinit var fromDozingTransitionInteractor: FromDozingTransitionInteractor
|
||||||
|
private lateinit var fromOccludedTransitionInteractor: FromOccludedTransitionInteractor
|
||||||
|
private lateinit var fromGoneTransitionInteractor: FromGoneTransitionInteractor
|
||||||
|
private lateinit var fromAodTransitionInteractor: FromAodTransitionInteractor
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
@@ -102,6 +106,42 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
|||||||
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
|
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
|
||||||
)
|
)
|
||||||
fromDreamingTransitionInteractor.start()
|
fromDreamingTransitionInteractor.start()
|
||||||
|
|
||||||
|
fromAodTransitionInteractor =
|
||||||
|
FromAodTransitionInteractor(
|
||||||
|
scope = testScope,
|
||||||
|
keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue),
|
||||||
|
keyguardTransitionRepository = mockTransitionRepository,
|
||||||
|
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
|
||||||
|
)
|
||||||
|
fromAodTransitionInteractor.start()
|
||||||
|
|
||||||
|
fromGoneTransitionInteractor =
|
||||||
|
FromGoneTransitionInteractor(
|
||||||
|
scope = testScope,
|
||||||
|
keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue),
|
||||||
|
keyguardTransitionRepository = mockTransitionRepository,
|
||||||
|
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
|
||||||
|
)
|
||||||
|
fromGoneTransitionInteractor.start()
|
||||||
|
|
||||||
|
fromDozingTransitionInteractor =
|
||||||
|
FromDozingTransitionInteractor(
|
||||||
|
scope = testScope,
|
||||||
|
keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue),
|
||||||
|
keyguardTransitionRepository = mockTransitionRepository,
|
||||||
|
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
|
||||||
|
)
|
||||||
|
fromDozingTransitionInteractor.start()
|
||||||
|
|
||||||
|
fromOccludedTransitionInteractor =
|
||||||
|
FromOccludedTransitionInteractor(
|
||||||
|
scope = testScope,
|
||||||
|
keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue),
|
||||||
|
keyguardTransitionRepository = mockTransitionRepository,
|
||||||
|
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
|
||||||
|
)
|
||||||
|
fromOccludedTransitionInteractor.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -192,6 +232,289 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
|||||||
coroutineContext.cancelChildren()
|
coroutineContext.cancelChildren()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `OCCLUDED to DOZING`() =
|
||||||
|
testScope.runTest {
|
||||||
|
// GIVEN a device with AOD not available
|
||||||
|
keyguardRepository.setAodAvailable(false)
|
||||||
|
runCurrent()
|
||||||
|
|
||||||
|
// GIVEN a prior transition has run to OCCLUDED
|
||||||
|
runner.startTransition(
|
||||||
|
testScope,
|
||||||
|
TransitionInfo(
|
||||||
|
ownerName = "",
|
||||||
|
from = KeyguardState.LOCKSCREEN,
|
||||||
|
to = KeyguardState.OCCLUDED,
|
||||||
|
animator =
|
||||||
|
ValueAnimator().apply {
|
||||||
|
duration = 10
|
||||||
|
interpolator = Interpolators.LINEAR
|
||||||
|
},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
runCurrent()
|
||||||
|
reset(mockTransitionRepository)
|
||||||
|
|
||||||
|
// WHEN the device begins to sleep
|
||||||
|
keyguardRepository.setWakefulnessModel(startingToSleep())
|
||||||
|
runCurrent()
|
||||||
|
|
||||||
|
val info =
|
||||||
|
withArgCaptor<TransitionInfo> {
|
||||||
|
verify(mockTransitionRepository).startTransition(capture())
|
||||||
|
}
|
||||||
|
// THEN a transition to DOZING should occur
|
||||||
|
assertThat(info.ownerName).isEqualTo("FromOccludedTransitionInteractor")
|
||||||
|
assertThat(info.from).isEqualTo(KeyguardState.OCCLUDED)
|
||||||
|
assertThat(info.to).isEqualTo(KeyguardState.DOZING)
|
||||||
|
assertThat(info.animator).isNotNull()
|
||||||
|
|
||||||
|
coroutineContext.cancelChildren()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `OCCLUDED to AOD`() =
|
||||||
|
testScope.runTest {
|
||||||
|
// GIVEN a device with AOD available
|
||||||
|
keyguardRepository.setAodAvailable(true)
|
||||||
|
runCurrent()
|
||||||
|
|
||||||
|
// GIVEN a prior transition has run to OCCLUDED
|
||||||
|
runner.startTransition(
|
||||||
|
testScope,
|
||||||
|
TransitionInfo(
|
||||||
|
ownerName = "",
|
||||||
|
from = KeyguardState.LOCKSCREEN,
|
||||||
|
to = KeyguardState.OCCLUDED,
|
||||||
|
animator =
|
||||||
|
ValueAnimator().apply {
|
||||||
|
duration = 10
|
||||||
|
interpolator = Interpolators.LINEAR
|
||||||
|
},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
runCurrent()
|
||||||
|
reset(mockTransitionRepository)
|
||||||
|
|
||||||
|
// WHEN the device begins to sleep
|
||||||
|
keyguardRepository.setWakefulnessModel(startingToSleep())
|
||||||
|
runCurrent()
|
||||||
|
|
||||||
|
val info =
|
||||||
|
withArgCaptor<TransitionInfo> {
|
||||||
|
verify(mockTransitionRepository).startTransition(capture())
|
||||||
|
}
|
||||||
|
// THEN a transition to DOZING should occur
|
||||||
|
assertThat(info.ownerName).isEqualTo("FromOccludedTransitionInteractor")
|
||||||
|
assertThat(info.from).isEqualTo(KeyguardState.OCCLUDED)
|
||||||
|
assertThat(info.to).isEqualTo(KeyguardState.AOD)
|
||||||
|
assertThat(info.animator).isNotNull()
|
||||||
|
|
||||||
|
coroutineContext.cancelChildren()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `LOCKSCREEN to DOZING`() =
|
||||||
|
testScope.runTest {
|
||||||
|
// GIVEN a device with AOD not available
|
||||||
|
keyguardRepository.setAodAvailable(false)
|
||||||
|
runCurrent()
|
||||||
|
|
||||||
|
// GIVEN a prior transition has run to LOCKSCREEN
|
||||||
|
runner.startTransition(
|
||||||
|
testScope,
|
||||||
|
TransitionInfo(
|
||||||
|
ownerName = "",
|
||||||
|
from = KeyguardState.GONE,
|
||||||
|
to = KeyguardState.LOCKSCREEN,
|
||||||
|
animator =
|
||||||
|
ValueAnimator().apply {
|
||||||
|
duration = 10
|
||||||
|
interpolator = Interpolators.LINEAR
|
||||||
|
},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
runCurrent()
|
||||||
|
reset(mockTransitionRepository)
|
||||||
|
|
||||||
|
// WHEN the device begins to sleep
|
||||||
|
keyguardRepository.setWakefulnessModel(startingToSleep())
|
||||||
|
runCurrent()
|
||||||
|
|
||||||
|
val info =
|
||||||
|
withArgCaptor<TransitionInfo> {
|
||||||
|
verify(mockTransitionRepository).startTransition(capture())
|
||||||
|
}
|
||||||
|
// THEN a transition to DOZING should occur
|
||||||
|
assertThat(info.ownerName).isEqualTo("FromLockscreenTransitionInteractor")
|
||||||
|
assertThat(info.from).isEqualTo(KeyguardState.LOCKSCREEN)
|
||||||
|
assertThat(info.to).isEqualTo(KeyguardState.DOZING)
|
||||||
|
assertThat(info.animator).isNotNull()
|
||||||
|
|
||||||
|
coroutineContext.cancelChildren()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `LOCKSCREEN to AOD`() =
|
||||||
|
testScope.runTest {
|
||||||
|
// GIVEN a device with AOD available
|
||||||
|
keyguardRepository.setAodAvailable(true)
|
||||||
|
runCurrent()
|
||||||
|
|
||||||
|
// GIVEN a prior transition has run to LOCKSCREEN
|
||||||
|
runner.startTransition(
|
||||||
|
testScope,
|
||||||
|
TransitionInfo(
|
||||||
|
ownerName = "",
|
||||||
|
from = KeyguardState.GONE,
|
||||||
|
to = KeyguardState.LOCKSCREEN,
|
||||||
|
animator =
|
||||||
|
ValueAnimator().apply {
|
||||||
|
duration = 10
|
||||||
|
interpolator = Interpolators.LINEAR
|
||||||
|
},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
runCurrent()
|
||||||
|
reset(mockTransitionRepository)
|
||||||
|
|
||||||
|
// WHEN the device begins to sleep
|
||||||
|
keyguardRepository.setWakefulnessModel(startingToSleep())
|
||||||
|
runCurrent()
|
||||||
|
|
||||||
|
val info =
|
||||||
|
withArgCaptor<TransitionInfo> {
|
||||||
|
verify(mockTransitionRepository).startTransition(capture())
|
||||||
|
}
|
||||||
|
// THEN a transition to DOZING should occur
|
||||||
|
assertThat(info.ownerName).isEqualTo("FromLockscreenTransitionInteractor")
|
||||||
|
assertThat(info.from).isEqualTo(KeyguardState.LOCKSCREEN)
|
||||||
|
assertThat(info.to).isEqualTo(KeyguardState.AOD)
|
||||||
|
assertThat(info.animator).isNotNull()
|
||||||
|
|
||||||
|
coroutineContext.cancelChildren()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `DOZING to LOCKSCREEN`() =
|
||||||
|
testScope.runTest {
|
||||||
|
// GIVEN a prior transition has run to DOZING
|
||||||
|
runner.startTransition(
|
||||||
|
testScope,
|
||||||
|
TransitionInfo(
|
||||||
|
ownerName = "",
|
||||||
|
from = KeyguardState.LOCKSCREEN,
|
||||||
|
to = KeyguardState.DOZING,
|
||||||
|
animator =
|
||||||
|
ValueAnimator().apply {
|
||||||
|
duration = 10
|
||||||
|
interpolator = Interpolators.LINEAR
|
||||||
|
},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
runCurrent()
|
||||||
|
reset(mockTransitionRepository)
|
||||||
|
|
||||||
|
// WHEN the device begins to wake
|
||||||
|
keyguardRepository.setWakefulnessModel(startingToWake())
|
||||||
|
runCurrent()
|
||||||
|
|
||||||
|
val info =
|
||||||
|
withArgCaptor<TransitionInfo> {
|
||||||
|
verify(mockTransitionRepository).startTransition(capture())
|
||||||
|
}
|
||||||
|
// THEN a transition to DOZING should occur
|
||||||
|
assertThat(info.ownerName).isEqualTo("FromDozingTransitionInteractor")
|
||||||
|
assertThat(info.from).isEqualTo(KeyguardState.DOZING)
|
||||||
|
assertThat(info.to).isEqualTo(KeyguardState.LOCKSCREEN)
|
||||||
|
assertThat(info.animator).isNotNull()
|
||||||
|
|
||||||
|
coroutineContext.cancelChildren()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `GONE to DOZING`() =
|
||||||
|
testScope.runTest {
|
||||||
|
// GIVEN a device with AOD not available
|
||||||
|
keyguardRepository.setAodAvailable(false)
|
||||||
|
runCurrent()
|
||||||
|
|
||||||
|
// GIVEN a prior transition has run to GONE
|
||||||
|
runner.startTransition(
|
||||||
|
testScope,
|
||||||
|
TransitionInfo(
|
||||||
|
ownerName = "",
|
||||||
|
from = KeyguardState.LOCKSCREEN,
|
||||||
|
to = KeyguardState.GONE,
|
||||||
|
animator =
|
||||||
|
ValueAnimator().apply {
|
||||||
|
duration = 10
|
||||||
|
interpolator = Interpolators.LINEAR
|
||||||
|
},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
runCurrent()
|
||||||
|
reset(mockTransitionRepository)
|
||||||
|
|
||||||
|
// WHEN the device begins to sleep
|
||||||
|
keyguardRepository.setWakefulnessModel(startingToSleep())
|
||||||
|
runCurrent()
|
||||||
|
|
||||||
|
val info =
|
||||||
|
withArgCaptor<TransitionInfo> {
|
||||||
|
verify(mockTransitionRepository).startTransition(capture())
|
||||||
|
}
|
||||||
|
// THEN a transition to DOZING should occur
|
||||||
|
assertThat(info.ownerName).isEqualTo("FromGoneTransitionInteractor")
|
||||||
|
assertThat(info.from).isEqualTo(KeyguardState.GONE)
|
||||||
|
assertThat(info.to).isEqualTo(KeyguardState.DOZING)
|
||||||
|
assertThat(info.animator).isNotNull()
|
||||||
|
|
||||||
|
coroutineContext.cancelChildren()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `GONE to AOD`() =
|
||||||
|
testScope.runTest {
|
||||||
|
// GIVEN a device with AOD available
|
||||||
|
keyguardRepository.setAodAvailable(true)
|
||||||
|
runCurrent()
|
||||||
|
|
||||||
|
// GIVEN a prior transition has run to GONE
|
||||||
|
runner.startTransition(
|
||||||
|
testScope,
|
||||||
|
TransitionInfo(
|
||||||
|
ownerName = "",
|
||||||
|
from = KeyguardState.LOCKSCREEN,
|
||||||
|
to = KeyguardState.GONE,
|
||||||
|
animator =
|
||||||
|
ValueAnimator().apply {
|
||||||
|
duration = 10
|
||||||
|
interpolator = Interpolators.LINEAR
|
||||||
|
},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
runCurrent()
|
||||||
|
reset(mockTransitionRepository)
|
||||||
|
|
||||||
|
// WHEN the device begins to sleep
|
||||||
|
keyguardRepository.setWakefulnessModel(startingToSleep())
|
||||||
|
runCurrent()
|
||||||
|
|
||||||
|
val info =
|
||||||
|
withArgCaptor<TransitionInfo> {
|
||||||
|
verify(mockTransitionRepository).startTransition(capture())
|
||||||
|
}
|
||||||
|
// THEN a transition to DOZING should occur
|
||||||
|
assertThat(info.ownerName).isEqualTo("FromGoneTransitionInteractor")
|
||||||
|
assertThat(info.from).isEqualTo(KeyguardState.GONE)
|
||||||
|
assertThat(info.to).isEqualTo(KeyguardState.AOD)
|
||||||
|
assertThat(info.animator).isNotNull()
|
||||||
|
|
||||||
|
coroutineContext.cancelChildren()
|
||||||
|
}
|
||||||
|
|
||||||
private fun startingToWake() =
|
private fun startingToWake() =
|
||||||
WakefulnessModel(
|
WakefulnessModel(
|
||||||
WakefulnessState.STARTING_TO_WAKE,
|
WakefulnessState.STARTING_TO_WAKE,
|
||||||
@@ -199,4 +522,12 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
|||||||
WakeSleepReason.OTHER,
|
WakeSleepReason.OTHER,
|
||||||
WakeSleepReason.OTHER
|
WakeSleepReason.OTHER
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private fun startingToSleep() =
|
||||||
|
WakefulnessModel(
|
||||||
|
WakefulnessState.STARTING_TO_SLEEP,
|
||||||
|
true,
|
||||||
|
WakeSleepReason.OTHER,
|
||||||
|
WakeSleepReason.OTHER
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,10 @@ import static org.junit.Assert.assertTrue;
|
|||||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
import static org.mockito.Mockito.doAnswer;
|
import static org.mockito.Mockito.doAnswer;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.reset;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
@@ -39,10 +43,9 @@ import com.android.systemui.SysuiTestCase;
|
|||||||
import com.android.systemui.doze.AlwaysOnDisplayPolicy;
|
import com.android.systemui.doze.AlwaysOnDisplayPolicy;
|
||||||
import com.android.systemui.doze.DozeScreenState;
|
import com.android.systemui.doze.DozeScreenState;
|
||||||
import com.android.systemui.dump.DumpManager;
|
import com.android.systemui.dump.DumpManager;
|
||||||
import com.android.systemui.flags.FeatureFlags;
|
|
||||||
import com.android.systemui.flags.Flags;
|
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||||
import com.android.systemui.statusbar.policy.BatteryController;
|
import com.android.systemui.statusbar.policy.BatteryController;
|
||||||
|
import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
|
||||||
import com.android.systemui.statusbar.policy.ConfigurationController;
|
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||||
import com.android.systemui.tuner.TunerService;
|
import com.android.systemui.tuner.TunerService;
|
||||||
import com.android.systemui.unfold.FoldAodAnimationController;
|
import com.android.systemui.unfold.FoldAodAnimationController;
|
||||||
@@ -52,6 +55,8 @@ import org.junit.Assert;
|
|||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.Captor;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
@@ -69,7 +74,6 @@ public class DozeParametersTest extends SysuiTestCase {
|
|||||||
@Mock private PowerManager mPowerManager;
|
@Mock private PowerManager mPowerManager;
|
||||||
@Mock private TunerService mTunerService;
|
@Mock private TunerService mTunerService;
|
||||||
@Mock private BatteryController mBatteryController;
|
@Mock private BatteryController mBatteryController;
|
||||||
@Mock private FeatureFlags mFeatureFlags;
|
|
||||||
@Mock private DumpManager mDumpManager;
|
@Mock private DumpManager mDumpManager;
|
||||||
@Mock private ScreenOffAnimationController mScreenOffAnimationController;
|
@Mock private ScreenOffAnimationController mScreenOffAnimationController;
|
||||||
@Mock private FoldAodAnimationController mFoldAodAnimationController;
|
@Mock private FoldAodAnimationController mFoldAodAnimationController;
|
||||||
@@ -78,6 +82,7 @@ public class DozeParametersTest extends SysuiTestCase {
|
|||||||
@Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
@Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||||
@Mock private StatusBarStateController mStatusBarStateController;
|
@Mock private StatusBarStateController mStatusBarStateController;
|
||||||
@Mock private ConfigurationController mConfigurationController;
|
@Mock private ConfigurationController mConfigurationController;
|
||||||
|
@Captor private ArgumentCaptor<BatteryStateChangeCallback> mBatteryStateChangeCallback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current value of PowerManager's dozeAfterScreenOff property.
|
* The current value of PowerManager's dozeAfterScreenOff property.
|
||||||
@@ -113,7 +118,6 @@ public class DozeParametersTest extends SysuiTestCase {
|
|||||||
mBatteryController,
|
mBatteryController,
|
||||||
mTunerService,
|
mTunerService,
|
||||||
mDumpManager,
|
mDumpManager,
|
||||||
mFeatureFlags,
|
|
||||||
mScreenOffAnimationController,
|
mScreenOffAnimationController,
|
||||||
Optional.of(mSysUIUnfoldComponent),
|
Optional.of(mSysUIUnfoldComponent),
|
||||||
mUnlockedScreenOffAnimationController,
|
mUnlockedScreenOffAnimationController,
|
||||||
@@ -122,7 +126,8 @@ public class DozeParametersTest extends SysuiTestCase {
|
|||||||
mStatusBarStateController
|
mStatusBarStateController
|
||||||
);
|
);
|
||||||
|
|
||||||
when(mFeatureFlags.isEnabled(Flags.LOCKSCREEN_ANIMATIONS)).thenReturn(true);
|
verify(mBatteryController).addCallback(mBatteryStateChangeCallback.capture());
|
||||||
|
|
||||||
setAodEnabledForTest(true);
|
setAodEnabledForTest(true);
|
||||||
setShouldControlUnlockedScreenOffForTest(true);
|
setShouldControlUnlockedScreenOffForTest(true);
|
||||||
setDisplayNeedsBlankingForTest(false);
|
setDisplayNeedsBlankingForTest(false);
|
||||||
@@ -173,6 +178,29 @@ public class DozeParametersTest extends SysuiTestCase {
|
|||||||
assertThat(mDozeParameters.getAlwaysOn()).isFalse();
|
assertThat(mDozeParameters.getAlwaysOn()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetAlwaysOn_whenBatterySaverCallback() {
|
||||||
|
DozeParameters.Callback callback = mock(DozeParameters.Callback.class);
|
||||||
|
mDozeParameters.addCallback(callback);
|
||||||
|
|
||||||
|
when(mAmbientDisplayConfiguration.alwaysOnEnabled(anyInt())).thenReturn(true);
|
||||||
|
when(mBatteryController.isAodPowerSave()).thenReturn(true);
|
||||||
|
|
||||||
|
// Both lines should trigger an event
|
||||||
|
mDozeParameters.onTuningChanged(Settings.Secure.DOZE_ALWAYS_ON, "1");
|
||||||
|
mBatteryStateChangeCallback.getValue().onPowerSaveChanged(true);
|
||||||
|
|
||||||
|
verify(callback, times(2)).onAlwaysOnChange();
|
||||||
|
assertThat(mDozeParameters.getAlwaysOn()).isFalse();
|
||||||
|
|
||||||
|
reset(callback);
|
||||||
|
when(mBatteryController.isAodPowerSave()).thenReturn(false);
|
||||||
|
mBatteryStateChangeCallback.getValue().onPowerSaveChanged(true);
|
||||||
|
|
||||||
|
verify(callback).onAlwaysOnChange();
|
||||||
|
assertThat(mDozeParameters.getAlwaysOn()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PowerManager.setDozeAfterScreenOff(true) means we are not controlling screen off, and calling
|
* PowerManager.setDozeAfterScreenOff(true) means we are not controlling screen off, and calling
|
||||||
* it with false means we are. Confusing, but sure - make sure that we call PowerManager with
|
* it with false means we are. Confusing, but sure - make sure that we call PowerManager with
|
||||||
@@ -195,17 +223,6 @@ public class DozeParametersTest extends SysuiTestCase {
|
|||||||
assertFalse(mPowerManagerDozeAfterScreenOff);
|
assertFalse(mPowerManagerDozeAfterScreenOff);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testControlUnlockedScreenOffAnimationDisabled_dozeAfterScreenOff() {
|
|
||||||
when(mFeatureFlags.isEnabled(Flags.LOCKSCREEN_ANIMATIONS)).thenReturn(false);
|
|
||||||
|
|
||||||
assertFalse(mDozeParameters.shouldControlUnlockedScreenOff());
|
|
||||||
|
|
||||||
// Trigger the setter for the current value.
|
|
||||||
mDozeParameters.setControlScreenOffAnimation(mDozeParameters.shouldControlScreenOff());
|
|
||||||
assertFalse(mDozeParameters.shouldControlScreenOff());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void propagatesAnimateScreenOff_noAlwaysOn() {
|
public void propagatesAnimateScreenOff_noAlwaysOn() {
|
||||||
setAodEnabledForTest(false);
|
setAodEnabledForTest(false);
|
||||||
|
|||||||
@@ -52,6 +52,9 @@ class FakeKeyguardRepository : KeyguardRepository {
|
|||||||
private val _isDozing = MutableStateFlow(false)
|
private val _isDozing = MutableStateFlow(false)
|
||||||
override val isDozing: Flow<Boolean> = _isDozing
|
override val isDozing: Flow<Boolean> = _isDozing
|
||||||
|
|
||||||
|
private val _isAodAvailable = MutableStateFlow(false)
|
||||||
|
override val isAodAvailable: Flow<Boolean> = _isAodAvailable
|
||||||
|
|
||||||
private val _isDreaming = MutableStateFlow(false)
|
private val _isDreaming = MutableStateFlow(false)
|
||||||
override val isDreaming: Flow<Boolean> = _isDreaming
|
override val isDreaming: Flow<Boolean> = _isDreaming
|
||||||
|
|
||||||
@@ -126,6 +129,10 @@ class FakeKeyguardRepository : KeyguardRepository {
|
|||||||
_isDozing.value = isDozing
|
_isDozing.value = isDozing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setAodAvailable(isAodAvailable: Boolean) {
|
||||||
|
_isAodAvailable.value = isAodAvailable
|
||||||
|
}
|
||||||
|
|
||||||
fun setDreamingWithOverlay(isDreaming: Boolean) {
|
fun setDreamingWithOverlay(isDreaming: Boolean) {
|
||||||
_isDreamingWithOverlay.value = isDreaming
|
_isDreamingWithOverlay.value = isDreaming
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user