Merge "[DO NOT MERGE] Transitions: LOCKSCREEN->DREAMING" into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
840c39460f
@@ -1279,6 +1279,12 @@
|
|||||||
<!-- OCCLUDED -> LOCKSCREEN transition: Amount to shift lockscreen content on entering -->
|
<!-- OCCLUDED -> LOCKSCREEN transition: Amount to shift lockscreen content on entering -->
|
||||||
<dimen name="occluded_to_lockscreen_transition_lockscreen_translation_y">40dp</dimen>
|
<dimen name="occluded_to_lockscreen_transition_lockscreen_translation_y">40dp</dimen>
|
||||||
|
|
||||||
|
<!-- LOCKSCREEN -> DREAMING transition: Amount to shift lockscreen content on entering -->
|
||||||
|
<dimen name="lockscreen_to_dreaming_transition_lockscreen_translation_y">-40dp</dimen>
|
||||||
|
|
||||||
|
<!-- LOCKSCREEN -> OCCLUDED transition: Amount to shift lockscreen content on entering -->
|
||||||
|
<dimen name="lockscreen_to_occluded_transition_lockscreen_translation_y">-40dp</dimen>
|
||||||
|
|
||||||
<!-- The amount of vertical offset for the keyguard during the full shade transition. -->
|
<!-- The amount of vertical offset for the keyguard during the full shade transition. -->
|
||||||
<dimen name="lockscreen_shade_keyguard_transition_vertical_offset">0dp</dimen>
|
<dimen name="lockscreen_shade_keyguard_transition_vertical_offset">0dp</dimen>
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STR
|
|||||||
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE;
|
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE;
|
||||||
import static com.android.systemui.DejankUtils.whitelistIpcs;
|
import static com.android.systemui.DejankUtils.whitelistIpcs;
|
||||||
import static com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel.LOCKSCREEN_ANIMATION_DURATION_MS;
|
import static com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel.LOCKSCREEN_ANIMATION_DURATION_MS;
|
||||||
|
import static com.android.systemui.keyguard.ui.viewmodel.LockscreenToDreamingTransitionViewModel.DREAMING_ANIMATION_DURATION_MS;
|
||||||
|
|
||||||
import android.animation.Animator;
|
import android.animation.Animator;
|
||||||
import android.animation.AnimatorListenerAdapter;
|
import android.animation.AnimatorListenerAdapter;
|
||||||
@@ -122,6 +123,8 @@ import com.android.systemui.classifier.FalsingCollector;
|
|||||||
import com.android.systemui.dagger.qualifiers.UiBackground;
|
import com.android.systemui.dagger.qualifiers.UiBackground;
|
||||||
import com.android.systemui.dreams.DreamOverlayStateController;
|
import com.android.systemui.dreams.DreamOverlayStateController;
|
||||||
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.keyguard.dagger.KeyguardModule;
|
import com.android.systemui.keyguard.dagger.KeyguardModule;
|
||||||
import com.android.systemui.navigationbar.NavigationModeController;
|
import com.android.systemui.navigationbar.NavigationModeController;
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||||
@@ -507,6 +510,8 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
|
|||||||
|
|
||||||
private CentralSurfaces mCentralSurfaces;
|
private CentralSurfaces mCentralSurfaces;
|
||||||
|
|
||||||
|
private boolean mUnocclusionTransitionFlagEnabled = false;
|
||||||
|
|
||||||
private final DeviceConfig.OnPropertiesChangedListener mOnPropertiesChangedListener =
|
private final DeviceConfig.OnPropertiesChangedListener mOnPropertiesChangedListener =
|
||||||
new DeviceConfig.OnPropertiesChangedListener() {
|
new DeviceConfig.OnPropertiesChangedListener() {
|
||||||
@Override
|
@Override
|
||||||
@@ -958,8 +963,9 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
|
|||||||
public void onAnimationStart(int transit, RemoteAnimationTarget[] apps,
|
public void onAnimationStart(int transit, RemoteAnimationTarget[] apps,
|
||||||
RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
|
RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
|
||||||
IRemoteAnimationFinishedCallback finishedCallback) throws RemoteException {
|
IRemoteAnimationFinishedCallback finishedCallback) throws RemoteException {
|
||||||
|
if (!mUnocclusionTransitionFlagEnabled) {
|
||||||
setOccluded(true /* isOccluded */, true /* animate */);
|
setOccluded(true /* isOccluded */, true /* animate */);
|
||||||
|
}
|
||||||
if (apps == null || apps.length == 0 || apps[0] == null) {
|
if (apps == null || apps.length == 0 || apps[0] == null) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "No apps provided to the OccludeByDream runner; "
|
Log.d(TAG, "No apps provided to the OccludeByDream runner; "
|
||||||
@@ -1001,9 +1007,20 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
|
|||||||
applier.scheduleApply(paramsBuilder.build());
|
applier.scheduleApply(paramsBuilder.build());
|
||||||
});
|
});
|
||||||
mOccludeByDreamAnimator.addListener(new AnimatorListenerAdapter() {
|
mOccludeByDreamAnimator.addListener(new AnimatorListenerAdapter() {
|
||||||
|
private boolean mIsCancelled = false;
|
||||||
|
@Override
|
||||||
|
public void onAnimationCancel(Animator animation) {
|
||||||
|
mIsCancelled = true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAnimationEnd(Animator animation) {
|
public void onAnimationEnd(Animator animation) {
|
||||||
try {
|
try {
|
||||||
|
if (!mIsCancelled && mUnocclusionTransitionFlagEnabled) {
|
||||||
|
// We're already on the main thread, don't queue this call
|
||||||
|
handleSetOccluded(true /* isOccluded */,
|
||||||
|
false /* animate */);
|
||||||
|
}
|
||||||
finishedCallback.onAnimationFinished();
|
finishedCallback.onAnimationFinished();
|
||||||
mOccludeByDreamAnimator = null;
|
mOccludeByDreamAnimator = null;
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
@@ -1176,6 +1193,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
|
|||||||
ScreenOnCoordinator screenOnCoordinator,
|
ScreenOnCoordinator screenOnCoordinator,
|
||||||
InteractionJankMonitor interactionJankMonitor,
|
InteractionJankMonitor interactionJankMonitor,
|
||||||
DreamOverlayStateController dreamOverlayStateController,
|
DreamOverlayStateController dreamOverlayStateController,
|
||||||
|
FeatureFlags featureFlags,
|
||||||
Lazy<ShadeController> shadeControllerLazy,
|
Lazy<ShadeController> shadeControllerLazy,
|
||||||
Lazy<NotificationShadeWindowController> notificationShadeWindowControllerLazy,
|
Lazy<NotificationShadeWindowController> notificationShadeWindowControllerLazy,
|
||||||
Lazy<ActivityLaunchAnimator> activityLaunchAnimator,
|
Lazy<ActivityLaunchAnimator> activityLaunchAnimator,
|
||||||
@@ -1230,9 +1248,9 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
|
|||||||
R.dimen.physical_power_button_center_screen_location_y);
|
R.dimen.physical_power_button_center_screen_location_y);
|
||||||
mWindowCornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(context);
|
mWindowCornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(context);
|
||||||
|
|
||||||
mDreamOpenAnimationDuration = context.getResources().getInteger(
|
mDreamOpenAnimationDuration = (int) DREAMING_ANIMATION_DURATION_MS;
|
||||||
com.android.internal.R.integer.config_dreamOpenAnimationDuration);
|
|
||||||
mDreamCloseAnimationDuration = (int) LOCKSCREEN_ANIMATION_DURATION_MS;
|
mDreamCloseAnimationDuration = (int) LOCKSCREEN_ANIMATION_DURATION_MS;
|
||||||
|
mUnocclusionTransitionFlagEnabled = featureFlags.isEnabled(Flags.UNOCCLUSION_TRANSITION);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void userActivity() {
|
public void userActivity() {
|
||||||
@@ -1792,7 +1810,6 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
|
|||||||
|
|
||||||
Trace.beginSection("KeyguardViewMediator#setOccluded");
|
Trace.beginSection("KeyguardViewMediator#setOccluded");
|
||||||
if (DEBUG) Log.d(TAG, "setOccluded " + isOccluded);
|
if (DEBUG) Log.d(TAG, "setOccluded " + isOccluded);
|
||||||
mInteractionJankMonitor.cancel(CUJ_LOCKSCREEN_TRANSITION_FROM_AOD);
|
|
||||||
mHandler.removeMessages(SET_OCCLUDED);
|
mHandler.removeMessages(SET_OCCLUDED);
|
||||||
Message msg = mHandler.obtainMessage(SET_OCCLUDED, isOccluded ? 1 : 0, animate ? 1 : 0);
|
Message msg = mHandler.obtainMessage(SET_OCCLUDED, isOccluded ? 1 : 0, animate ? 1 : 0);
|
||||||
mHandler.sendMessage(msg);
|
mHandler.sendMessage(msg);
|
||||||
@@ -1825,6 +1842,8 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
|
|||||||
private void handleSetOccluded(boolean isOccluded, boolean animate) {
|
private void handleSetOccluded(boolean isOccluded, boolean animate) {
|
||||||
Trace.beginSection("KeyguardViewMediator#handleSetOccluded");
|
Trace.beginSection("KeyguardViewMediator#handleSetOccluded");
|
||||||
Log.d(TAG, "handleSetOccluded(" + isOccluded + ")");
|
Log.d(TAG, "handleSetOccluded(" + isOccluded + ")");
|
||||||
|
mInteractionJankMonitor.cancel(CUJ_LOCKSCREEN_TRANSITION_FROM_AOD);
|
||||||
|
|
||||||
synchronized (KeyguardViewMediator.this) {
|
synchronized (KeyguardViewMediator.this) {
|
||||||
if (mHiding && isOccluded) {
|
if (mHiding && isOccluded) {
|
||||||
// We're in the process of going away but WindowManager wants to show a
|
// We're in the process of going away but WindowManager wants to show a
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import com.android.systemui.dagger.SysUISingleton;
|
|||||||
import com.android.systemui.dagger.qualifiers.UiBackground;
|
import com.android.systemui.dagger.qualifiers.UiBackground;
|
||||||
import com.android.systemui.dreams.DreamOverlayStateController;
|
import com.android.systemui.dreams.DreamOverlayStateController;
|
||||||
import com.android.systemui.dump.DumpManager;
|
import com.android.systemui.dump.DumpManager;
|
||||||
|
import com.android.systemui.flags.FeatureFlags;
|
||||||
import com.android.systemui.keyguard.DismissCallbackRegistry;
|
import com.android.systemui.keyguard.DismissCallbackRegistry;
|
||||||
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
||||||
import com.android.systemui.keyguard.KeyguardViewMediator;
|
import com.android.systemui.keyguard.KeyguardViewMediator;
|
||||||
@@ -112,6 +113,7 @@ public class KeyguardModule {
|
|||||||
ScreenOnCoordinator screenOnCoordinator,
|
ScreenOnCoordinator screenOnCoordinator,
|
||||||
InteractionJankMonitor interactionJankMonitor,
|
InteractionJankMonitor interactionJankMonitor,
|
||||||
DreamOverlayStateController dreamOverlayStateController,
|
DreamOverlayStateController dreamOverlayStateController,
|
||||||
|
FeatureFlags featureFlags,
|
||||||
Lazy<ShadeController> shadeController,
|
Lazy<ShadeController> shadeController,
|
||||||
Lazy<NotificationShadeWindowController> notificationShadeWindowController,
|
Lazy<NotificationShadeWindowController> notificationShadeWindowController,
|
||||||
Lazy<ActivityLaunchAnimator> activityLaunchAnimator,
|
Lazy<ActivityLaunchAnimator> activityLaunchAnimator,
|
||||||
@@ -142,6 +144,7 @@ public class KeyguardModule {
|
|||||||
screenOnCoordinator,
|
screenOnCoordinator,
|
||||||
interactionJankMonitor,
|
interactionJankMonitor,
|
||||||
dreamOverlayStateController,
|
dreamOverlayStateController,
|
||||||
|
featureFlags,
|
||||||
shadeController,
|
shadeController,
|
||||||
notificationShadeWindowController,
|
notificationShadeWindowController,
|
||||||
activityLaunchAnimator,
|
activityLaunchAnimator,
|
||||||
|
|||||||
@@ -135,11 +135,14 @@ class KeyguardTransitionRepositoryImpl @Inject constructor() : KeyguardTransitio
|
|||||||
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
|
||||||
}
|
}
|
||||||
|
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
|
||||||
|
} else {
|
||||||
|
0f
|
||||||
}
|
}
|
||||||
|
|
||||||
val startingValue = 1f - lastStep.value
|
|
||||||
lastAnimator?.cancel()
|
lastAnimator?.cancel()
|
||||||
lastAnimator = info.animator
|
lastAnimator = info.animator
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ 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
|
||||||
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.collect
|
import kotlinx.coroutines.flow.collect
|
||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
@@ -51,6 +53,7 @@ constructor(
|
|||||||
override fun start() {
|
override fun start() {
|
||||||
listenForLockscreenToGone()
|
listenForLockscreenToGone()
|
||||||
listenForLockscreenToOccluded()
|
listenForLockscreenToOccluded()
|
||||||
|
listenForLockscreenToCamera()
|
||||||
listenForLockscreenToAod()
|
listenForLockscreenToAod()
|
||||||
listenForLockscreenToBouncer()
|
listenForLockscreenToBouncer()
|
||||||
listenForLockscreenToDreaming()
|
listenForLockscreenToDreaming()
|
||||||
@@ -69,7 +72,7 @@ constructor(
|
|||||||
name,
|
name,
|
||||||
KeyguardState.LOCKSCREEN,
|
KeyguardState.LOCKSCREEN,
|
||||||
KeyguardState.DREAMING,
|
KeyguardState.DREAMING,
|
||||||
getAnimator(),
|
getAnimator(TO_DREAMING_DURATION),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -184,17 +187,42 @@ constructor(
|
|||||||
),
|
),
|
||||||
::toTriple
|
::toTriple
|
||||||
)
|
)
|
||||||
.collect { triple ->
|
.collect { (isOccluded, keyguardState, isDreaming) ->
|
||||||
val (isOccluded, keyguardState, isDreaming) = triple
|
if (isOccluded && !isDreaming && keyguardState == KeyguardState.LOCKSCREEN) {
|
||||||
// Occlusion signals come from the framework, and should interrupt any
|
|
||||||
// existing transition
|
|
||||||
if (isOccluded && !isDreaming) {
|
|
||||||
keyguardTransitionRepository.startTransition(
|
keyguardTransitionRepository.startTransition(
|
||||||
TransitionInfo(
|
TransitionInfo(
|
||||||
name,
|
name,
|
||||||
keyguardState,
|
keyguardState,
|
||||||
KeyguardState.OCCLUDED,
|
KeyguardState.OCCLUDED,
|
||||||
getAnimator(),
|
getAnimator(TO_OCCLUDED_DURATION),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** This signal may come in before the occlusion signal, and can provide a custom transition */
|
||||||
|
private fun listenForLockscreenToCamera() {
|
||||||
|
scope.launch {
|
||||||
|
keyguardInteractor.onCameraLaunchDetected
|
||||||
|
.sample(keyguardTransitionInteractor.startedKeyguardTransitionStep, ::Pair)
|
||||||
|
.collect { (_, lastStartedStep) ->
|
||||||
|
// DREAMING/AOD/OFF may trigger on the first power button push, so include this
|
||||||
|
// state in order to cancel and correct the transition
|
||||||
|
if (
|
||||||
|
lastStartedStep.to == KeyguardState.LOCKSCREEN ||
|
||||||
|
lastStartedStep.to == KeyguardState.DREAMING ||
|
||||||
|
lastStartedStep.to == KeyguardState.DOZING ||
|
||||||
|
lastStartedStep.to == KeyguardState.AOD ||
|
||||||
|
lastStartedStep.to == KeyguardState.OFF
|
||||||
|
) {
|
||||||
|
keyguardTransitionRepository.startTransition(
|
||||||
|
TransitionInfo(
|
||||||
|
name,
|
||||||
|
KeyguardState.LOCKSCREEN,
|
||||||
|
KeyguardState.OCCLUDED,
|
||||||
|
getAnimator(TO_OCCLUDED_DURATION),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -223,14 +251,16 @@ 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
|
||||||
|
val TO_OCCLUDED_DURATION = 450.milliseconds
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,17 +17,24 @@
|
|||||||
|
|
||||||
package com.android.systemui.keyguard.domain.interactor
|
package com.android.systemui.keyguard.domain.interactor
|
||||||
|
|
||||||
|
import android.app.StatusBarManager
|
||||||
import android.graphics.Point
|
import android.graphics.Point
|
||||||
|
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
|
||||||
|
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
|
||||||
import com.android.systemui.dagger.SysUISingleton
|
import com.android.systemui.dagger.SysUISingleton
|
||||||
import com.android.systemui.keyguard.data.repository.KeyguardRepository
|
import com.android.systemui.keyguard.data.repository.KeyguardRepository
|
||||||
import com.android.systemui.keyguard.shared.model.BiometricUnlockModel
|
import com.android.systemui.keyguard.shared.model.BiometricUnlockModel
|
||||||
|
import com.android.systemui.keyguard.shared.model.CameraLaunchSourceModel
|
||||||
import com.android.systemui.keyguard.shared.model.DozeStateModel
|
import com.android.systemui.keyguard.shared.model.DozeStateModel
|
||||||
import com.android.systemui.keyguard.shared.model.DozeStateModel.Companion.isDozeOff
|
import com.android.systemui.keyguard.shared.model.DozeStateModel.Companion.isDozeOff
|
||||||
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.statusbar.CommandQueue
|
||||||
|
import com.android.systemui.statusbar.CommandQueue.Callbacks
|
||||||
import com.android.systemui.util.kotlin.sample
|
import com.android.systemui.util.kotlin.sample
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import kotlinx.coroutines.channels.awaitClose
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
import kotlinx.coroutines.flow.filter
|
import kotlinx.coroutines.flow.filter
|
||||||
@@ -41,6 +48,7 @@ class KeyguardInteractor
|
|||||||
@Inject
|
@Inject
|
||||||
constructor(
|
constructor(
|
||||||
private val repository: KeyguardRepository,
|
private val repository: KeyguardRepository,
|
||||||
|
private val commandQueue: CommandQueue,
|
||||||
) {
|
) {
|
||||||
/**
|
/**
|
||||||
* The amount of doze the system is in, where `1.0` is fully dozing and `0.0` is not dozing at
|
* The amount of doze the system is in, where `1.0` is fully dozing and `0.0` is not dozing at
|
||||||
@@ -58,6 +66,23 @@ constructor(
|
|||||||
val isDreaming: Flow<Boolean> = repository.isDreaming
|
val isDreaming: Flow<Boolean> = repository.isDreaming
|
||||||
/** Whether the system is dreaming with an overlay active */
|
/** Whether the system is dreaming with an overlay active */
|
||||||
val isDreamingWithOverlay: Flow<Boolean> = repository.isDreamingWithOverlay
|
val isDreamingWithOverlay: Flow<Boolean> = repository.isDreamingWithOverlay
|
||||||
|
/** Event for when the camera gesture is detected */
|
||||||
|
val onCameraLaunchDetected: Flow<CameraLaunchSourceModel> = conflatedCallbackFlow {
|
||||||
|
val callback =
|
||||||
|
object : CommandQueue.Callbacks {
|
||||||
|
override fun onCameraLaunchGestureDetected(source: Int) {
|
||||||
|
trySendWithFailureLogging(
|
||||||
|
cameraLaunchSourceIntToModel(source),
|
||||||
|
TAG,
|
||||||
|
"updated onCameraLaunchGestureDetected"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
commandQueue.addCallback(callback)
|
||||||
|
|
||||||
|
awaitClose { commandQueue.removeCallback(callback) }
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
@@ -103,4 +128,21 @@ constructor(
|
|||||||
fun isKeyguardShowing(): Boolean {
|
fun isKeyguardShowing(): Boolean {
|
||||||
return repository.isKeyguardShowing()
|
return repository.isKeyguardShowing()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun cameraLaunchSourceIntToModel(value: Int): CameraLaunchSourceModel {
|
||||||
|
return when (value) {
|
||||||
|
StatusBarManager.CAMERA_LAUNCH_SOURCE_WIGGLE -> CameraLaunchSourceModel.WIGGLE
|
||||||
|
StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP ->
|
||||||
|
CameraLaunchSourceModel.POWER_DOUBLE_TAP
|
||||||
|
StatusBarManager.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER ->
|
||||||
|
CameraLaunchSourceModel.LIFT_TRIGGER
|
||||||
|
StatusBarManager.CAMERA_LAUNCH_SOURCE_QUICK_AFFORDANCE ->
|
||||||
|
CameraLaunchSourceModel.QUICK_AFFORDANCE
|
||||||
|
else -> throw IllegalArgumentException("Invalid CameraLaunchSourceModel value: $value")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "KeyguardInteractor"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,24 +42,32 @@ class KeyguardTransitionInteractor
|
|||||||
constructor(
|
constructor(
|
||||||
repository: KeyguardTransitionRepository,
|
repository: KeyguardTransitionRepository,
|
||||||
) {
|
) {
|
||||||
|
/** (any)->AOD transition information */
|
||||||
|
val anyStateToAodTransition: Flow<TransitionStep> =
|
||||||
|
repository.transitions.filter { step -> step.to == KeyguardState.AOD }
|
||||||
|
|
||||||
/** AOD->LOCKSCREEN transition information. */
|
/** AOD->LOCKSCREEN transition information. */
|
||||||
val aodToLockscreenTransition: Flow<TransitionStep> = repository.transition(AOD, LOCKSCREEN)
|
val aodToLockscreenTransition: Flow<TransitionStep> = repository.transition(AOD, LOCKSCREEN)
|
||||||
|
|
||||||
/** LOCKSCREEN->AOD transition information. */
|
|
||||||
val lockscreenToAodTransition: Flow<TransitionStep> = repository.transition(LOCKSCREEN, AOD)
|
|
||||||
|
|
||||||
/** DREAMING->LOCKSCREEN transition information. */
|
/** DREAMING->LOCKSCREEN transition information. */
|
||||||
val dreamingToLockscreenTransition: Flow<TransitionStep> =
|
val dreamingToLockscreenTransition: Flow<TransitionStep> =
|
||||||
repository.transition(DREAMING, LOCKSCREEN)
|
repository.transition(DREAMING, LOCKSCREEN)
|
||||||
|
|
||||||
|
/** LOCKSCREEN->AOD transition information. */
|
||||||
|
val lockscreenToAodTransition: Flow<TransitionStep> = repository.transition(LOCKSCREEN, AOD)
|
||||||
|
|
||||||
|
/** LOCKSCREEN->DREAMING transition information. */
|
||||||
|
val lockscreenToDreamingTransition: Flow<TransitionStep> =
|
||||||
|
repository.transition(LOCKSCREEN, DREAMING)
|
||||||
|
|
||||||
|
/** LOCKSCREEN->OCCLUDED transition information. */
|
||||||
|
val lockscreenToOccludedTransition: Flow<TransitionStep> =
|
||||||
|
repository.transition(LOCKSCREEN, OCCLUDED)
|
||||||
|
|
||||||
/** OCCLUDED->LOCKSCREEN transition information. */
|
/** OCCLUDED->LOCKSCREEN transition information. */
|
||||||
val occludedToLockscreenTransition: Flow<TransitionStep> =
|
val occludedToLockscreenTransition: Flow<TransitionStep> =
|
||||||
repository.transition(OCCLUDED, LOCKSCREEN)
|
repository.transition(OCCLUDED, LOCKSCREEN)
|
||||||
|
|
||||||
/** (any)->AOD transition information */
|
|
||||||
val anyStateToAodTransition: Flow<TransitionStep> =
|
|
||||||
repository.transitions.filter { step -> step.to == KeyguardState.AOD }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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).
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License
|
||||||
|
*/
|
||||||
|
package com.android.systemui.keyguard.shared.model
|
||||||
|
|
||||||
|
/** Camera launch sources */
|
||||||
|
enum class CameraLaunchSourceModel {
|
||||||
|
/** Device is wiggled */
|
||||||
|
WIGGLE,
|
||||||
|
/** Power button has been double tapped */
|
||||||
|
POWER_DOUBLE_TAP,
|
||||||
|
/** Device has been lifted */
|
||||||
|
LIFT_TRIGGER,
|
||||||
|
/** Quick affordance button has been pressed */
|
||||||
|
QUICK_AFFORDANCE,
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* 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.FromLockscreenTransitionInteractor.Companion.TO_DREAMING_DURATION
|
||||||
|
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
|
||||||
|
import com.android.systemui.keyguard.shared.model.AnimationParams
|
||||||
|
import com.android.systemui.keyguard.shared.model.TransitionState
|
||||||
|
import javax.inject.Inject
|
||||||
|
import kotlin.time.Duration.Companion.milliseconds
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.filter
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
import kotlinx.coroutines.flow.merge
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Breaks down LOCKSCREEN->DREAMING transition into discrete steps for corresponding views to
|
||||||
|
* consume.
|
||||||
|
*/
|
||||||
|
@SysUISingleton
|
||||||
|
class LockscreenToDreamingTransitionViewModel
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
|
private val interactor: KeyguardTransitionInteractor,
|
||||||
|
) {
|
||||||
|
|
||||||
|
/** Lockscreen views y-translation */
|
||||||
|
fun lockscreenTranslationY(translatePx: Int): Flow<Float> {
|
||||||
|
return merge(
|
||||||
|
flowForAnimation(LOCKSCREEN_TRANSLATION_Y).map { value ->
|
||||||
|
(EMPHASIZED_ACCELERATE.getInterpolation(value) * translatePx)
|
||||||
|
},
|
||||||
|
// On end, reset the translation to 0
|
||||||
|
interactor.lockscreenToDreamingTransition
|
||||||
|
.filter { step -> step.transitionState == TransitionState.FINISHED }
|
||||||
|
.map { 0f }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Lockscreen views alpha */
|
||||||
|
val lockscreenAlpha: Flow<Float> = flowForAnimation(LOCKSCREEN_ALPHA).map { 1f - it }
|
||||||
|
|
||||||
|
private fun flowForAnimation(params: AnimationParams): Flow<Float> {
|
||||||
|
return interactor.transitionStepAnimation(
|
||||||
|
interactor.lockscreenToDreamingTransition,
|
||||||
|
params,
|
||||||
|
totalDuration = TO_DREAMING_DURATION
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmField val DREAMING_ANIMATION_DURATION_MS = TO_DREAMING_DURATION.inWholeMilliseconds
|
||||||
|
|
||||||
|
val LOCKSCREEN_TRANSLATION_Y = AnimationParams(duration = 500.milliseconds)
|
||||||
|
val LOCKSCREEN_ALPHA = AnimationParams(duration = 250.milliseconds)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* 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.FromLockscreenTransitionInteractor.Companion.TO_OCCLUDED_DURATION
|
||||||
|
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
|
||||||
|
import com.android.systemui.keyguard.shared.model.AnimationParams
|
||||||
|
import com.android.systemui.keyguard.shared.model.TransitionState
|
||||||
|
import javax.inject.Inject
|
||||||
|
import kotlin.time.Duration.Companion.milliseconds
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.filter
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
import kotlinx.coroutines.flow.merge
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Breaks down LOCKSCREEN->OCCLUDED transition into discrete steps for corresponding views to
|
||||||
|
* consume.
|
||||||
|
*/
|
||||||
|
@SysUISingleton
|
||||||
|
class LockscreenToOccludedTransitionViewModel
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
|
private val interactor: KeyguardTransitionInteractor,
|
||||||
|
) {
|
||||||
|
|
||||||
|
/** Lockscreen views y-translation */
|
||||||
|
fun lockscreenTranslationY(translatePx: Int): Flow<Float> {
|
||||||
|
return merge(
|
||||||
|
flowForAnimation(LOCKSCREEN_TRANSLATION_Y).map { value ->
|
||||||
|
(EMPHASIZED_ACCELERATE.getInterpolation(value) * translatePx)
|
||||||
|
},
|
||||||
|
// On end, reset the translation to 0
|
||||||
|
interactor.lockscreenToOccludedTransition
|
||||||
|
.filter { step -> step.transitionState == TransitionState.FINISHED }
|
||||||
|
.map { 0f }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Lockscreen views alpha */
|
||||||
|
val lockscreenAlpha: Flow<Float> = flowForAnimation(LOCKSCREEN_ALPHA).map { 1f - it }
|
||||||
|
|
||||||
|
private fun flowForAnimation(params: AnimationParams): Flow<Float> {
|
||||||
|
return interactor.transitionStepAnimation(
|
||||||
|
interactor.lockscreenToOccludedTransition,
|
||||||
|
params,
|
||||||
|
totalDuration = TO_OCCLUDED_DURATION
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val LOCKSCREEN_TRANSLATION_Y = AnimationParams(duration = TO_OCCLUDED_DURATION)
|
||||||
|
val LOCKSCREEN_ALPHA = AnimationParams(duration = 250.milliseconds)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -144,6 +144,8 @@ 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.viewmodel.DreamingToLockscreenTransitionViewModel;
|
import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel;
|
||||||
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel;
|
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel;
|
||||||
|
import com.android.systemui.keyguard.ui.viewmodel.LockscreenToDreamingTransitionViewModel;
|
||||||
|
import com.android.systemui.keyguard.ui.viewmodel.LockscreenToOccludedTransitionViewModel;
|
||||||
import com.android.systemui.keyguard.ui.viewmodel.OccludedToLockscreenTransitionViewModel;
|
import com.android.systemui.keyguard.ui.viewmodel.OccludedToLockscreenTransitionViewModel;
|
||||||
import com.android.systemui.media.controls.pipeline.MediaDataManager;
|
import com.android.systemui.media.controls.pipeline.MediaDataManager;
|
||||||
import com.android.systemui.media.controls.ui.KeyguardMediaController;
|
import com.android.systemui.media.controls.ui.KeyguardMediaController;
|
||||||
@@ -687,12 +689,16 @@ public final class NotificationPanelViewController implements Dumpable {
|
|||||||
private boolean mExpandLatencyTracking;
|
private boolean mExpandLatencyTracking;
|
||||||
private DreamingToLockscreenTransitionViewModel mDreamingToLockscreenTransitionViewModel;
|
private DreamingToLockscreenTransitionViewModel mDreamingToLockscreenTransitionViewModel;
|
||||||
private OccludedToLockscreenTransitionViewModel mOccludedToLockscreenTransitionViewModel;
|
private OccludedToLockscreenTransitionViewModel mOccludedToLockscreenTransitionViewModel;
|
||||||
|
private LockscreenToDreamingTransitionViewModel mLockscreenToDreamingTransitionViewModel;
|
||||||
|
private LockscreenToOccludedTransitionViewModel mLockscreenToOccludedTransitionViewModel;
|
||||||
|
|
||||||
private KeyguardTransitionInteractor mKeyguardTransitionInteractor;
|
private KeyguardTransitionInteractor mKeyguardTransitionInteractor;
|
||||||
private CoroutineDispatcher mMainDispatcher;
|
private CoroutineDispatcher mMainDispatcher;
|
||||||
private boolean mIsToLockscreenTransitionRunning = false;
|
private boolean mIsOcclusionTransitionRunning = false;
|
||||||
private int mDreamingToLockscreenTransitionTranslationY;
|
private int mDreamingToLockscreenTransitionTranslationY;
|
||||||
private int mOccludedToLockscreenTransitionTranslationY;
|
private int mOccludedToLockscreenTransitionTranslationY;
|
||||||
|
private int mLockscreenToDreamingTransitionTranslationY;
|
||||||
|
private int mLockscreenToOccludedTransitionTranslationY;
|
||||||
private boolean mUnocclusionTransitionFlagEnabled = false;
|
private boolean mUnocclusionTransitionFlagEnabled = false;
|
||||||
|
|
||||||
private final Runnable mFlingCollapseRunnable = () -> fling(0, false /* expand */,
|
private final Runnable mFlingCollapseRunnable = () -> fling(0, false /* expand */,
|
||||||
@@ -711,13 +717,25 @@ public final class NotificationPanelViewController implements Dumpable {
|
|||||||
|
|
||||||
private final Consumer<TransitionStep> mDreamingToLockscreenTransition =
|
private final Consumer<TransitionStep> mDreamingToLockscreenTransition =
|
||||||
(TransitionStep step) -> {
|
(TransitionStep step) -> {
|
||||||
mIsToLockscreenTransitionRunning =
|
mIsOcclusionTransitionRunning =
|
||||||
step.getTransitionState() == TransitionState.RUNNING;
|
step.getTransitionState() == TransitionState.RUNNING;
|
||||||
};
|
};
|
||||||
|
|
||||||
private final Consumer<TransitionStep> mOccludedToLockscreenTransition =
|
private final Consumer<TransitionStep> mOccludedToLockscreenTransition =
|
||||||
(TransitionStep step) -> {
|
(TransitionStep step) -> {
|
||||||
mIsToLockscreenTransitionRunning =
|
mIsOcclusionTransitionRunning =
|
||||||
|
step.getTransitionState() == TransitionState.RUNNING;
|
||||||
|
};
|
||||||
|
|
||||||
|
private final Consumer<TransitionStep> mLockscreenToDreamingTransition =
|
||||||
|
(TransitionStep step) -> {
|
||||||
|
mIsOcclusionTransitionRunning =
|
||||||
|
step.getTransitionState() == TransitionState.RUNNING;
|
||||||
|
};
|
||||||
|
|
||||||
|
private final Consumer<TransitionStep> mLockscreenToOccludedTransition =
|
||||||
|
(TransitionStep step) -> {
|
||||||
|
mIsOcclusionTransitionRunning =
|
||||||
step.getTransitionState() == TransitionState.RUNNING;
|
step.getTransitionState() == TransitionState.RUNNING;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -791,6 +809,8 @@ public final class NotificationPanelViewController implements Dumpable {
|
|||||||
KeyguardBottomAreaInteractor keyguardBottomAreaInteractor,
|
KeyguardBottomAreaInteractor keyguardBottomAreaInteractor,
|
||||||
DreamingToLockscreenTransitionViewModel dreamingToLockscreenTransitionViewModel,
|
DreamingToLockscreenTransitionViewModel dreamingToLockscreenTransitionViewModel,
|
||||||
OccludedToLockscreenTransitionViewModel occludedToLockscreenTransitionViewModel,
|
OccludedToLockscreenTransitionViewModel occludedToLockscreenTransitionViewModel,
|
||||||
|
LockscreenToDreamingTransitionViewModel lockscreenToDreamingTransitionViewModel,
|
||||||
|
LockscreenToOccludedTransitionViewModel lockscreenToOccludedTransitionViewModel,
|
||||||
@Main CoroutineDispatcher mainDispatcher,
|
@Main CoroutineDispatcher mainDispatcher,
|
||||||
KeyguardTransitionInteractor keyguardTransitionInteractor,
|
KeyguardTransitionInteractor keyguardTransitionInteractor,
|
||||||
DumpManager dumpManager) {
|
DumpManager dumpManager) {
|
||||||
@@ -810,6 +830,8 @@ public final class NotificationPanelViewController implements Dumpable {
|
|||||||
mGutsManager = gutsManager;
|
mGutsManager = gutsManager;
|
||||||
mDreamingToLockscreenTransitionViewModel = dreamingToLockscreenTransitionViewModel;
|
mDreamingToLockscreenTransitionViewModel = dreamingToLockscreenTransitionViewModel;
|
||||||
mOccludedToLockscreenTransitionViewModel = occludedToLockscreenTransitionViewModel;
|
mOccludedToLockscreenTransitionViewModel = occludedToLockscreenTransitionViewModel;
|
||||||
|
mLockscreenToDreamingTransitionViewModel = lockscreenToDreamingTransitionViewModel;
|
||||||
|
mLockscreenToOccludedTransitionViewModel = lockscreenToOccludedTransitionViewModel;
|
||||||
mKeyguardTransitionInteractor = keyguardTransitionInteractor;
|
mKeyguardTransitionInteractor = keyguardTransitionInteractor;
|
||||||
mView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
|
mView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
@@ -1117,22 +1139,44 @@ public final class NotificationPanelViewController implements Dumpable {
|
|||||||
collectFlow(mView, mKeyguardTransitionInteractor.getDreamingToLockscreenTransition(),
|
collectFlow(mView, mKeyguardTransitionInteractor.getDreamingToLockscreenTransition(),
|
||||||
mDreamingToLockscreenTransition, mMainDispatcher);
|
mDreamingToLockscreenTransition, mMainDispatcher);
|
||||||
collectFlow(mView, mDreamingToLockscreenTransitionViewModel.getLockscreenAlpha(),
|
collectFlow(mView, mDreamingToLockscreenTransitionViewModel.getLockscreenAlpha(),
|
||||||
toLockscreenTransitionAlpha(mNotificationStackScrollLayoutController),
|
setTransitionAlpha(mNotificationStackScrollLayoutController),
|
||||||
mMainDispatcher);
|
mMainDispatcher);
|
||||||
collectFlow(mView, mDreamingToLockscreenTransitionViewModel.lockscreenTranslationY(
|
collectFlow(mView, mDreamingToLockscreenTransitionViewModel.lockscreenTranslationY(
|
||||||
mDreamingToLockscreenTransitionTranslationY),
|
mDreamingToLockscreenTransitionTranslationY),
|
||||||
toLockscreenTransitionY(mNotificationStackScrollLayoutController),
|
setTransitionY(mNotificationStackScrollLayoutController),
|
||||||
mMainDispatcher);
|
mMainDispatcher);
|
||||||
|
|
||||||
// Occluded->Lockscreen
|
// Occluded->Lockscreen
|
||||||
collectFlow(mView, mKeyguardTransitionInteractor.getOccludedToLockscreenTransition(),
|
collectFlow(mView, mKeyguardTransitionInteractor.getOccludedToLockscreenTransition(),
|
||||||
mOccludedToLockscreenTransition, mMainDispatcher);
|
mOccludedToLockscreenTransition, mMainDispatcher);
|
||||||
collectFlow(mView, mOccludedToLockscreenTransitionViewModel.getLockscreenAlpha(),
|
collectFlow(mView, mOccludedToLockscreenTransitionViewModel.getLockscreenAlpha(),
|
||||||
toLockscreenTransitionAlpha(mNotificationStackScrollLayoutController),
|
setTransitionAlpha(mNotificationStackScrollLayoutController),
|
||||||
mMainDispatcher);
|
mMainDispatcher);
|
||||||
collectFlow(mView, mOccludedToLockscreenTransitionViewModel.lockscreenTranslationY(
|
collectFlow(mView, mOccludedToLockscreenTransitionViewModel.lockscreenTranslationY(
|
||||||
mOccludedToLockscreenTransitionTranslationY),
|
mOccludedToLockscreenTransitionTranslationY),
|
||||||
toLockscreenTransitionY(mNotificationStackScrollLayoutController),
|
setTransitionY(mNotificationStackScrollLayoutController),
|
||||||
|
mMainDispatcher);
|
||||||
|
|
||||||
|
// Lockscreen->Dreaming
|
||||||
|
collectFlow(mView, mKeyguardTransitionInteractor.getLockscreenToDreamingTransition(),
|
||||||
|
mLockscreenToDreamingTransition, mMainDispatcher);
|
||||||
|
collectFlow(mView, mLockscreenToDreamingTransitionViewModel.getLockscreenAlpha(),
|
||||||
|
setTransitionAlpha(mNotificationStackScrollLayoutController),
|
||||||
|
mMainDispatcher);
|
||||||
|
collectFlow(mView, mLockscreenToDreamingTransitionViewModel.lockscreenTranslationY(
|
||||||
|
mLockscreenToDreamingTransitionTranslationY),
|
||||||
|
setTransitionY(mNotificationStackScrollLayoutController),
|
||||||
|
mMainDispatcher);
|
||||||
|
|
||||||
|
// Lockscreen->Occluded
|
||||||
|
collectFlow(mView, mKeyguardTransitionInteractor.getLockscreenToOccludedTransition(),
|
||||||
|
mLockscreenToOccludedTransition, mMainDispatcher);
|
||||||
|
collectFlow(mView, mLockscreenToOccludedTransitionViewModel.getLockscreenAlpha(),
|
||||||
|
setTransitionAlpha(mNotificationStackScrollLayoutController),
|
||||||
|
mMainDispatcher);
|
||||||
|
collectFlow(mView, mLockscreenToOccludedTransitionViewModel.lockscreenTranslationY(
|
||||||
|
mLockscreenToOccludedTransitionTranslationY),
|
||||||
|
setTransitionY(mNotificationStackScrollLayoutController),
|
||||||
mMainDispatcher);
|
mMainDispatcher);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1173,6 +1217,10 @@ public final class NotificationPanelViewController implements Dumpable {
|
|||||||
R.dimen.dreaming_to_lockscreen_transition_lockscreen_translation_y);
|
R.dimen.dreaming_to_lockscreen_transition_lockscreen_translation_y);
|
||||||
mOccludedToLockscreenTransitionTranslationY = mResources.getDimensionPixelSize(
|
mOccludedToLockscreenTransitionTranslationY = mResources.getDimensionPixelSize(
|
||||||
R.dimen.occluded_to_lockscreen_transition_lockscreen_translation_y);
|
R.dimen.occluded_to_lockscreen_transition_lockscreen_translation_y);
|
||||||
|
mLockscreenToDreamingTransitionTranslationY = mResources.getDimensionPixelSize(
|
||||||
|
R.dimen.lockscreen_to_dreaming_transition_lockscreen_translation_y);
|
||||||
|
mLockscreenToOccludedTransitionTranslationY = mResources.getDimensionPixelSize(
|
||||||
|
R.dimen.lockscreen_to_occluded_transition_lockscreen_translation_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateViewControllers(KeyguardStatusView keyguardStatusView,
|
private void updateViewControllers(KeyguardStatusView keyguardStatusView,
|
||||||
@@ -1836,7 +1884,7 @@ public final class NotificationPanelViewController implements Dumpable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateClock() {
|
private void updateClock() {
|
||||||
if (mIsToLockscreenTransitionRunning) {
|
if (mIsOcclusionTransitionRunning) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
float alpha = mClockPositionResult.clockAlpha * mKeyguardOnlyContentAlpha;
|
float alpha = mClockPositionResult.clockAlpha * mKeyguardOnlyContentAlpha;
|
||||||
@@ -2727,7 +2775,7 @@ public final class NotificationPanelViewController implements Dumpable {
|
|||||||
} else if (statusBarState == KEYGUARD
|
} else if (statusBarState == KEYGUARD
|
||||||
|| statusBarState == StatusBarState.SHADE_LOCKED) {
|
|| statusBarState == StatusBarState.SHADE_LOCKED) {
|
||||||
mKeyguardBottomArea.setVisibility(View.VISIBLE);
|
mKeyguardBottomArea.setVisibility(View.VISIBLE);
|
||||||
if (!mIsToLockscreenTransitionRunning) {
|
if (!mIsOcclusionTransitionRunning) {
|
||||||
mKeyguardBottomArea.setAlpha(1f);
|
mKeyguardBottomArea.setAlpha(1f);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -3596,7 +3644,7 @@ public final class NotificationPanelViewController implements Dumpable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateNotificationTranslucency() {
|
private void updateNotificationTranslucency() {
|
||||||
if (mIsToLockscreenTransitionRunning) {
|
if (mIsOcclusionTransitionRunning) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
float alpha = 1f;
|
float alpha = 1f;
|
||||||
@@ -3654,7 +3702,7 @@ public final class NotificationPanelViewController implements Dumpable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateKeyguardBottomAreaAlpha() {
|
private void updateKeyguardBottomAreaAlpha() {
|
||||||
if (mIsToLockscreenTransitionRunning) {
|
if (mIsOcclusionTransitionRunning) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// There are two possible panel expansion behaviors:
|
// There are two possible panel expansion behaviors:
|
||||||
@@ -5886,7 +5934,7 @@ public final class NotificationPanelViewController implements Dumpable {
|
|||||||
mCurrentPanelState = state;
|
mCurrentPanelState = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Consumer<Float> toLockscreenTransitionAlpha(
|
private Consumer<Float> setTransitionAlpha(
|
||||||
NotificationStackScrollLayoutController stackScroller) {
|
NotificationStackScrollLayoutController stackScroller) {
|
||||||
return (Float alpha) -> {
|
return (Float alpha) -> {
|
||||||
mKeyguardStatusViewController.setAlpha(alpha);
|
mKeyguardStatusViewController.setAlpha(alpha);
|
||||||
@@ -5904,7 +5952,7 @@ public final class NotificationPanelViewController implements Dumpable {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private Consumer<Float> toLockscreenTransitionY(
|
private Consumer<Float> setTransitionY(
|
||||||
NotificationStackScrollLayoutController stackScroller) {
|
NotificationStackScrollLayoutController stackScroller) {
|
||||||
return (Float translationY) -> {
|
return (Float translationY) -> {
|
||||||
mKeyguardStatusViewController.setTranslationY(translationY, /* excludeMedia= */false);
|
mKeyguardStatusViewController.setTranslationY(translationY, /* excludeMedia= */false);
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package com.android.systemui.shade;
|
package com.android.systemui.shade;
|
||||||
|
|
||||||
|
import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;
|
||||||
|
|
||||||
import android.app.StatusBarManager;
|
import android.app.StatusBarManager;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.media.session.MediaSessionLegacyHelper;
|
import android.media.session.MediaSessionLegacyHelper;
|
||||||
@@ -39,6 +41,9 @@ import com.android.systemui.dock.DockManager;
|
|||||||
import com.android.systemui.flags.FeatureFlags;
|
import com.android.systemui.flags.FeatureFlags;
|
||||||
import com.android.systemui.flags.Flags;
|
import com.android.systemui.flags.Flags;
|
||||||
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
||||||
|
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
|
||||||
|
import com.android.systemui.keyguard.shared.model.TransitionState;
|
||||||
|
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.statusbar.DragDownHelper;
|
import com.android.systemui.statusbar.DragDownHelper;
|
||||||
@@ -57,6 +62,7 @@ import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
|
|||||||
import com.android.systemui.statusbar.window.StatusBarWindowStateController;
|
import com.android.systemui.statusbar.window.StatusBarWindowStateController;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@@ -96,6 +102,13 @@ public class NotificationShadeWindowViewController {
|
|||||||
private final ShadeExpansionStateManager mShadeExpansionStateManager;
|
private final ShadeExpansionStateManager mShadeExpansionStateManager;
|
||||||
|
|
||||||
private boolean mIsTrackingBarGesture = false;
|
private boolean mIsTrackingBarGesture = false;
|
||||||
|
private boolean mIsOcclusionTransitionRunning = false;
|
||||||
|
|
||||||
|
private final Consumer<TransitionStep> mLockscreenToDreamingTransition =
|
||||||
|
(TransitionStep step) -> {
|
||||||
|
mIsOcclusionTransitionRunning =
|
||||||
|
step.getTransitionState() == TransitionState.RUNNING;
|
||||||
|
};
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public NotificationShadeWindowViewController(
|
public NotificationShadeWindowViewController(
|
||||||
@@ -119,6 +132,7 @@ public class NotificationShadeWindowViewController {
|
|||||||
PulsingGestureListener pulsingGestureListener,
|
PulsingGestureListener pulsingGestureListener,
|
||||||
FeatureFlags featureFlags,
|
FeatureFlags featureFlags,
|
||||||
KeyguardBouncerViewModel keyguardBouncerViewModel,
|
KeyguardBouncerViewModel keyguardBouncerViewModel,
|
||||||
|
KeyguardTransitionInteractor keyguardTransitionInteractor,
|
||||||
KeyguardBouncerComponent.Factory keyguardBouncerComponentFactory
|
KeyguardBouncerComponent.Factory keyguardBouncerComponentFactory
|
||||||
) {
|
) {
|
||||||
mLockscreenShadeTransitionController = transitionController;
|
mLockscreenShadeTransitionController = transitionController;
|
||||||
@@ -148,6 +162,11 @@ public class NotificationShadeWindowViewController {
|
|||||||
keyguardBouncerViewModel,
|
keyguardBouncerViewModel,
|
||||||
keyguardBouncerComponentFactory);
|
keyguardBouncerComponentFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (featureFlags.isEnabled(Flags.UNOCCLUSION_TRANSITION)) {
|
||||||
|
collectFlow(mView, keyguardTransitionInteractor.getLockscreenToDreamingTransition(),
|
||||||
|
mLockscreenToDreamingTransition);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -215,6 +234,10 @@ public class NotificationShadeWindowViewController {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mIsOcclusionTransitionRunning) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
mFalsingCollector.onTouchEvent(ev);
|
mFalsingCollector.onTouchEvent(ev);
|
||||||
mPulsingWakeupGestureHandler.onTouchEvent(ev);
|
mPulsingWakeupGestureHandler.onTouchEvent(ev);
|
||||||
mStatusBarKeyguardViewManager.onTouch(ev);
|
mStatusBarKeyguardViewManager.onTouch(ev);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.keyguard
|
package com.android.keyguard
|
||||||
|
|
||||||
|
import com.android.systemui.statusbar.CommandQueue
|
||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
import android.testing.AndroidTestingRunner
|
import android.testing.AndroidTestingRunner
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@@ -81,6 +82,7 @@ class ClockEventControllerTest : SysuiTestCase() {
|
|||||||
@Mock private lateinit var largeClockEvents: ClockFaceEvents
|
@Mock private lateinit var largeClockEvents: ClockFaceEvents
|
||||||
@Mock private lateinit var parentView: View
|
@Mock private lateinit var parentView: View
|
||||||
@Mock private lateinit var transitionRepository: KeyguardTransitionRepository
|
@Mock private lateinit var transitionRepository: KeyguardTransitionRepository
|
||||||
|
@Mock private lateinit var commandQueue: CommandQueue
|
||||||
private lateinit var repository: FakeKeyguardRepository
|
private lateinit var repository: FakeKeyguardRepository
|
||||||
@Mock private lateinit var logBuffer: LogBuffer
|
@Mock private lateinit var logBuffer: LogBuffer
|
||||||
private lateinit var underTest: ClockEventController
|
private lateinit var underTest: ClockEventController
|
||||||
@@ -99,7 +101,7 @@ class ClockEventControllerTest : SysuiTestCase() {
|
|||||||
repository = FakeKeyguardRepository()
|
repository = FakeKeyguardRepository()
|
||||||
|
|
||||||
underTest = ClockEventController(
|
underTest = ClockEventController(
|
||||||
KeyguardInteractor(repository = repository),
|
KeyguardInteractor(repository = repository, commandQueue = commandQueue),
|
||||||
KeyguardTransitionInteractor(repository = transitionRepository),
|
KeyguardTransitionInteractor(repository = transitionRepository),
|
||||||
broadcastDispatcher,
|
broadcastDispatcher,
|
||||||
batteryController,
|
batteryController,
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
|
|||||||
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
|
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
|
||||||
import com.android.systemui.plugins.FalsingManager;
|
import com.android.systemui.plugins.FalsingManager;
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||||
|
import com.android.systemui.statusbar.CommandQueue;
|
||||||
import com.android.systemui.statusbar.StatusBarState;
|
import com.android.systemui.statusbar.StatusBarState;
|
||||||
import com.android.systemui.statusbar.VibratorHelper;
|
import com.android.systemui.statusbar.VibratorHelper;
|
||||||
import com.android.systemui.statusbar.policy.ConfigurationController;
|
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||||
@@ -91,6 +92,7 @@ public class LockIconViewControllerBaseTest extends SysuiTestCase {
|
|||||||
protected @Mock AuthRippleController mAuthRippleController;
|
protected @Mock AuthRippleController mAuthRippleController;
|
||||||
protected @Mock FeatureFlags mFeatureFlags;
|
protected @Mock FeatureFlags mFeatureFlags;
|
||||||
protected @Mock KeyguardTransitionRepository mTransitionRepository;
|
protected @Mock KeyguardTransitionRepository mTransitionRepository;
|
||||||
|
protected @Mock CommandQueue mCommandQueue;
|
||||||
protected FakeExecutor mDelayableExecutor = new FakeExecutor(new FakeSystemClock());
|
protected FakeExecutor mDelayableExecutor = new FakeExecutor(new FakeSystemClock());
|
||||||
|
|
||||||
protected LockIconViewController mUnderTest;
|
protected LockIconViewController mUnderTest;
|
||||||
@@ -157,7 +159,7 @@ public class LockIconViewControllerBaseTest extends SysuiTestCase {
|
|||||||
mAuthRippleController,
|
mAuthRippleController,
|
||||||
mResources,
|
mResources,
|
||||||
new KeyguardTransitionInteractor(mTransitionRepository),
|
new KeyguardTransitionInteractor(mTransitionRepository),
|
||||||
new KeyguardInteractor(new FakeKeyguardRepository()),
|
new KeyguardInteractor(new FakeKeyguardRepository(), mCommandQueue),
|
||||||
mFeatureFlags
|
mFeatureFlags
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ import com.android.systemui.settings.UserFileManager
|
|||||||
import com.android.systemui.settings.UserTracker
|
import com.android.systemui.settings.UserTracker
|
||||||
import com.android.systemui.shared.customization.data.content.CustomizationProviderContract as Contract
|
import com.android.systemui.shared.customization.data.content.CustomizationProviderContract as Contract
|
||||||
import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
|
import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
|
||||||
|
import com.android.systemui.statusbar.CommandQueue
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||||
import com.android.systemui.util.FakeSharedPreferences
|
import com.android.systemui.util.FakeSharedPreferences
|
||||||
import com.android.systemui.util.mockito.any
|
import com.android.systemui.util.mockito.any
|
||||||
@@ -86,9 +87,9 @@ class CustomizationProviderTest : SysuiTestCase() {
|
|||||||
@Mock private lateinit var backgroundHandler: Handler
|
@Mock private lateinit var backgroundHandler: Handler
|
||||||
@Mock private lateinit var previewSurfacePackage: SurfaceControlViewHost.SurfacePackage
|
@Mock private lateinit var previewSurfacePackage: SurfaceControlViewHost.SurfacePackage
|
||||||
@Mock private lateinit var launchAnimator: DialogLaunchAnimator
|
@Mock private lateinit var launchAnimator: DialogLaunchAnimator
|
||||||
|
@Mock private lateinit var commandQueue: CommandQueue
|
||||||
|
|
||||||
private lateinit var underTest: CustomizationProvider
|
private lateinit var underTest: CustomizationProvider
|
||||||
|
|
||||||
private lateinit var testScope: TestScope
|
private lateinit var testScope: TestScope
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
@@ -160,6 +161,7 @@ class CustomizationProviderTest : SysuiTestCase() {
|
|||||||
keyguardInteractor =
|
keyguardInteractor =
|
||||||
KeyguardInteractor(
|
KeyguardInteractor(
|
||||||
repository = FakeKeyguardRepository(),
|
repository = FakeKeyguardRepository(),
|
||||||
|
commandQueue = commandQueue,
|
||||||
),
|
),
|
||||||
registry = mock(),
|
registry = mock(),
|
||||||
lockPatternUtils = lockPatternUtils,
|
lockPatternUtils = lockPatternUtils,
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ import com.android.systemui.classifier.FalsingCollectorFake;
|
|||||||
import com.android.systemui.colorextraction.SysuiColorExtractor;
|
import com.android.systemui.colorextraction.SysuiColorExtractor;
|
||||||
import com.android.systemui.dreams.DreamOverlayStateController;
|
import com.android.systemui.dreams.DreamOverlayStateController;
|
||||||
import com.android.systemui.dump.DumpManager;
|
import com.android.systemui.dump.DumpManager;
|
||||||
|
import com.android.systemui.flags.FeatureFlags;
|
||||||
import com.android.systemui.navigationbar.NavigationModeController;
|
import com.android.systemui.navigationbar.NavigationModeController;
|
||||||
import com.android.systemui.settings.UserTracker;
|
import com.android.systemui.settings.UserTracker;
|
||||||
import com.android.systemui.shade.NotificationShadeWindowControllerImpl;
|
import com.android.systemui.shade.NotificationShadeWindowControllerImpl;
|
||||||
@@ -135,6 +136,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
|
|||||||
private @Mock AuthController mAuthController;
|
private @Mock AuthController mAuthController;
|
||||||
private @Mock ShadeExpansionStateManager mShadeExpansionStateManager;
|
private @Mock ShadeExpansionStateManager mShadeExpansionStateManager;
|
||||||
private @Mock ShadeWindowLogger mShadeWindowLogger;
|
private @Mock ShadeWindowLogger mShadeWindowLogger;
|
||||||
|
private @Mock FeatureFlags mFeatureFlags;
|
||||||
private DeviceConfigProxy mDeviceConfig = new DeviceConfigProxyFake();
|
private DeviceConfigProxy mDeviceConfig = new DeviceConfigProxyFake();
|
||||||
private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
|
private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
|
||||||
|
|
||||||
@@ -510,6 +512,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
|
|||||||
mScreenOnCoordinator,
|
mScreenOnCoordinator,
|
||||||
mInteractionJankMonitor,
|
mInteractionJankMonitor,
|
||||||
mDreamOverlayStateController,
|
mDreamOverlayStateController,
|
||||||
|
mFeatureFlags,
|
||||||
() -> mShadeController,
|
() -> mShadeController,
|
||||||
() -> mNotificationShadeWindowController,
|
() -> mNotificationShadeWindowController,
|
||||||
() -> mActivityLaunchAnimator,
|
() -> mActivityLaunchAnimator,
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ class KeyguardTransitionRepositoryTest : SysuiTestCase() {
|
|||||||
val firstTransitionSteps = listWithStep(step = BigDecimal(.1), stop = BigDecimal(.1))
|
val firstTransitionSteps = listWithStep(step = BigDecimal(.1), stop = BigDecimal(.1))
|
||||||
assertSteps(steps.subList(0, 4), firstTransitionSteps, AOD, LOCKSCREEN)
|
assertSteps(steps.subList(0, 4), firstTransitionSteps, AOD, LOCKSCREEN)
|
||||||
|
|
||||||
val secondTransitionSteps = listWithStep(step = BigDecimal(.1), start = BigDecimal(.9))
|
val secondTransitionSteps = listWithStep(step = BigDecimal(.1), start = BigDecimal(.1))
|
||||||
assertSteps(steps.subList(4, steps.size), secondTransitionSteps, LOCKSCREEN, AOD)
|
assertSteps(steps.subList(4, steps.size), secondTransitionSteps, LOCKSCREEN, AOD)
|
||||||
|
|
||||||
job.cancel()
|
job.cancel()
|
||||||
@@ -201,7 +201,10 @@ class KeyguardTransitionRepositoryTest : SysuiTestCase() {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
fractions.forEachIndexed { index, fraction ->
|
fractions.forEachIndexed { index, fraction ->
|
||||||
assertThat(steps[index + 1])
|
val step = steps[index + 1]
|
||||||
|
val truncatedValue =
|
||||||
|
BigDecimal(step.value.toDouble()).setScale(2, RoundingMode.HALF_UP).toFloat()
|
||||||
|
assertThat(step.copy(value = truncatedValue))
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
TransitionStep(
|
TransitionStep(
|
||||||
from,
|
from,
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.systemui.keyguard.domain.interactor
|
||||||
|
|
||||||
|
import android.app.StatusBarManager
|
||||||
|
import androidx.test.filters.SmallTest
|
||||||
|
import com.android.systemui.SysuiTestCase
|
||||||
|
import com.android.systemui.coroutines.collectLastValue
|
||||||
|
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
|
||||||
|
import com.android.systemui.keyguard.shared.model.CameraLaunchSourceModel
|
||||||
|
import com.android.systemui.statusbar.CommandQueue
|
||||||
|
import com.android.systemui.statusbar.CommandQueue.Callbacks
|
||||||
|
import com.android.systemui.util.mockito.argumentCaptor
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import kotlinx.coroutines.flow.onCompletion
|
||||||
|
import kotlinx.coroutines.test.runCurrent
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import org.junit.runners.JUnit4
|
||||||
|
import org.mockito.Mock
|
||||||
|
import org.mockito.Mockito.verify
|
||||||
|
import org.mockito.MockitoAnnotations
|
||||||
|
|
||||||
|
@SmallTest
|
||||||
|
@RunWith(JUnit4::class)
|
||||||
|
class KeyguardInteractorTest : SysuiTestCase() {
|
||||||
|
@Mock private lateinit var commandQueue: CommandQueue
|
||||||
|
|
||||||
|
private lateinit var underTest: KeyguardInteractor
|
||||||
|
private lateinit var repository: FakeKeyguardRepository
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this)
|
||||||
|
|
||||||
|
repository = FakeKeyguardRepository()
|
||||||
|
underTest = KeyguardInteractor(repository, commandQueue)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onCameraLaunchDetected() = runTest {
|
||||||
|
val flow = underTest.onCameraLaunchDetected
|
||||||
|
var cameraLaunchSource = collectLastValue(flow)
|
||||||
|
runCurrent()
|
||||||
|
|
||||||
|
val captor = argumentCaptor<CommandQueue.Callbacks>()
|
||||||
|
verify(commandQueue).addCallback(captor.capture())
|
||||||
|
|
||||||
|
captor.value.onCameraLaunchGestureDetected(StatusBarManager.CAMERA_LAUNCH_SOURCE_WIGGLE)
|
||||||
|
assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.WIGGLE)
|
||||||
|
|
||||||
|
captor.value.onCameraLaunchGestureDetected(
|
||||||
|
StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP
|
||||||
|
)
|
||||||
|
assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.POWER_DOUBLE_TAP)
|
||||||
|
|
||||||
|
captor.value.onCameraLaunchGestureDetected(
|
||||||
|
StatusBarManager.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER
|
||||||
|
)
|
||||||
|
assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.LIFT_TRIGGER)
|
||||||
|
|
||||||
|
captor.value.onCameraLaunchGestureDetected(
|
||||||
|
StatusBarManager.CAMERA_LAUNCH_SOURCE_QUICK_AFFORDANCE
|
||||||
|
)
|
||||||
|
assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.QUICK_AFFORDANCE)
|
||||||
|
|
||||||
|
flow.onCompletion { verify(commandQueue).removeCallback(captor.value) }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -44,6 +44,7 @@ import com.android.systemui.plugins.ActivityStarter
|
|||||||
import com.android.systemui.settings.FakeUserTracker
|
import com.android.systemui.settings.FakeUserTracker
|
||||||
import com.android.systemui.settings.UserFileManager
|
import com.android.systemui.settings.UserFileManager
|
||||||
import com.android.systemui.settings.UserTracker
|
import com.android.systemui.settings.UserTracker
|
||||||
|
import com.android.systemui.statusbar.CommandQueue
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||||
import com.android.systemui.util.FakeSharedPreferences
|
import com.android.systemui.util.FakeSharedPreferences
|
||||||
import com.android.systemui.util.mockito.any
|
import com.android.systemui.util.mockito.any
|
||||||
@@ -216,6 +217,7 @@ class KeyguardQuickAffordanceInteractorParameterizedTest : SysuiTestCase() {
|
|||||||
@Mock private lateinit var animationController: ActivityLaunchAnimator.Controller
|
@Mock private lateinit var animationController: ActivityLaunchAnimator.Controller
|
||||||
@Mock private lateinit var expandable: Expandable
|
@Mock private lateinit var expandable: Expandable
|
||||||
@Mock private lateinit var launchAnimator: DialogLaunchAnimator
|
@Mock private lateinit var launchAnimator: DialogLaunchAnimator
|
||||||
|
@Mock private lateinit var commandQueue: CommandQueue
|
||||||
|
|
||||||
private lateinit var underTest: KeyguardQuickAffordanceInteractor
|
private lateinit var underTest: KeyguardQuickAffordanceInteractor
|
||||||
|
|
||||||
@@ -286,7 +288,11 @@ class KeyguardQuickAffordanceInteractorParameterizedTest : SysuiTestCase() {
|
|||||||
)
|
)
|
||||||
underTest =
|
underTest =
|
||||||
KeyguardQuickAffordanceInteractor(
|
KeyguardQuickAffordanceInteractor(
|
||||||
keyguardInteractor = KeyguardInteractor(repository = FakeKeyguardRepository()),
|
keyguardInteractor =
|
||||||
|
KeyguardInteractor(
|
||||||
|
repository = FakeKeyguardRepository(),
|
||||||
|
commandQueue = commandQueue
|
||||||
|
),
|
||||||
registry =
|
registry =
|
||||||
FakeKeyguardQuickAffordanceRegistry(
|
FakeKeyguardQuickAffordanceRegistry(
|
||||||
mapOf(
|
mapOf(
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ import com.android.systemui.plugins.ActivityStarter
|
|||||||
import com.android.systemui.settings.UserFileManager
|
import com.android.systemui.settings.UserFileManager
|
||||||
import com.android.systemui.settings.UserTracker
|
import com.android.systemui.settings.UserTracker
|
||||||
import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
|
import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
|
||||||
|
import com.android.systemui.statusbar.CommandQueue
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||||
import com.android.systemui.util.FakeSharedPreferences
|
import com.android.systemui.util.FakeSharedPreferences
|
||||||
import com.android.systemui.util.mockito.mock
|
import com.android.systemui.util.mockito.mock
|
||||||
@@ -75,6 +76,7 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
|
|||||||
@Mock private lateinit var userTracker: UserTracker
|
@Mock private lateinit var userTracker: UserTracker
|
||||||
@Mock private lateinit var activityStarter: ActivityStarter
|
@Mock private lateinit var activityStarter: ActivityStarter
|
||||||
@Mock private lateinit var launchAnimator: DialogLaunchAnimator
|
@Mock private lateinit var launchAnimator: DialogLaunchAnimator
|
||||||
|
@Mock private lateinit var commandQueue: CommandQueue
|
||||||
|
|
||||||
private lateinit var underTest: KeyguardQuickAffordanceInteractor
|
private lateinit var underTest: KeyguardQuickAffordanceInteractor
|
||||||
|
|
||||||
@@ -152,7 +154,8 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
|
|||||||
|
|
||||||
underTest =
|
underTest =
|
||||||
KeyguardQuickAffordanceInteractor(
|
KeyguardQuickAffordanceInteractor(
|
||||||
keyguardInteractor = KeyguardInteractor(repository = repository),
|
keyguardInteractor =
|
||||||
|
KeyguardInteractor(repository = repository, commandQueue = commandQueue),
|
||||||
registry =
|
registry =
|
||||||
FakeKeyguardQuickAffordanceRegistry(
|
FakeKeyguardQuickAffordanceRegistry(
|
||||||
mapOf(
|
mapOf(
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import com.android.systemui.keyguard.shared.model.WakefulnessState
|
|||||||
import com.android.systemui.keyguard.util.KeyguardTransitionRunner
|
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.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
|
||||||
@@ -66,6 +67,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
|
||||||
|
|
||||||
private lateinit var fromLockscreenTransitionInteractor: FromLockscreenTransitionInteractor
|
private lateinit var fromLockscreenTransitionInteractor: FromLockscreenTransitionInteractor
|
||||||
private lateinit var fromDreamingTransitionInteractor: FromDreamingTransitionInteractor
|
private lateinit var fromDreamingTransitionInteractor: FromDreamingTransitionInteractor
|
||||||
@@ -85,7 +87,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
|||||||
fromLockscreenTransitionInteractor =
|
fromLockscreenTransitionInteractor =
|
||||||
FromLockscreenTransitionInteractor(
|
FromLockscreenTransitionInteractor(
|
||||||
scope = testScope,
|
scope = testScope,
|
||||||
keyguardInteractor = KeyguardInteractor(keyguardRepository),
|
keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue),
|
||||||
shadeRepository = shadeRepository,
|
shadeRepository = shadeRepository,
|
||||||
keyguardTransitionRepository = mockTransitionRepository,
|
keyguardTransitionRepository = mockTransitionRepository,
|
||||||
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
|
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
|
||||||
@@ -95,7 +97,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
|||||||
fromDreamingTransitionInteractor =
|
fromDreamingTransitionInteractor =
|
||||||
FromDreamingTransitionInteractor(
|
FromDreamingTransitionInteractor(
|
||||||
scope = testScope,
|
scope = testScope,
|
||||||
keyguardInteractor = KeyguardInteractor(keyguardRepository),
|
keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue),
|
||||||
keyguardTransitionRepository = mockTransitionRepository,
|
keyguardTransitionRepository = mockTransitionRepository,
|
||||||
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
|
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ import com.android.systemui.plugins.ActivityStarter
|
|||||||
import com.android.systemui.settings.UserFileManager
|
import com.android.systemui.settings.UserFileManager
|
||||||
import com.android.systemui.settings.UserTracker
|
import com.android.systemui.settings.UserTracker
|
||||||
import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
|
import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
|
||||||
|
import com.android.systemui.statusbar.CommandQueue
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||||
import com.android.systemui.util.FakeSharedPreferences
|
import com.android.systemui.util.FakeSharedPreferences
|
||||||
import com.android.systemui.util.mockito.any
|
import com.android.systemui.util.mockito.any
|
||||||
@@ -84,6 +85,7 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
|
|||||||
@Mock private lateinit var userTracker: UserTracker
|
@Mock private lateinit var userTracker: UserTracker
|
||||||
@Mock private lateinit var activityStarter: ActivityStarter
|
@Mock private lateinit var activityStarter: ActivityStarter
|
||||||
@Mock private lateinit var launchAnimator: DialogLaunchAnimator
|
@Mock private lateinit var launchAnimator: DialogLaunchAnimator
|
||||||
|
@Mock private lateinit var commandQueue: CommandQueue
|
||||||
|
|
||||||
private lateinit var underTest: KeyguardBottomAreaViewModel
|
private lateinit var underTest: KeyguardBottomAreaViewModel
|
||||||
|
|
||||||
@@ -124,7 +126,8 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
|
|||||||
)
|
)
|
||||||
repository = FakeKeyguardRepository()
|
repository = FakeKeyguardRepository()
|
||||||
|
|
||||||
val keyguardInteractor = KeyguardInteractor(repository = repository)
|
val keyguardInteractor =
|
||||||
|
KeyguardInteractor(repository = repository, commandQueue = commandQueue)
|
||||||
whenever(userTracker.userHandle).thenReturn(mock())
|
whenever(userTracker.userHandle).thenReturn(mock())
|
||||||
whenever(lockPatternUtils.getStrongAuthForUser(anyInt()))
|
whenever(lockPatternUtils.getStrongAuthForUser(anyInt()))
|
||||||
.thenReturn(LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED)
|
.thenReturn(LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED)
|
||||||
|
|||||||
@@ -0,0 +1,135 @@
|
|||||||
|
/*
|
||||||
|
* 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 androidx.test.filters.SmallTest
|
||||||
|
import com.android.systemui.SysuiTestCase
|
||||||
|
import com.android.systemui.animation.Interpolators.EMPHASIZED_ACCELERATE
|
||||||
|
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
|
||||||
|
import com.android.systemui.keyguard.domain.interactor.FromLockscreenTransitionInteractor.Companion.TO_DREAMING_DURATION
|
||||||
|
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
|
||||||
|
import com.android.systemui.keyguard.shared.model.AnimationParams
|
||||||
|
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.LockscreenToDreamingTransitionViewModel.Companion.LOCKSCREEN_ALPHA
|
||||||
|
import com.android.systemui.keyguard.ui.viewmodel.LockscreenToDreamingTransitionViewModel.Companion.LOCKSCREEN_TRANSLATION_Y
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import kotlinx.coroutines.flow.launchIn
|
||||||
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
import kotlinx.coroutines.test.UnconfinedTestDispatcher
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import org.junit.runners.JUnit4
|
||||||
|
|
||||||
|
@SmallTest
|
||||||
|
@RunWith(JUnit4::class)
|
||||||
|
class LockscreenToDreamingTransitionViewModelTest : SysuiTestCase() {
|
||||||
|
private lateinit var underTest: LockscreenToDreamingTransitionViewModel
|
||||||
|
private lateinit var repository: FakeKeyguardTransitionRepository
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setUp() {
|
||||||
|
repository = FakeKeyguardTransitionRepository()
|
||||||
|
val interactor = KeyguardTransitionInteractor(repository)
|
||||||
|
underTest = LockscreenToDreamingTransitionViewModel(interactor)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun lockscreenFadeOut() =
|
||||||
|
runTest(UnconfinedTestDispatcher()) {
|
||||||
|
val values = mutableListOf<Float>()
|
||||||
|
|
||||||
|
val job = underTest.lockscreenAlpha.onEach { values.add(it) }.launchIn(this)
|
||||||
|
|
||||||
|
// Should start running here...
|
||||||
|
repository.sendTransitionStep(step(0f))
|
||||||
|
repository.sendTransitionStep(step(0.1f))
|
||||||
|
repository.sendTransitionStep(step(0.2f))
|
||||||
|
// ...up to here
|
||||||
|
repository.sendTransitionStep(step(0.3f))
|
||||||
|
repository.sendTransitionStep(step(1f))
|
||||||
|
|
||||||
|
// Only three values should be present, since the dream overlay runs for a small
|
||||||
|
// fraction
|
||||||
|
// of the overall animation time
|
||||||
|
assertThat(values.size).isEqualTo(3)
|
||||||
|
assertThat(values[0]).isEqualTo(1f - animValue(0f, LOCKSCREEN_ALPHA))
|
||||||
|
assertThat(values[1]).isEqualTo(1f - animValue(0.1f, LOCKSCREEN_ALPHA))
|
||||||
|
assertThat(values[2]).isEqualTo(1f - animValue(0.2f, LOCKSCREEN_ALPHA))
|
||||||
|
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun lockscreenTranslationY() =
|
||||||
|
runTest(UnconfinedTestDispatcher()) {
|
||||||
|
val values = mutableListOf<Float>()
|
||||||
|
|
||||||
|
val pixels = 100
|
||||||
|
val job =
|
||||||
|
underTest.lockscreenTranslationY(pixels).onEach { values.add(it) }.launchIn(this)
|
||||||
|
|
||||||
|
// Should start running here...
|
||||||
|
repository.sendTransitionStep(step(0f))
|
||||||
|
repository.sendTransitionStep(step(0.3f))
|
||||||
|
repository.sendTransitionStep(step(0.5f))
|
||||||
|
// ...up to here
|
||||||
|
repository.sendTransitionStep(step(1f))
|
||||||
|
|
||||||
|
assertThat(values.size).isEqualTo(3)
|
||||||
|
assertThat(values[0])
|
||||||
|
.isEqualTo(
|
||||||
|
EMPHASIZED_ACCELERATE.getInterpolation(
|
||||||
|
animValue(0f, LOCKSCREEN_TRANSLATION_Y)
|
||||||
|
) * pixels
|
||||||
|
)
|
||||||
|
assertThat(values[1])
|
||||||
|
.isEqualTo(
|
||||||
|
EMPHASIZED_ACCELERATE.getInterpolation(
|
||||||
|
animValue(0.3f, LOCKSCREEN_TRANSLATION_Y)
|
||||||
|
) * pixels
|
||||||
|
)
|
||||||
|
assertThat(values[2])
|
||||||
|
.isEqualTo(
|
||||||
|
EMPHASIZED_ACCELERATE.getInterpolation(
|
||||||
|
animValue(0.5f, LOCKSCREEN_TRANSLATION_Y)
|
||||||
|
) * pixels
|
||||||
|
)
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun animValue(stepValue: Float, params: AnimationParams): Float {
|
||||||
|
val totalDuration = TO_DREAMING_DURATION
|
||||||
|
val startValue = (params.startTime / totalDuration).toFloat()
|
||||||
|
|
||||||
|
val multiplier = (totalDuration / params.duration).toFloat()
|
||||||
|
return (stepValue - startValue) * multiplier
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun step(value: Float): TransitionStep {
|
||||||
|
return TransitionStep(
|
||||||
|
from = KeyguardState.LOCKSCREEN,
|
||||||
|
to = KeyguardState.DREAMING,
|
||||||
|
value = value,
|
||||||
|
transitionState = TransitionState.RUNNING,
|
||||||
|
ownerName = "LockscreenToDreamingTransitionViewModelTest"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
/*
|
||||||
|
* 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 androidx.test.filters.SmallTest
|
||||||
|
import com.android.systemui.SysuiTestCase
|
||||||
|
import com.android.systemui.animation.Interpolators.EMPHASIZED_ACCELERATE
|
||||||
|
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
|
||||||
|
import com.android.systemui.keyguard.domain.interactor.FromLockscreenTransitionInteractor.Companion.TO_OCCLUDED_DURATION
|
||||||
|
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
|
||||||
|
import com.android.systemui.keyguard.shared.model.AnimationParams
|
||||||
|
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.LockscreenToOccludedTransitionViewModel.Companion.LOCKSCREEN_ALPHA
|
||||||
|
import com.android.systemui.keyguard.ui.viewmodel.LockscreenToOccludedTransitionViewModel.Companion.LOCKSCREEN_TRANSLATION_Y
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import kotlinx.coroutines.flow.launchIn
|
||||||
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
import kotlinx.coroutines.test.UnconfinedTestDispatcher
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import org.junit.runners.JUnit4
|
||||||
|
|
||||||
|
@SmallTest
|
||||||
|
@RunWith(JUnit4::class)
|
||||||
|
class LockscreenToOccludedTransitionViewModelTest : SysuiTestCase() {
|
||||||
|
private lateinit var underTest: LockscreenToOccludedTransitionViewModel
|
||||||
|
private lateinit var repository: FakeKeyguardTransitionRepository
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setUp() {
|
||||||
|
repository = FakeKeyguardTransitionRepository()
|
||||||
|
val interactor = KeyguardTransitionInteractor(repository)
|
||||||
|
underTest = LockscreenToOccludedTransitionViewModel(interactor)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun lockscreenFadeOut() =
|
||||||
|
runTest(UnconfinedTestDispatcher()) {
|
||||||
|
val values = mutableListOf<Float>()
|
||||||
|
|
||||||
|
val job = underTest.lockscreenAlpha.onEach { values.add(it) }.launchIn(this)
|
||||||
|
|
||||||
|
// Should start running here...
|
||||||
|
repository.sendTransitionStep(step(0f))
|
||||||
|
repository.sendTransitionStep(step(0.1f))
|
||||||
|
repository.sendTransitionStep(step(0.4f))
|
||||||
|
// ...up to here
|
||||||
|
repository.sendTransitionStep(step(0.7f))
|
||||||
|
repository.sendTransitionStep(step(1f))
|
||||||
|
|
||||||
|
// Only 3 values should be present, since the dream overlay runs for a small fraction
|
||||||
|
// of the overall animation time
|
||||||
|
assertThat(values.size).isEqualTo(3)
|
||||||
|
assertThat(values[0]).isEqualTo(1f - animValue(0f, LOCKSCREEN_ALPHA))
|
||||||
|
assertThat(values[1]).isEqualTo(1f - animValue(0.1f, LOCKSCREEN_ALPHA))
|
||||||
|
assertThat(values[2]).isEqualTo(1f - animValue(0.4f, LOCKSCREEN_ALPHA))
|
||||||
|
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun lockscreenTranslationY() =
|
||||||
|
runTest(UnconfinedTestDispatcher()) {
|
||||||
|
val values = mutableListOf<Float>()
|
||||||
|
|
||||||
|
val pixels = 100
|
||||||
|
val job =
|
||||||
|
underTest.lockscreenTranslationY(pixels).onEach { values.add(it) }.launchIn(this)
|
||||||
|
|
||||||
|
// Should start running here...
|
||||||
|
repository.sendTransitionStep(step(0f))
|
||||||
|
repository.sendTransitionStep(step(0.3f))
|
||||||
|
repository.sendTransitionStep(step(0.5f))
|
||||||
|
repository.sendTransitionStep(step(1f))
|
||||||
|
// ...up to here
|
||||||
|
|
||||||
|
assertThat(values.size).isEqualTo(4)
|
||||||
|
assertThat(values[0])
|
||||||
|
.isEqualTo(
|
||||||
|
EMPHASIZED_ACCELERATE.getInterpolation(
|
||||||
|
animValue(0f, LOCKSCREEN_TRANSLATION_Y)
|
||||||
|
) * pixels
|
||||||
|
)
|
||||||
|
assertThat(values[1])
|
||||||
|
.isEqualTo(
|
||||||
|
EMPHASIZED_ACCELERATE.getInterpolation(
|
||||||
|
animValue(0.3f, LOCKSCREEN_TRANSLATION_Y)
|
||||||
|
) * pixels
|
||||||
|
)
|
||||||
|
assertThat(values[2])
|
||||||
|
.isEqualTo(
|
||||||
|
EMPHASIZED_ACCELERATE.getInterpolation(
|
||||||
|
animValue(0.5f, LOCKSCREEN_TRANSLATION_Y)
|
||||||
|
) * pixels
|
||||||
|
)
|
||||||
|
assertThat(values[3])
|
||||||
|
.isEqualTo(
|
||||||
|
EMPHASIZED_ACCELERATE.getInterpolation(
|
||||||
|
animValue(1f, LOCKSCREEN_TRANSLATION_Y)
|
||||||
|
) * pixels
|
||||||
|
)
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun animValue(stepValue: Float, params: AnimationParams): Float {
|
||||||
|
val totalDuration = TO_OCCLUDED_DURATION
|
||||||
|
val startValue = (params.startTime / totalDuration).toFloat()
|
||||||
|
|
||||||
|
val multiplier = (totalDuration / params.duration).toFloat()
|
||||||
|
return (stepValue - startValue) * multiplier
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun step(value: Float): TransitionStep {
|
||||||
|
return TransitionStep(
|
||||||
|
from = KeyguardState.LOCKSCREEN,
|
||||||
|
to = KeyguardState.OCCLUDED,
|
||||||
|
value = value,
|
||||||
|
transitionState = TransitionState.RUNNING,
|
||||||
|
ownerName = "LockscreenToOccludedTransitionViewModelTest"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -107,6 +107,8 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInterac
|
|||||||
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
|
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
|
||||||
import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel;
|
import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel;
|
||||||
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel;
|
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel;
|
||||||
|
import com.android.systemui.keyguard.ui.viewmodel.LockscreenToDreamingTransitionViewModel;
|
||||||
|
import com.android.systemui.keyguard.ui.viewmodel.LockscreenToOccludedTransitionViewModel;
|
||||||
import com.android.systemui.keyguard.ui.viewmodel.OccludedToLockscreenTransitionViewModel;
|
import com.android.systemui.keyguard.ui.viewmodel.OccludedToLockscreenTransitionViewModel;
|
||||||
import com.android.systemui.media.controls.pipeline.MediaDataManager;
|
import com.android.systemui.media.controls.pipeline.MediaDataManager;
|
||||||
import com.android.systemui.media.controls.ui.KeyguardMediaController;
|
import com.android.systemui.media.controls.ui.KeyguardMediaController;
|
||||||
@@ -293,6 +295,9 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
|
|||||||
@Mock private KeyguardBottomAreaInteractor mKeyguardBottomAreaInteractor;
|
@Mock private KeyguardBottomAreaInteractor mKeyguardBottomAreaInteractor;
|
||||||
@Mock private DreamingToLockscreenTransitionViewModel mDreamingToLockscreenTransitionViewModel;
|
@Mock private DreamingToLockscreenTransitionViewModel mDreamingToLockscreenTransitionViewModel;
|
||||||
@Mock private OccludedToLockscreenTransitionViewModel mOccludedToLockscreenTransitionViewModel;
|
@Mock private OccludedToLockscreenTransitionViewModel mOccludedToLockscreenTransitionViewModel;
|
||||||
|
@Mock private LockscreenToDreamingTransitionViewModel mLockscreenToDreamingTransitionViewModel;
|
||||||
|
@Mock private LockscreenToOccludedTransitionViewModel mLockscreenToOccludedTransitionViewModel;
|
||||||
|
|
||||||
@Mock private KeyguardTransitionInteractor mKeyguardTransitionInteractor;
|
@Mock private KeyguardTransitionInteractor mKeyguardTransitionInteractor;
|
||||||
@Mock private CoroutineDispatcher mMainDispatcher;
|
@Mock private CoroutineDispatcher mMainDispatcher;
|
||||||
@Mock private MotionEvent mDownMotionEvent;
|
@Mock private MotionEvent mDownMotionEvent;
|
||||||
@@ -513,6 +518,8 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
|
|||||||
mKeyguardBottomAreaInteractor,
|
mKeyguardBottomAreaInteractor,
|
||||||
mDreamingToLockscreenTransitionViewModel,
|
mDreamingToLockscreenTransitionViewModel,
|
||||||
mOccludedToLockscreenTransitionViewModel,
|
mOccludedToLockscreenTransitionViewModel,
|
||||||
|
mLockscreenToDreamingTransitionViewModel,
|
||||||
|
mLockscreenToOccludedTransitionViewModel,
|
||||||
mMainDispatcher,
|
mMainDispatcher,
|
||||||
mKeyguardTransitionInteractor,
|
mKeyguardTransitionInteractor,
|
||||||
mDumpManager);
|
mDumpManager);
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import com.android.systemui.classifier.FalsingCollectorFake
|
|||||||
import com.android.systemui.dock.DockManager
|
import com.android.systemui.dock.DockManager
|
||||||
import com.android.systemui.flags.FeatureFlags
|
import com.android.systemui.flags.FeatureFlags
|
||||||
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.ui.viewmodel.KeyguardBouncerViewModel
|
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel
|
||||||
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
|
||||||
@@ -101,6 +102,7 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
|
|||||||
@Mock lateinit var keyguardBouncerContainer: ViewGroup
|
@Mock lateinit var keyguardBouncerContainer: ViewGroup
|
||||||
@Mock lateinit var keyguardBouncerComponent: KeyguardBouncerComponent
|
@Mock lateinit var keyguardBouncerComponent: KeyguardBouncerComponent
|
||||||
@Mock lateinit var keyguardHostViewController: KeyguardHostViewController
|
@Mock lateinit var keyguardHostViewController: KeyguardHostViewController
|
||||||
|
@Mock lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor
|
||||||
|
|
||||||
private lateinit var interactionEventHandlerCaptor: ArgumentCaptor<InteractionEventHandler>
|
private lateinit var interactionEventHandlerCaptor: ArgumentCaptor<InteractionEventHandler>
|
||||||
private lateinit var interactionEventHandler: InteractionEventHandler
|
private lateinit var interactionEventHandler: InteractionEventHandler
|
||||||
@@ -132,7 +134,8 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
|
|||||||
pulsingGestureListener,
|
pulsingGestureListener,
|
||||||
featureFlags,
|
featureFlags,
|
||||||
keyguardBouncerViewModel,
|
keyguardBouncerViewModel,
|
||||||
keyguardBouncerComponentFactory
|
keyguardTransitionInteractor,
|
||||||
|
keyguardBouncerComponentFactory,
|
||||||
)
|
)
|
||||||
underTest.setupExpandedStatusBar()
|
underTest.setupExpandedStatusBar()
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import com.android.systemui.classifier.FalsingCollectorFake;
|
|||||||
import com.android.systemui.dock.DockManager;
|
import com.android.systemui.dock.DockManager;
|
||||||
import com.android.systemui.flags.FeatureFlags;
|
import com.android.systemui.flags.FeatureFlags;
|
||||||
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.ui.viewmodel.KeyguardBouncerViewModel;
|
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel;
|
||||||
import com.android.systemui.statusbar.DragDownHelper;
|
import com.android.systemui.statusbar.DragDownHelper;
|
||||||
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
|
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
|
||||||
@@ -93,6 +94,7 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase {
|
|||||||
@Mock private KeyguardBouncerViewModel mKeyguardBouncerViewModel;
|
@Mock private KeyguardBouncerViewModel mKeyguardBouncerViewModel;
|
||||||
@Mock private KeyguardBouncerComponent.Factory mKeyguardBouncerComponentFactory;
|
@Mock private KeyguardBouncerComponent.Factory mKeyguardBouncerComponentFactory;
|
||||||
@Mock private NotificationInsetsController mNotificationInsetsController;
|
@Mock private NotificationInsetsController mNotificationInsetsController;
|
||||||
|
@Mock private KeyguardTransitionInteractor mKeyguardTransitionInteractor;
|
||||||
|
|
||||||
@Captor private ArgumentCaptor<NotificationShadeWindowView.InteractionEventHandler>
|
@Captor private ArgumentCaptor<NotificationShadeWindowView.InteractionEventHandler>
|
||||||
mInteractionEventHandlerCaptor;
|
mInteractionEventHandlerCaptor;
|
||||||
@@ -132,6 +134,7 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase {
|
|||||||
mPulsingGestureListener,
|
mPulsingGestureListener,
|
||||||
mFeatureFlags,
|
mFeatureFlags,
|
||||||
mKeyguardBouncerViewModel,
|
mKeyguardBouncerViewModel,
|
||||||
|
mKeyguardTransitionInteractor,
|
||||||
mKeyguardBouncerComponentFactory
|
mKeyguardBouncerComponentFactory
|
||||||
);
|
);
|
||||||
mController.setupExpandedStatusBar();
|
mController.setupExpandedStatusBar();
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import com.android.systemui.keyguard.WakefulnessLifecycle
|
|||||||
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
|
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
|
||||||
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
|
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
|
||||||
import com.android.systemui.shade.NotificationPanelViewController
|
import com.android.systemui.shade.NotificationPanelViewController
|
||||||
|
import com.android.systemui.statusbar.CommandQueue
|
||||||
import com.android.systemui.statusbar.LightRevealScrim
|
import com.android.systemui.statusbar.LightRevealScrim
|
||||||
import com.android.systemui.statusbar.phone.CentralSurfaces
|
import com.android.systemui.statusbar.phone.CentralSurfaces
|
||||||
import com.android.systemui.unfold.util.FoldableDeviceStates
|
import com.android.systemui.unfold.util.FoldableDeviceStates
|
||||||
@@ -73,6 +74,8 @@ class FoldAodAnimationControllerTest : SysuiTestCase() {
|
|||||||
|
|
||||||
@Mock lateinit var viewTreeObserver: ViewTreeObserver
|
@Mock lateinit var viewTreeObserver: ViewTreeObserver
|
||||||
|
|
||||||
|
@Mock private lateinit var commandQueue: CommandQueue
|
||||||
|
|
||||||
@Captor private lateinit var foldStateListenerCaptor: ArgumentCaptor<FoldStateListener>
|
@Captor private lateinit var foldStateListenerCaptor: ArgumentCaptor<FoldStateListener>
|
||||||
|
|
||||||
private lateinit var deviceStates: FoldableDeviceStates
|
private lateinit var deviceStates: FoldableDeviceStates
|
||||||
@@ -102,7 +105,8 @@ class FoldAodAnimationControllerTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
keyguardRepository = FakeKeyguardRepository()
|
keyguardRepository = FakeKeyguardRepository()
|
||||||
val keyguardInteractor = KeyguardInteractor(repository = keyguardRepository)
|
val keyguardInteractor =
|
||||||
|
KeyguardInteractor(repository = keyguardRepository, commandQueue = commandQueue)
|
||||||
|
|
||||||
// Needs to be run on the main thread
|
// Needs to be run on the main thread
|
||||||
runBlocking(IMMEDIATE) {
|
runBlocking(IMMEDIATE) {
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
|
|||||||
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
|
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
|
||||||
import com.android.systemui.plugins.ActivityStarter
|
import com.android.systemui.plugins.ActivityStarter
|
||||||
import com.android.systemui.qs.user.UserSwitchDialogController
|
import com.android.systemui.qs.user.UserSwitchDialogController
|
||||||
|
import com.android.systemui.statusbar.CommandQueue
|
||||||
import com.android.systemui.statusbar.policy.DeviceProvisionedController
|
import com.android.systemui.statusbar.policy.DeviceProvisionedController
|
||||||
import com.android.systemui.telephony.data.repository.FakeTelephonyRepository
|
import com.android.systemui.telephony.data.repository.FakeTelephonyRepository
|
||||||
import com.android.systemui.telephony.domain.interactor.TelephonyInteractor
|
import com.android.systemui.telephony.domain.interactor.TelephonyInteractor
|
||||||
@@ -93,6 +94,7 @@ class UserInteractorTest : SysuiTestCase() {
|
|||||||
@Mock private lateinit var dialogShower: UserSwitchDialogController.DialogShower
|
@Mock private lateinit var dialogShower: UserSwitchDialogController.DialogShower
|
||||||
@Mock private lateinit var resumeSessionReceiver: GuestResumeSessionReceiver
|
@Mock private lateinit var resumeSessionReceiver: GuestResumeSessionReceiver
|
||||||
@Mock private lateinit var resetOrExitSessionReceiver: GuestResetOrExitSessionReceiver
|
@Mock private lateinit var resetOrExitSessionReceiver: GuestResetOrExitSessionReceiver
|
||||||
|
@Mock private lateinit var commandQueue: CommandQueue
|
||||||
|
|
||||||
private lateinit var underTest: UserInteractor
|
private lateinit var underTest: UserInteractor
|
||||||
|
|
||||||
@@ -136,6 +138,7 @@ class UserInteractorTest : SysuiTestCase() {
|
|||||||
keyguardInteractor =
|
keyguardInteractor =
|
||||||
KeyguardInteractor(
|
KeyguardInteractor(
|
||||||
repository = keyguardRepository,
|
repository = keyguardRepository,
|
||||||
|
commandQueue = commandQueue,
|
||||||
),
|
),
|
||||||
manager = manager,
|
manager = manager,
|
||||||
applicationScope = testScope.backgroundScope,
|
applicationScope = testScope.backgroundScope,
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import com.android.systemui.flags.Flags
|
|||||||
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
|
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
|
||||||
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
|
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
|
||||||
import com.android.systemui.plugins.ActivityStarter
|
import com.android.systemui.plugins.ActivityStarter
|
||||||
|
import com.android.systemui.statusbar.CommandQueue
|
||||||
import com.android.systemui.statusbar.policy.DeviceProvisionedController
|
import com.android.systemui.statusbar.policy.DeviceProvisionedController
|
||||||
import com.android.systemui.telephony.data.repository.FakeTelephonyRepository
|
import com.android.systemui.telephony.data.repository.FakeTelephonyRepository
|
||||||
import com.android.systemui.telephony.domain.interactor.TelephonyInteractor
|
import com.android.systemui.telephony.domain.interactor.TelephonyInteractor
|
||||||
@@ -75,6 +76,7 @@ class StatusBarUserChipViewModelTest : SysuiTestCase() {
|
|||||||
@Mock private lateinit var uiEventLogger: UiEventLogger
|
@Mock private lateinit var uiEventLogger: UiEventLogger
|
||||||
@Mock private lateinit var resumeSessionReceiver: GuestResumeSessionReceiver
|
@Mock private lateinit var resumeSessionReceiver: GuestResumeSessionReceiver
|
||||||
@Mock private lateinit var resetOrExitSessionReceiver: GuestResetOrExitSessionReceiver
|
@Mock private lateinit var resetOrExitSessionReceiver: GuestResetOrExitSessionReceiver
|
||||||
|
@Mock private lateinit var commandQueue: CommandQueue
|
||||||
|
|
||||||
private lateinit var underTest: StatusBarUserChipViewModel
|
private lateinit var underTest: StatusBarUserChipViewModel
|
||||||
|
|
||||||
@@ -241,6 +243,7 @@ class StatusBarUserChipViewModelTest : SysuiTestCase() {
|
|||||||
keyguardInteractor =
|
keyguardInteractor =
|
||||||
KeyguardInteractor(
|
KeyguardInteractor(
|
||||||
repository = keyguardRepository,
|
repository = keyguardRepository,
|
||||||
|
commandQueue = commandQueue,
|
||||||
),
|
),
|
||||||
featureFlags =
|
featureFlags =
|
||||||
FakeFeatureFlags().apply { set(Flags.FULL_SCREEN_USER_SWITCHER, false) },
|
FakeFeatureFlags().apply { set(Flags.FULL_SCREEN_USER_SWITCHER, false) },
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
|
|||||||
import com.android.systemui.plugins.ActivityStarter
|
import com.android.systemui.plugins.ActivityStarter
|
||||||
import com.android.systemui.power.data.repository.FakePowerRepository
|
import com.android.systemui.power.data.repository.FakePowerRepository
|
||||||
import com.android.systemui.power.domain.interactor.PowerInteractor
|
import com.android.systemui.power.domain.interactor.PowerInteractor
|
||||||
|
import com.android.systemui.statusbar.CommandQueue
|
||||||
import com.android.systemui.statusbar.policy.DeviceProvisionedController
|
import com.android.systemui.statusbar.policy.DeviceProvisionedController
|
||||||
import com.android.systemui.telephony.data.repository.FakeTelephonyRepository
|
import com.android.systemui.telephony.data.repository.FakeTelephonyRepository
|
||||||
import com.android.systemui.telephony.domain.interactor.TelephonyInteractor
|
import com.android.systemui.telephony.domain.interactor.TelephonyInteractor
|
||||||
@@ -76,6 +77,7 @@ class UserSwitcherViewModelTest : SysuiTestCase() {
|
|||||||
@Mock private lateinit var uiEventLogger: UiEventLogger
|
@Mock private lateinit var uiEventLogger: UiEventLogger
|
||||||
@Mock private lateinit var resumeSessionReceiver: GuestResumeSessionReceiver
|
@Mock private lateinit var resumeSessionReceiver: GuestResumeSessionReceiver
|
||||||
@Mock private lateinit var resetOrExitSessionReceiver: GuestResetOrExitSessionReceiver
|
@Mock private lateinit var resetOrExitSessionReceiver: GuestResetOrExitSessionReceiver
|
||||||
|
@Mock private lateinit var commandQueue: CommandQueue
|
||||||
|
|
||||||
private lateinit var underTest: UserSwitcherViewModel
|
private lateinit var underTest: UserSwitcherViewModel
|
||||||
|
|
||||||
@@ -142,6 +144,7 @@ class UserSwitcherViewModelTest : SysuiTestCase() {
|
|||||||
keyguardInteractor =
|
keyguardInteractor =
|
||||||
KeyguardInteractor(
|
KeyguardInteractor(
|
||||||
repository = keyguardRepository,
|
repository = keyguardRepository,
|
||||||
|
commandQueue = commandQueue,
|
||||||
),
|
),
|
||||||
featureFlags =
|
featureFlags =
|
||||||
FakeFeatureFlags().apply {
|
FakeFeatureFlags().apply {
|
||||||
@@ -169,14 +172,17 @@ class UserSwitcherViewModelTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun users() = testScope.runTest {
|
fun users() =
|
||||||
|
testScope.runTest {
|
||||||
val userInfos =
|
val userInfos =
|
||||||
listOf(
|
listOf(
|
||||||
UserInfo(
|
UserInfo(
|
||||||
/* id= */ 0,
|
/* id= */ 0,
|
||||||
/* name= */ "zero",
|
/* name= */ "zero",
|
||||||
/* iconPath= */ "",
|
/* iconPath= */ "",
|
||||||
/* flags= */ UserInfo.FLAG_PRIMARY or UserInfo.FLAG_ADMIN or UserInfo.FLAG_FULL,
|
/* flags= */ UserInfo.FLAG_PRIMARY or
|
||||||
|
UserInfo.FLAG_ADMIN or
|
||||||
|
UserInfo.FLAG_FULL,
|
||||||
UserManager.USER_TYPE_FULL_SYSTEM,
|
UserManager.USER_TYPE_FULL_SYSTEM,
|
||||||
),
|
),
|
||||||
UserInfo(
|
UserInfo(
|
||||||
@@ -223,7 +229,8 @@ class UserSwitcherViewModelTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `maximumUserColumns - few users`() = testScope.runTest {
|
fun `maximumUserColumns - few users`() =
|
||||||
|
testScope.runTest {
|
||||||
setUsers(count = 2)
|
setUsers(count = 2)
|
||||||
val values = mutableListOf<Int>()
|
val values = mutableListOf<Int>()
|
||||||
val job = launch(testDispatcher) { underTest.maximumUserColumns.toList(values) }
|
val job = launch(testDispatcher) { underTest.maximumUserColumns.toList(values) }
|
||||||
@@ -234,7 +241,8 @@ class UserSwitcherViewModelTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `maximumUserColumns - many users`() = testScope.runTest {
|
fun `maximumUserColumns - many users`() =
|
||||||
|
testScope.runTest {
|
||||||
setUsers(count = 5)
|
setUsers(count = 5)
|
||||||
val values = mutableListOf<Int>()
|
val values = mutableListOf<Int>()
|
||||||
val job = launch(testDispatcher) { underTest.maximumUserColumns.toList(values) }
|
val job = launch(testDispatcher) { underTest.maximumUserColumns.toList(values) }
|
||||||
@@ -244,7 +252,8 @@ class UserSwitcherViewModelTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `isOpenMenuButtonVisible - has actions - true`() = testScope.runTest {
|
fun `isOpenMenuButtonVisible - has actions - true`() =
|
||||||
|
testScope.runTest {
|
||||||
setUsers(2)
|
setUsers(2)
|
||||||
|
|
||||||
val isVisible = mutableListOf<Boolean>()
|
val isVisible = mutableListOf<Boolean>()
|
||||||
@@ -255,7 +264,8 @@ class UserSwitcherViewModelTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `isOpenMenuButtonVisible - no actions - false`() = testScope.runTest {
|
fun `isOpenMenuButtonVisible - no actions - false`() =
|
||||||
|
testScope.runTest {
|
||||||
val userInfos = setUsers(2)
|
val userInfos = setUsers(2)
|
||||||
userRepository.setSelectedUserInfo(userInfos[1])
|
userRepository.setSelectedUserInfo(userInfos[1])
|
||||||
keyguardRepository.setKeyguardShowing(true)
|
keyguardRepository.setKeyguardShowing(true)
|
||||||
@@ -269,7 +279,8 @@ class UserSwitcherViewModelTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun menu() = testScope.runTest {
|
fun menu() =
|
||||||
|
testScope.runTest {
|
||||||
val isMenuVisible = mutableListOf<Boolean>()
|
val isMenuVisible = mutableListOf<Boolean>()
|
||||||
val job = launch(testDispatcher) { underTest.isMenuVisible.toList(isMenuVisible) }
|
val job = launch(testDispatcher) { underTest.isMenuVisible.toList(isMenuVisible) }
|
||||||
assertThat(isMenuVisible.last()).isFalse()
|
assertThat(isMenuVisible.last()).isFalse()
|
||||||
@@ -284,7 +295,8 @@ class UserSwitcherViewModelTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `menu actions`() = testScope.runTest {
|
fun `menu actions`() =
|
||||||
|
testScope.runTest {
|
||||||
setUsers(2)
|
setUsers(2)
|
||||||
val actions = mutableListOf<List<UserActionViewModel>>()
|
val actions = mutableListOf<List<UserActionViewModel>>()
|
||||||
val job = launch(testDispatcher) { underTest.menu.toList(actions) }
|
val job = launch(testDispatcher) { underTest.menu.toList(actions) }
|
||||||
@@ -303,10 +315,12 @@ class UserSwitcherViewModelTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `isFinishRequested - finishes when user is switched`() = testScope.runTest {
|
fun `isFinishRequested - finishes when user is switched`() =
|
||||||
|
testScope.runTest {
|
||||||
val userInfos = setUsers(count = 2)
|
val userInfos = setUsers(count = 2)
|
||||||
val isFinishRequested = mutableListOf<Boolean>()
|
val isFinishRequested = mutableListOf<Boolean>()
|
||||||
val job = launch(testDispatcher) { underTest.isFinishRequested.toList(isFinishRequested) }
|
val job =
|
||||||
|
launch(testDispatcher) { underTest.isFinishRequested.toList(isFinishRequested) }
|
||||||
assertThat(isFinishRequested.last()).isFalse()
|
assertThat(isFinishRequested.last()).isFalse()
|
||||||
|
|
||||||
userRepository.setSelectedUserInfo(userInfos[1])
|
userRepository.setSelectedUserInfo(userInfos[1])
|
||||||
@@ -317,11 +331,13 @@ class UserSwitcherViewModelTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `isFinishRequested - finishes when the screen turns off`() = testScope.runTest {
|
fun `isFinishRequested - finishes when the screen turns off`() =
|
||||||
|
testScope.runTest {
|
||||||
setUsers(count = 2)
|
setUsers(count = 2)
|
||||||
powerRepository.setInteractive(true)
|
powerRepository.setInteractive(true)
|
||||||
val isFinishRequested = mutableListOf<Boolean>()
|
val isFinishRequested = mutableListOf<Boolean>()
|
||||||
val job = launch(testDispatcher) { underTest.isFinishRequested.toList(isFinishRequested) }
|
val job =
|
||||||
|
launch(testDispatcher) { underTest.isFinishRequested.toList(isFinishRequested) }
|
||||||
assertThat(isFinishRequested.last()).isFalse()
|
assertThat(isFinishRequested.last()).isFalse()
|
||||||
|
|
||||||
powerRepository.setInteractive(false)
|
powerRepository.setInteractive(false)
|
||||||
@@ -332,11 +348,13 @@ class UserSwitcherViewModelTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `isFinishRequested - finishes when cancel button is clicked`() = testScope.runTest {
|
fun `isFinishRequested - finishes when cancel button is clicked`() =
|
||||||
|
testScope.runTest {
|
||||||
setUsers(count = 2)
|
setUsers(count = 2)
|
||||||
powerRepository.setInteractive(true)
|
powerRepository.setInteractive(true)
|
||||||
val isFinishRequested = mutableListOf<Boolean>()
|
val isFinishRequested = mutableListOf<Boolean>()
|
||||||
val job = launch(testDispatcher) { underTest.isFinishRequested.toList(isFinishRequested) }
|
val job =
|
||||||
|
launch(testDispatcher) { underTest.isFinishRequested.toList(isFinishRequested) }
|
||||||
assertThat(isFinishRequested.last()).isFalse()
|
assertThat(isFinishRequested.last()).isFalse()
|
||||||
|
|
||||||
underTest.onCancelButtonClicked()
|
underTest.onCancelButtonClicked()
|
||||||
@@ -351,14 +369,17 @@ class UserSwitcherViewModelTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `guest selected -- name is exit guest`() = testScope.runTest {
|
fun `guest selected -- name is exit guest`() =
|
||||||
|
testScope.runTest {
|
||||||
val userInfos =
|
val userInfos =
|
||||||
listOf(
|
listOf(
|
||||||
UserInfo(
|
UserInfo(
|
||||||
/* id= */ 0,
|
/* id= */ 0,
|
||||||
/* name= */ "zero",
|
/* name= */ "zero",
|
||||||
/* iconPath= */ "",
|
/* iconPath= */ "",
|
||||||
/* flags= */ UserInfo.FLAG_PRIMARY or UserInfo.FLAG_ADMIN or UserInfo.FLAG_FULL,
|
/* flags= */ UserInfo.FLAG_PRIMARY or
|
||||||
|
UserInfo.FLAG_ADMIN or
|
||||||
|
UserInfo.FLAG_FULL,
|
||||||
UserManager.USER_TYPE_FULL_SYSTEM,
|
UserManager.USER_TYPE_FULL_SYSTEM,
|
||||||
),
|
),
|
||||||
UserInfo(
|
UserInfo(
|
||||||
@@ -386,7 +407,8 @@ class UserSwitcherViewModelTest : SysuiTestCase() {
|
|||||||
assertUserViewModel(
|
assertUserViewModel(
|
||||||
viewModel = userViewModels.last()[1],
|
viewModel = userViewModels.last()[1],
|
||||||
viewKey = 1,
|
viewKey = 1,
|
||||||
name = Text.Resource(
|
name =
|
||||||
|
Text.Resource(
|
||||||
com.android.settingslib.R.string.guest_exit_quick_settings_button
|
com.android.settingslib.R.string.guest_exit_quick_settings_button
|
||||||
),
|
),
|
||||||
isSelectionMarkerVisible = true,
|
isSelectionMarkerVisible = true,
|
||||||
@@ -395,14 +417,17 @@ class UserSwitcherViewModelTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `guest not selected -- name is guest`() = testScope.runTest {
|
fun `guest not selected -- name is guest`() =
|
||||||
|
testScope.runTest {
|
||||||
val userInfos =
|
val userInfos =
|
||||||
listOf(
|
listOf(
|
||||||
UserInfo(
|
UserInfo(
|
||||||
/* id= */ 0,
|
/* id= */ 0,
|
||||||
/* name= */ "zero",
|
/* name= */ "zero",
|
||||||
/* iconPath= */ "",
|
/* iconPath= */ "",
|
||||||
/* flags= */ UserInfo.FLAG_PRIMARY or UserInfo.FLAG_ADMIN or UserInfo.FLAG_FULL,
|
/* flags= */ UserInfo.FLAG_PRIMARY or
|
||||||
|
UserInfo.FLAG_ADMIN or
|
||||||
|
UserInfo.FLAG_FULL,
|
||||||
UserManager.USER_TYPE_FULL_SYSTEM,
|
UserManager.USER_TYPE_FULL_SYSTEM,
|
||||||
),
|
),
|
||||||
UserInfo(
|
UserInfo(
|
||||||
|
|||||||
Reference in New Issue
Block a user