Merge "Rewire setDozing() to use repositories" into tm-qpr-dev am: 3b625dece1
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19732716 Change-Id: I2ec6f8f912e4bb9ba3f2938c5a747e6140538723 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -101,6 +101,11 @@ public interface DozeHost {
|
|||||||
* Called when the always on suppression state changes. See {@link #isAlwaysOnSuppressed()}.
|
* Called when the always on suppression state changes. See {@link #isAlwaysOnSuppressed()}.
|
||||||
*/
|
*/
|
||||||
default void onAlwaysOnSuppressedChanged(boolean suppressed) {}
|
default void onAlwaysOnSuppressedChanged(boolean suppressed) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the dozing state may have been updated.
|
||||||
|
*/
|
||||||
|
default void onDozingChanged(boolean isDozing) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PulseCallback {
|
interface PulseCallback {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLoggin
|
|||||||
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
|
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
|
||||||
import com.android.systemui.common.shared.model.Position
|
import com.android.systemui.common.shared.model.Position
|
||||||
import com.android.systemui.dagger.SysUISingleton
|
import com.android.systemui.dagger.SysUISingleton
|
||||||
|
import com.android.systemui.doze.DozeHost
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -28,6 +29,7 @@ import kotlinx.coroutines.flow.Flow
|
|||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
|
|
||||||
/** Defines interface for classes that encapsulate application state for the keyguard. */
|
/** Defines interface for classes that encapsulate application state for the keyguard. */
|
||||||
interface KeyguardRepository {
|
interface KeyguardRepository {
|
||||||
@@ -102,6 +104,7 @@ class KeyguardRepositoryImpl
|
|||||||
constructor(
|
constructor(
|
||||||
statusBarStateController: StatusBarStateController,
|
statusBarStateController: StatusBarStateController,
|
||||||
keyguardStateController: KeyguardStateController,
|
keyguardStateController: KeyguardStateController,
|
||||||
|
dozeHost: DozeHost,
|
||||||
) : KeyguardRepository {
|
) : KeyguardRepository {
|
||||||
private val _animateBottomAreaDozingTransitions = MutableStateFlow(false)
|
private val _animateBottomAreaDozingTransitions = MutableStateFlow(false)
|
||||||
override val animateBottomAreaDozingTransitions =
|
override val animateBottomAreaDozingTransitions =
|
||||||
@@ -136,19 +139,21 @@ constructor(
|
|||||||
awaitClose { keyguardStateController.removeCallback(callback) }
|
awaitClose { keyguardStateController.removeCallback(callback) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override val isDozing: Flow<Boolean> = conflatedCallbackFlow {
|
override val isDozing: Flow<Boolean> =
|
||||||
val callback =
|
conflatedCallbackFlow {
|
||||||
object : StatusBarStateController.StateListener {
|
val callback =
|
||||||
override fun onDozingChanged(isDozing: Boolean) {
|
object : DozeHost.Callback {
|
||||||
trySendWithFailureLogging(isDozing, TAG, "updated isDozing")
|
override fun onDozingChanged(isDozing: Boolean) {
|
||||||
}
|
trySendWithFailureLogging(isDozing, TAG, "updated isDozing")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dozeHost.addCallback(callback)
|
||||||
|
trySendWithFailureLogging(false, TAG, "initial isDozing: false")
|
||||||
|
|
||||||
|
awaitClose { dozeHost.removeCallback(callback) }
|
||||||
}
|
}
|
||||||
|
.distinctUntilChanged()
|
||||||
|
|
||||||
statusBarStateController.addCallback(callback)
|
|
||||||
trySendWithFailureLogging(statusBarStateController.isDozing, TAG, "initial isDozing")
|
|
||||||
|
|
||||||
awaitClose { statusBarStateController.removeCallback(callback) }
|
|
||||||
}
|
|
||||||
override val dozeAmount: Flow<Float> = conflatedCallbackFlow {
|
override val dozeAmount: Flow<Float> = conflatedCallbackFlow {
|
||||||
val callback =
|
val callback =
|
||||||
object : StatusBarStateController.StateListener {
|
object : StatusBarStateController.StateListener {
|
||||||
|
|||||||
@@ -28,8 +28,6 @@ import android.util.Log;
|
|||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||||
import com.android.systemui.assist.AssistManager;
|
import com.android.systemui.assist.AssistManager;
|
||||||
@@ -50,11 +48,9 @@ import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator
|
|||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||||
import com.android.systemui.statusbar.policy.BatteryController;
|
import com.android.systemui.statusbar.policy.BatteryController;
|
||||||
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
|
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
|
||||||
import com.android.systemui.unfold.FoldAodAnimationController;
|
import com.android.systemui.util.Assert;
|
||||||
import com.android.systemui.unfold.SysUIUnfoldComponent;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@@ -80,8 +76,6 @@ public final class DozeServiceHost implements DozeHost {
|
|||||||
private final WakefulnessLifecycle mWakefulnessLifecycle;
|
private final WakefulnessLifecycle mWakefulnessLifecycle;
|
||||||
private final SysuiStatusBarStateController mStatusBarStateController;
|
private final SysuiStatusBarStateController mStatusBarStateController;
|
||||||
private final DeviceProvisionedController mDeviceProvisionedController;
|
private final DeviceProvisionedController mDeviceProvisionedController;
|
||||||
@Nullable
|
|
||||||
private final FoldAodAnimationController mFoldAodAnimationController;
|
|
||||||
private final HeadsUpManagerPhone mHeadsUpManagerPhone;
|
private final HeadsUpManagerPhone mHeadsUpManagerPhone;
|
||||||
private final BatteryController mBatteryController;
|
private final BatteryController mBatteryController;
|
||||||
private final ScrimController mScrimController;
|
private final ScrimController mScrimController;
|
||||||
@@ -114,7 +108,6 @@ public final class DozeServiceHost implements DozeHost {
|
|||||||
Lazy<AssistManager> assistManagerLazy,
|
Lazy<AssistManager> assistManagerLazy,
|
||||||
DozeScrimController dozeScrimController, KeyguardUpdateMonitor keyguardUpdateMonitor,
|
DozeScrimController dozeScrimController, KeyguardUpdateMonitor keyguardUpdateMonitor,
|
||||||
PulseExpansionHandler pulseExpansionHandler,
|
PulseExpansionHandler pulseExpansionHandler,
|
||||||
Optional<SysUIUnfoldComponent> sysUIUnfoldComponent,
|
|
||||||
NotificationShadeWindowController notificationShadeWindowController,
|
NotificationShadeWindowController notificationShadeWindowController,
|
||||||
NotificationWakeUpCoordinator notificationWakeUpCoordinator,
|
NotificationWakeUpCoordinator notificationWakeUpCoordinator,
|
||||||
AuthController authController,
|
AuthController authController,
|
||||||
@@ -138,8 +131,6 @@ public final class DozeServiceHost implements DozeHost {
|
|||||||
mNotificationWakeUpCoordinator = notificationWakeUpCoordinator;
|
mNotificationWakeUpCoordinator = notificationWakeUpCoordinator;
|
||||||
mAuthController = authController;
|
mAuthController = authController;
|
||||||
mNotificationIconAreaController = notificationIconAreaController;
|
mNotificationIconAreaController = notificationIconAreaController;
|
||||||
mFoldAodAnimationController = sysUIUnfoldComponent
|
|
||||||
.map(SysUIUnfoldComponent::getFoldAodAnimationController).orElse(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: we should try to not pass status bar in here if we can avoid it.
|
// TODO: we should try to not pass status bar in here if we can avoid it.
|
||||||
@@ -167,6 +158,7 @@ public final class DozeServiceHost implements DozeHost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void firePowerSaveChanged(boolean active) {
|
void firePowerSaveChanged(boolean active) {
|
||||||
|
Assert.isMainThread();
|
||||||
for (Callback callback : mCallbacks) {
|
for (Callback callback : mCallbacks) {
|
||||||
callback.onPowerSaveChanged(active);
|
callback.onPowerSaveChanged(active);
|
||||||
}
|
}
|
||||||
@@ -177,6 +169,7 @@ public final class DozeServiceHost implements DozeHost {
|
|||||||
entry.setPulseSuppressed(true);
|
entry.setPulseSuppressed(true);
|
||||||
mNotificationIconAreaController.updateAodNotificationIcons();
|
mNotificationIconAreaController.updateAodNotificationIcons();
|
||||||
};
|
};
|
||||||
|
Assert.isMainThread();
|
||||||
for (Callback callback : mCallbacks) {
|
for (Callback callback : mCallbacks) {
|
||||||
callback.onNotificationAlerted(pulseSuppressedListener);
|
callback.onNotificationAlerted(pulseSuppressedListener);
|
||||||
}
|
}
|
||||||
@@ -193,11 +186,13 @@ public final class DozeServiceHost implements DozeHost {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addCallback(@NonNull Callback callback) {
|
public void addCallback(@NonNull Callback callback) {
|
||||||
|
Assert.isMainThread();
|
||||||
mCallbacks.add(callback);
|
mCallbacks.add(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeCallback(@NonNull Callback callback) {
|
public void removeCallback(@NonNull Callback callback) {
|
||||||
|
Assert.isMainThread();
|
||||||
mCallbacks.remove(callback);
|
mCallbacks.remove(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,6 +207,8 @@ public final class DozeServiceHost implements DozeHost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void updateDozing() {
|
void updateDozing() {
|
||||||
|
Assert.isMainThread();
|
||||||
|
|
||||||
// When in wake-and-unlock while pulsing, keep dozing state until fully unlocked.
|
// When in wake-and-unlock while pulsing, keep dozing state until fully unlocked.
|
||||||
boolean
|
boolean
|
||||||
dozing =
|
dozing =
|
||||||
@@ -225,10 +222,10 @@ public final class DozeServiceHost implements DozeHost {
|
|||||||
dozing = false;
|
dozing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mStatusBarStateController.setIsDozing(dozing);
|
for (Callback callback : mCallbacks) {
|
||||||
if (mFoldAodAnimationController != null) {
|
callback.onDozingChanged(dozing);
|
||||||
mFoldAodAnimationController.setIsDozing(dozing);
|
|
||||||
}
|
}
|
||||||
|
mStatusBarStateController.setIsDozing(dozing);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -452,6 +449,7 @@ public final class DozeServiceHost implements DozeHost {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mAlwaysOnSuppressed = suppressed;
|
mAlwaysOnSuppressed = suppressed;
|
||||||
|
Assert.isMainThread();
|
||||||
for (Callback callback : mCallbacks) {
|
for (Callback callback : mCallbacks) {
|
||||||
callback.onAlwaysOnSuppressedChanged(suppressed);
|
callback.onAlwaysOnSuppressedChanged(suppressed);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,22 +18,31 @@ package com.android.systemui.unfold
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.hardware.devicestate.DeviceStateManager
|
import android.hardware.devicestate.DeviceStateManager
|
||||||
import android.os.Handler
|
|
||||||
import android.os.PowerManager
|
import android.os.PowerManager
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
|
import androidx.annotation.VisibleForTesting
|
||||||
import androidx.core.view.OneShotPreDrawListener
|
import androidx.core.view.OneShotPreDrawListener
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
import com.android.internal.util.LatencyTracker
|
import com.android.internal.util.LatencyTracker
|
||||||
import com.android.systemui.dagger.qualifiers.Main
|
import com.android.systemui.dagger.qualifiers.Main
|
||||||
import com.android.systemui.keyguard.WakefulnessLifecycle
|
import com.android.systemui.keyguard.WakefulnessLifecycle
|
||||||
|
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
|
||||||
|
import com.android.systemui.lifecycle.repeatWhenAttached
|
||||||
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.statusbar.phone.ScreenOffAnimation
|
import com.android.systemui.statusbar.phone.ScreenOffAnimation
|
||||||
import com.android.systemui.statusbar.policy.CallbackController
|
import com.android.systemui.statusbar.policy.CallbackController
|
||||||
import com.android.systemui.unfold.FoldAodAnimationController.FoldAodAnimationStatus
|
import com.android.systemui.unfold.FoldAodAnimationController.FoldAodAnimationStatus
|
||||||
|
import com.android.systemui.util.concurrency.DelayableExecutor
|
||||||
import com.android.systemui.util.settings.GlobalSettings
|
import com.android.systemui.util.settings.GlobalSettings
|
||||||
import java.util.concurrent.Executor
|
import dagger.Lazy
|
||||||
import java.util.function.Consumer
|
import java.util.function.Consumer
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.flow.collect
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controls folding to AOD animation: when AOD is enabled and foldable device is folded we play a
|
* Controls folding to AOD animation: when AOD is enabled and foldable device is folded we play a
|
||||||
@@ -43,16 +52,16 @@ import javax.inject.Inject
|
|||||||
class FoldAodAnimationController
|
class FoldAodAnimationController
|
||||||
@Inject
|
@Inject
|
||||||
constructor(
|
constructor(
|
||||||
@Main private val handler: Handler,
|
@Main private val executor: DelayableExecutor,
|
||||||
@Main private val executor: Executor,
|
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val deviceStateManager: DeviceStateManager,
|
private val deviceStateManager: DeviceStateManager,
|
||||||
private val wakefulnessLifecycle: WakefulnessLifecycle,
|
private val wakefulnessLifecycle: WakefulnessLifecycle,
|
||||||
private val globalSettings: GlobalSettings,
|
private val globalSettings: GlobalSettings,
|
||||||
private val latencyTracker: LatencyTracker,
|
private val latencyTracker: LatencyTracker,
|
||||||
|
private val keyguardInteractor: Lazy<KeyguardInteractor>,
|
||||||
) : CallbackController<FoldAodAnimationStatus>, ScreenOffAnimation, WakefulnessLifecycle.Observer {
|
) : CallbackController<FoldAodAnimationStatus>, ScreenOffAnimation, WakefulnessLifecycle.Observer {
|
||||||
|
|
||||||
private lateinit var mCentralSurfaces: CentralSurfaces
|
private lateinit var centralSurfaces: CentralSurfaces
|
||||||
|
|
||||||
private var isFolded = false
|
private var isFolded = false
|
||||||
private var isFoldHandled = true
|
private var isFoldHandled = true
|
||||||
@@ -64,12 +73,13 @@ constructor(
|
|||||||
|
|
||||||
private var shouldPlayAnimation = false
|
private var shouldPlayAnimation = false
|
||||||
private var isAnimationPlaying = false
|
private var isAnimationPlaying = false
|
||||||
|
private var cancelAnimation: Runnable? = null
|
||||||
|
|
||||||
private val statusListeners = arrayListOf<FoldAodAnimationStatus>()
|
private val statusListeners = arrayListOf<FoldAodAnimationStatus>()
|
||||||
private val foldToAodLatencyTracker = FoldToAodLatencyTracker()
|
private val foldToAodLatencyTracker = FoldToAodLatencyTracker()
|
||||||
|
|
||||||
private val startAnimationRunnable = Runnable {
|
private val startAnimationRunnable = Runnable {
|
||||||
mCentralSurfaces.notificationPanelViewController.startFoldToAodAnimation(
|
centralSurfaces.notificationPanelViewController.startFoldToAodAnimation(
|
||||||
/* startAction= */ { foldToAodLatencyTracker.onAnimationStarted() },
|
/* startAction= */ { foldToAodLatencyTracker.onAnimationStarted() },
|
||||||
/* endAction= */ { setAnimationState(playing = false) },
|
/* endAction= */ { setAnimationState(playing = false) },
|
||||||
/* cancelAction= */ { setAnimationState(playing = false) },
|
/* cancelAction= */ { setAnimationState(playing = false) },
|
||||||
@@ -77,10 +87,14 @@ constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun initialize(centralSurfaces: CentralSurfaces, lightRevealScrim: LightRevealScrim) {
|
override fun initialize(centralSurfaces: CentralSurfaces, lightRevealScrim: LightRevealScrim) {
|
||||||
this.mCentralSurfaces = centralSurfaces
|
this.centralSurfaces = centralSurfaces
|
||||||
|
|
||||||
deviceStateManager.registerCallback(executor, FoldListener())
|
deviceStateManager.registerCallback(executor, FoldListener())
|
||||||
wakefulnessLifecycle.addObserver(this)
|
wakefulnessLifecycle.addObserver(this)
|
||||||
|
|
||||||
|
centralSurfaces.notificationPanelViewController.view.repeatWhenAttached {
|
||||||
|
repeatOnLifecycle(Lifecycle.State.STARTED) { listenForDozing(this) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns true if we should run fold to AOD animation */
|
/** Returns true if we should run fold to AOD animation */
|
||||||
@@ -94,7 +108,7 @@ constructor(
|
|||||||
override fun startAnimation(): Boolean =
|
override fun startAnimation(): Boolean =
|
||||||
if (shouldStartAnimation()) {
|
if (shouldStartAnimation()) {
|
||||||
setAnimationState(playing = true)
|
setAnimationState(playing = true)
|
||||||
mCentralSurfaces.notificationPanelViewController.prepareFoldToAodAnimation()
|
centralSurfaces.notificationPanelViewController.prepareFoldToAodAnimation()
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
setAnimationState(playing = false)
|
setAnimationState(playing = false)
|
||||||
@@ -104,8 +118,8 @@ constructor(
|
|||||||
override fun onStartedWakingUp() {
|
override fun onStartedWakingUp() {
|
||||||
if (isAnimationPlaying) {
|
if (isAnimationPlaying) {
|
||||||
foldToAodLatencyTracker.cancel()
|
foldToAodLatencyTracker.cancel()
|
||||||
handler.removeCallbacks(startAnimationRunnable)
|
cancelAnimation?.run()
|
||||||
mCentralSurfaces.notificationPanelViewController.cancelFoldToAodAnimation()
|
centralSurfaces.notificationPanelViewController.cancelFoldToAodAnimation()
|
||||||
}
|
}
|
||||||
|
|
||||||
setAnimationState(playing = false)
|
setAnimationState(playing = false)
|
||||||
@@ -138,13 +152,13 @@ constructor(
|
|||||||
// We should play the folding to AOD animation
|
// We should play the folding to AOD animation
|
||||||
|
|
||||||
setAnimationState(playing = true)
|
setAnimationState(playing = true)
|
||||||
mCentralSurfaces.notificationPanelViewController.prepareFoldToAodAnimation()
|
centralSurfaces.notificationPanelViewController.prepareFoldToAodAnimation()
|
||||||
|
|
||||||
// We don't need to wait for the scrim as it is already displayed
|
// We don't need to wait for the scrim as it is already displayed
|
||||||
// but we should wait for the initial animation preparations to be drawn
|
// but we should wait for the initial animation preparations to be drawn
|
||||||
// (setting initial alpha/translation)
|
// (setting initial alpha/translation)
|
||||||
OneShotPreDrawListener.add(
|
OneShotPreDrawListener.add(
|
||||||
mCentralSurfaces.notificationPanelViewController.view,
|
centralSurfaces.notificationPanelViewController.view,
|
||||||
onReady
|
onReady
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
@@ -165,18 +179,14 @@ constructor(
|
|||||||
|
|
||||||
fun onScreenTurnedOn() {
|
fun onScreenTurnedOn() {
|
||||||
if (shouldPlayAnimation) {
|
if (shouldPlayAnimation) {
|
||||||
handler.removeCallbacks(startAnimationRunnable)
|
cancelAnimation?.run()
|
||||||
|
|
||||||
// Post starting the animation to the next frame to avoid junk due to inset changes
|
// Post starting the animation to the next frame to avoid junk due to inset changes
|
||||||
handler.post(startAnimationRunnable)
|
cancelAnimation = executor.executeDelayed(startAnimationRunnable, /* delayMillis= */ 0)
|
||||||
shouldPlayAnimation = false
|
shouldPlayAnimation = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setIsDozing(dozing: Boolean) {
|
|
||||||
isDozing = dozing
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun isAnimationPlaying(): Boolean = isAnimationPlaying
|
override fun isAnimationPlaying(): Boolean = isAnimationPlaying
|
||||||
|
|
||||||
override fun isKeyguardHideDelayed(): Boolean = isAnimationPlaying()
|
override fun isKeyguardHideDelayed(): Boolean = isAnimationPlaying()
|
||||||
@@ -204,6 +214,11 @@ constructor(
|
|||||||
statusListeners.remove(listener)
|
statusListeners.remove(listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
internal suspend fun listenForDozing(scope: CoroutineScope): Job {
|
||||||
|
return scope.launch { keyguardInteractor.get().isDozing.collect { isDozing = it } }
|
||||||
|
}
|
||||||
|
|
||||||
interface FoldAodAnimationStatus {
|
interface FoldAodAnimationStatus {
|
||||||
fun onFoldToAodAnimationChanged()
|
fun onFoldToAodAnimationChanged()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package com.android.systemui.keyguard.data.repository
|
|||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
import com.android.systemui.common.shared.model.Position
|
import com.android.systemui.common.shared.model.Position
|
||||||
|
import com.android.systemui.doze.DozeHost
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||||
import com.android.systemui.util.mockito.argumentCaptor
|
import com.android.systemui.util.mockito.argumentCaptor
|
||||||
@@ -40,6 +41,7 @@ import org.mockito.MockitoAnnotations
|
|||||||
class KeyguardRepositoryImplTest : SysuiTestCase() {
|
class KeyguardRepositoryImplTest : SysuiTestCase() {
|
||||||
|
|
||||||
@Mock private lateinit var statusBarStateController: StatusBarStateController
|
@Mock private lateinit var statusBarStateController: StatusBarStateController
|
||||||
|
@Mock private lateinit var dozeHost: DozeHost
|
||||||
@Mock private lateinit var keyguardStateController: KeyguardStateController
|
@Mock private lateinit var keyguardStateController: KeyguardStateController
|
||||||
|
|
||||||
private lateinit var underTest: KeyguardRepositoryImpl
|
private lateinit var underTest: KeyguardRepositoryImpl
|
||||||
@@ -48,7 +50,12 @@ class KeyguardRepositoryImplTest : SysuiTestCase() {
|
|||||||
fun setUp() {
|
fun setUp() {
|
||||||
MockitoAnnotations.initMocks(this)
|
MockitoAnnotations.initMocks(this)
|
||||||
|
|
||||||
underTest = KeyguardRepositoryImpl(statusBarStateController, keyguardStateController)
|
underTest =
|
||||||
|
KeyguardRepositoryImpl(
|
||||||
|
statusBarStateController,
|
||||||
|
keyguardStateController,
|
||||||
|
dozeHost,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -129,8 +136,8 @@ class KeyguardRepositoryImplTest : SysuiTestCase() {
|
|||||||
var latest: Boolean? = null
|
var latest: Boolean? = null
|
||||||
val job = underTest.isDozing.onEach { latest = it }.launchIn(this)
|
val job = underTest.isDozing.onEach { latest = it }.launchIn(this)
|
||||||
|
|
||||||
val captor = argumentCaptor<StatusBarStateController.StateListener>()
|
val captor = argumentCaptor<DozeHost.Callback>()
|
||||||
verify(statusBarStateController).addCallback(captor.capture())
|
verify(dozeHost).addCallback(captor.capture())
|
||||||
|
|
||||||
captor.value.onDozingChanged(true)
|
captor.value.onDozingChanged(true)
|
||||||
assertThat(latest).isTrue()
|
assertThat(latest).isTrue()
|
||||||
@@ -139,7 +146,7 @@ class KeyguardRepositoryImplTest : SysuiTestCase() {
|
|||||||
assertThat(latest).isFalse()
|
assertThat(latest).isFalse()
|
||||||
|
|
||||||
job.cancel()
|
job.cancel()
|
||||||
verify(statusBarStateController).removeCallback(captor.value)
|
verify(dozeHost).removeCallback(captor.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import static org.mockito.Mockito.when;
|
|||||||
|
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.testing.AndroidTestingRunner;
|
import android.testing.AndroidTestingRunner;
|
||||||
|
import android.testing.TestableLooper.RunWithLooper;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
@@ -61,10 +62,10 @@ import org.mockito.MockitoAnnotations;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@RunWith(AndroidTestingRunner.class)
|
@RunWith(AndroidTestingRunner.class)
|
||||||
|
@RunWithLooper(setAsMainLooper = true)
|
||||||
public class DozeServiceHostTest extends SysuiTestCase {
|
public class DozeServiceHostTest extends SysuiTestCase {
|
||||||
|
|
||||||
private DozeServiceHost mDozeServiceHost;
|
private DozeServiceHost mDozeServiceHost;
|
||||||
@@ -92,6 +93,7 @@ public class DozeServiceHostTest extends SysuiTestCase {
|
|||||||
@Mock private View mAmbientIndicationContainer;
|
@Mock private View mAmbientIndicationContainer;
|
||||||
@Mock private BiometricUnlockController mBiometricUnlockController;
|
@Mock private BiometricUnlockController mBiometricUnlockController;
|
||||||
@Mock private AuthController mAuthController;
|
@Mock private AuthController mAuthController;
|
||||||
|
@Mock private DozeHost.Callback mCallback;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
@@ -100,7 +102,7 @@ public class DozeServiceHostTest extends SysuiTestCase {
|
|||||||
mStatusBarStateController, mDeviceProvisionedController, mHeadsUpManager,
|
mStatusBarStateController, mDeviceProvisionedController, mHeadsUpManager,
|
||||||
mBatteryController, mScrimController, () -> mBiometricUnlockController,
|
mBatteryController, mScrimController, () -> mBiometricUnlockController,
|
||||||
mKeyguardViewMediator, () -> mAssistManager, mDozeScrimController,
|
mKeyguardViewMediator, () -> mAssistManager, mDozeScrimController,
|
||||||
mKeyguardUpdateMonitor, mPulseExpansionHandler, Optional.empty(),
|
mKeyguardUpdateMonitor, mPulseExpansionHandler,
|
||||||
mNotificationShadeWindowController, mNotificationWakeUpCoordinator,
|
mNotificationShadeWindowController, mNotificationWakeUpCoordinator,
|
||||||
mAuthController, mNotificationIconAreaController);
|
mAuthController, mNotificationIconAreaController);
|
||||||
|
|
||||||
@@ -114,16 +116,19 @@ public class DozeServiceHostTest extends SysuiTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStartStopDozing() {
|
public void testStartStopDozing() {
|
||||||
|
mDozeServiceHost.addCallback(mCallback);
|
||||||
when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
|
when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
|
||||||
when(mStatusBarStateController.isKeyguardRequested()).thenReturn(true);
|
when(mStatusBarStateController.isKeyguardRequested()).thenReturn(true);
|
||||||
|
|
||||||
assertFalse(mDozeServiceHost.getDozingRequested());
|
assertFalse(mDozeServiceHost.getDozingRequested());
|
||||||
|
|
||||||
mDozeServiceHost.startDozing();
|
mDozeServiceHost.startDozing();
|
||||||
|
verify(mCallback).onDozingChanged(eq(true));
|
||||||
verify(mStatusBarStateController).setIsDozing(eq(true));
|
verify(mStatusBarStateController).setIsDozing(eq(true));
|
||||||
verify(mCentralSurfaces).updateIsKeyguard();
|
verify(mCentralSurfaces).updateIsKeyguard();
|
||||||
|
|
||||||
mDozeServiceHost.stopDozing();
|
mDozeServiceHost.stopDozing();
|
||||||
|
verify(mCallback).onDozingChanged(eq(false));
|
||||||
verify(mStatusBarStateController).setIsDozing(eq(false));
|
verify(mStatusBarStateController).setIsDozing(eq(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,24 +18,28 @@ package com.android.systemui.unfold
|
|||||||
|
|
||||||
import android.hardware.devicestate.DeviceStateManager
|
import android.hardware.devicestate.DeviceStateManager
|
||||||
import android.hardware.devicestate.DeviceStateManager.FoldStateListener
|
import android.hardware.devicestate.DeviceStateManager.FoldStateListener
|
||||||
import android.os.Handler
|
|
||||||
import android.os.PowerManager
|
import android.os.PowerManager
|
||||||
import android.testing.AndroidTestingRunner
|
import android.testing.AndroidTestingRunner
|
||||||
import android.testing.TestableLooper
|
|
||||||
import android.testing.TestableLooper.RunWithLooper
|
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.ViewTreeObserver
|
import android.view.ViewTreeObserver
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
import com.android.internal.util.LatencyTracker
|
import com.android.internal.util.LatencyTracker
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
import com.android.systemui.keyguard.WakefulnessLifecycle
|
import com.android.systemui.keyguard.WakefulnessLifecycle
|
||||||
|
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
|
||||||
|
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.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
|
||||||
import com.android.systemui.unfold.util.FoldableTestUtils
|
import com.android.systemui.unfold.util.FoldableTestUtils
|
||||||
|
import com.android.systemui.util.concurrency.FakeExecutor
|
||||||
import com.android.systemui.util.mockito.any
|
import com.android.systemui.util.mockito.any
|
||||||
import com.android.systemui.util.settings.GlobalSettings
|
import com.android.systemui.util.settings.GlobalSettings
|
||||||
|
import com.android.systemui.util.time.FakeSystemClock
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import kotlinx.coroutines.yield
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
@@ -49,7 +53,6 @@ import org.mockito.MockitoAnnotations
|
|||||||
|
|
||||||
@RunWith(AndroidTestingRunner::class)
|
@RunWith(AndroidTestingRunner::class)
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@RunWithLooper
|
|
||||||
class FoldAodAnimationControllerTest : SysuiTestCase() {
|
class FoldAodAnimationControllerTest : SysuiTestCase() {
|
||||||
|
|
||||||
@Mock lateinit var deviceStateManager: DeviceStateManager
|
@Mock lateinit var deviceStateManager: DeviceStateManager
|
||||||
@@ -74,26 +77,15 @@ class FoldAodAnimationControllerTest : SysuiTestCase() {
|
|||||||
|
|
||||||
private lateinit var deviceStates: FoldableDeviceStates
|
private lateinit var deviceStates: FoldableDeviceStates
|
||||||
|
|
||||||
private lateinit var testableLooper: TestableLooper
|
lateinit var keyguardRepository: FakeKeyguardRepository
|
||||||
|
|
||||||
lateinit var foldAodAnimationController: FoldAodAnimationController
|
lateinit var underTest: FoldAodAnimationController
|
||||||
|
private val fakeExecutor = FakeExecutor(FakeSystemClock())
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
MockitoAnnotations.initMocks(this)
|
MockitoAnnotations.initMocks(this)
|
||||||
testableLooper = TestableLooper.get(this)
|
|
||||||
|
|
||||||
foldAodAnimationController =
|
|
||||||
FoldAodAnimationController(
|
|
||||||
Handler(testableLooper.looper),
|
|
||||||
context.mainExecutor,
|
|
||||||
context,
|
|
||||||
deviceStateManager,
|
|
||||||
wakefulnessLifecycle,
|
|
||||||
globalSettings,
|
|
||||||
latencyTracker,
|
|
||||||
)
|
|
||||||
.apply { initialize(centralSurfaces, lightRevealScrim) }
|
|
||||||
deviceStates = FoldableTestUtils.findDeviceStates(context)
|
deviceStates = FoldableTestUtils.findDeviceStates(context)
|
||||||
|
|
||||||
whenever(notificationPanelViewController.view).thenReturn(viewGroup)
|
whenever(notificationPanelViewController.view).thenReturn(viewGroup)
|
||||||
@@ -107,60 +99,102 @@ class FoldAodAnimationControllerTest : SysuiTestCase() {
|
|||||||
val onActionStarted = it.arguments[0] as Runnable
|
val onActionStarted = it.arguments[0] as Runnable
|
||||||
onActionStarted.run()
|
onActionStarted.run()
|
||||||
}
|
}
|
||||||
verify(deviceStateManager).registerCallback(any(), foldStateListenerCaptor.capture())
|
|
||||||
|
|
||||||
foldAodAnimationController.setIsDozing(dozing = true)
|
keyguardRepository = FakeKeyguardRepository()
|
||||||
setAodEnabled(enabled = true)
|
val keyguardInteractor = KeyguardInteractor(repository = keyguardRepository)
|
||||||
sendFoldEvent(folded = false)
|
|
||||||
|
// Needs to be run on the main thread
|
||||||
|
runBlocking(IMMEDIATE) {
|
||||||
|
underTest =
|
||||||
|
FoldAodAnimationController(
|
||||||
|
fakeExecutor,
|
||||||
|
context,
|
||||||
|
deviceStateManager,
|
||||||
|
wakefulnessLifecycle,
|
||||||
|
globalSettings,
|
||||||
|
latencyTracker,
|
||||||
|
{ keyguardInteractor },
|
||||||
|
)
|
||||||
|
.apply { initialize(centralSurfaces, lightRevealScrim) }
|
||||||
|
|
||||||
|
verify(deviceStateManager).registerCallback(any(), foldStateListenerCaptor.capture())
|
||||||
|
|
||||||
|
setAodEnabled(enabled = true)
|
||||||
|
sendFoldEvent(folded = false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun onFolded_aodDisabled_doesNotLogLatency() {
|
fun onFolded_aodDisabled_doesNotLogLatency() =
|
||||||
setAodEnabled(enabled = false)
|
runBlocking(IMMEDIATE) {
|
||||||
|
val job = underTest.listenForDozing(this)
|
||||||
|
keyguardRepository.setDozing(true)
|
||||||
|
setAodEnabled(enabled = false)
|
||||||
|
|
||||||
fold()
|
yield()
|
||||||
simulateScreenTurningOn()
|
|
||||||
|
|
||||||
verifyNoMoreInteractions(latencyTracker)
|
fold()
|
||||||
}
|
simulateScreenTurningOn()
|
||||||
|
|
||||||
|
verifyNoMoreInteractions(latencyTracker)
|
||||||
|
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun onFolded_aodEnabled_logsLatency() {
|
fun onFolded_aodEnabled_logsLatency() =
|
||||||
setAodEnabled(enabled = true)
|
runBlocking(IMMEDIATE) {
|
||||||
|
val job = underTest.listenForDozing(this)
|
||||||
|
keyguardRepository.setDozing(true)
|
||||||
|
setAodEnabled(enabled = true)
|
||||||
|
|
||||||
fold()
|
yield()
|
||||||
simulateScreenTurningOn()
|
|
||||||
|
|
||||||
verify(latencyTracker).onActionStart(any())
|
fold()
|
||||||
verify(latencyTracker).onActionEnd(any())
|
simulateScreenTurningOn()
|
||||||
}
|
|
||||||
|
verify(latencyTracker).onActionStart(any())
|
||||||
|
verify(latencyTracker).onActionEnd(any())
|
||||||
|
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun onFolded_animationCancelled_doesNotLogLatency() {
|
fun onFolded_animationCancelled_doesNotLogLatency() =
|
||||||
setAodEnabled(enabled = true)
|
runBlocking(IMMEDIATE) {
|
||||||
|
val job = underTest.listenForDozing(this)
|
||||||
|
keyguardRepository.setDozing(true)
|
||||||
|
setAodEnabled(enabled = true)
|
||||||
|
|
||||||
fold()
|
yield()
|
||||||
foldAodAnimationController.onScreenTurningOn({})
|
|
||||||
foldAodAnimationController.onStartedWakingUp()
|
|
||||||
testableLooper.processAllMessages()
|
|
||||||
|
|
||||||
verify(latencyTracker).onActionStart(any())
|
fold()
|
||||||
verify(latencyTracker).onActionCancel(any())
|
underTest.onScreenTurningOn({})
|
||||||
}
|
underTest.onStartedWakingUp()
|
||||||
|
fakeExecutor.runAllReady()
|
||||||
|
|
||||||
|
verify(latencyTracker).onActionStart(any())
|
||||||
|
verify(latencyTracker).onActionCancel(any())
|
||||||
|
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
private fun simulateScreenTurningOn() {
|
private fun simulateScreenTurningOn() {
|
||||||
foldAodAnimationController.onScreenTurningOn({})
|
underTest.onScreenTurningOn({})
|
||||||
foldAodAnimationController.onScreenTurnedOn()
|
underTest.onScreenTurnedOn()
|
||||||
testableLooper.processAllMessages()
|
fakeExecutor.runAllReady()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun fold() = sendFoldEvent(folded = true)
|
private fun fold() = sendFoldEvent(folded = true)
|
||||||
|
|
||||||
private fun setAodEnabled(enabled: Boolean) =
|
private fun setAodEnabled(enabled: Boolean) = underTest.onAlwaysOnChanged(alwaysOn = enabled)
|
||||||
foldAodAnimationController.onAlwaysOnChanged(alwaysOn = enabled)
|
|
||||||
|
|
||||||
private fun sendFoldEvent(folded: Boolean) {
|
private fun sendFoldEvent(folded: Boolean) {
|
||||||
val state = if (folded) deviceStates.folded else deviceStates.unfolded
|
val state = if (folded) deviceStates.folded else deviceStates.unfolded
|
||||||
foldStateListenerCaptor.value.onStateChanged(state)
|
foldStateListenerCaptor.value.onStateChanged(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val IMMEDIATE = Dispatchers.Main.immediate
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user