Loading packages/SystemUI/src/com/android/systemui/doze/DozeHost.java +5 −0 Original line number Diff line number Diff line Loading @@ -101,6 +101,11 @@ public interface DozeHost { * Called when the always on suppression state changes. See {@link #isAlwaysOnSuppressed()}. */ default void onAlwaysOnSuppressedChanged(boolean suppressed) {} /** * Called when the dozing state may have been updated. */ default void onDozingChanged(boolean isDozing) {} } interface PulseCallback { Loading packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt +16 −11 Original line number Diff line number Diff line Loading @@ -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.shared.model.Position import com.android.systemui.dagger.SysUISingleton import com.android.systemui.doze.DozeHost import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.statusbar.policy.KeyguardStateController import javax.inject.Inject Loading @@ -28,6 +29,7 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.distinctUntilChanged /** Defines interface for classes that encapsulate application state for the keyguard. */ interface KeyguardRepository { Loading Loading @@ -102,6 +104,7 @@ class KeyguardRepositoryImpl constructor( statusBarStateController: StatusBarStateController, keyguardStateController: KeyguardStateController, dozeHost: DozeHost, ) : KeyguardRepository { private val _animateBottomAreaDozingTransitions = MutableStateFlow(false) override val animateBottomAreaDozingTransitions = Loading Loading @@ -136,19 +139,21 @@ constructor( awaitClose { keyguardStateController.removeCallback(callback) } } override val isDozing: Flow<Boolean> = conflatedCallbackFlow { override val isDozing: Flow<Boolean> = conflatedCallbackFlow { val callback = object : StatusBarStateController.StateListener { object : DozeHost.Callback { override fun onDozingChanged(isDozing: Boolean) { trySendWithFailureLogging(isDozing, TAG, "updated isDozing") } } dozeHost.addCallback(callback) trySendWithFailureLogging(false, TAG, "initial isDozing: false") statusBarStateController.addCallback(callback) trySendWithFailureLogging(statusBarStateController.isDozing, TAG, "initial isDozing") awaitClose { statusBarStateController.removeCallback(callback) } awaitClose { dozeHost.removeCallback(callback) } } .distinctUntilChanged() override val dozeAmount: Flow<Float> = conflatedCallbackFlow { val callback = object : StatusBarStateController.StateListener { Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java +11 −13 Original line number Diff line number Diff line Loading @@ -28,8 +28,6 @@ import android.util.Log; import android.view.MotionEvent; import android.view.View; import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.assist.AssistManager; Loading @@ -50,11 +48,9 @@ import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.unfold.FoldAodAnimationController; import com.android.systemui.unfold.SysUIUnfoldComponent; import com.android.systemui.util.Assert; import java.util.ArrayList; import java.util.Optional; import javax.inject.Inject; Loading @@ -80,8 +76,6 @@ public final class DozeServiceHost implements DozeHost { private final WakefulnessLifecycle mWakefulnessLifecycle; private final SysuiStatusBarStateController mStatusBarStateController; private final DeviceProvisionedController mDeviceProvisionedController; @Nullable private final FoldAodAnimationController mFoldAodAnimationController; private final HeadsUpManagerPhone mHeadsUpManagerPhone; private final BatteryController mBatteryController; private final ScrimController mScrimController; Loading Loading @@ -114,7 +108,6 @@ public final class DozeServiceHost implements DozeHost { Lazy<AssistManager> assistManagerLazy, DozeScrimController dozeScrimController, KeyguardUpdateMonitor keyguardUpdateMonitor, PulseExpansionHandler pulseExpansionHandler, Optional<SysUIUnfoldComponent> sysUIUnfoldComponent, NotificationShadeWindowController notificationShadeWindowController, NotificationWakeUpCoordinator notificationWakeUpCoordinator, AuthController authController, Loading @@ -138,8 +131,6 @@ public final class DozeServiceHost implements DozeHost { mNotificationWakeUpCoordinator = notificationWakeUpCoordinator; mAuthController = authController; 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. Loading Loading @@ -167,6 +158,7 @@ public final class DozeServiceHost implements DozeHost { } void firePowerSaveChanged(boolean active) { Assert.isMainThread(); for (Callback callback : mCallbacks) { callback.onPowerSaveChanged(active); } Loading @@ -177,6 +169,7 @@ public final class DozeServiceHost implements DozeHost { entry.setPulseSuppressed(true); mNotificationIconAreaController.updateAodNotificationIcons(); }; Assert.isMainThread(); for (Callback callback : mCallbacks) { callback.onNotificationAlerted(pulseSuppressedListener); } Loading @@ -193,11 +186,13 @@ public final class DozeServiceHost implements DozeHost { @Override public void addCallback(@NonNull Callback callback) { Assert.isMainThread(); mCallbacks.add(callback); } @Override public void removeCallback(@NonNull Callback callback) { Assert.isMainThread(); mCallbacks.remove(callback); } Loading @@ -212,6 +207,8 @@ public final class DozeServiceHost implements DozeHost { } void updateDozing() { Assert.isMainThread(); // When in wake-and-unlock while pulsing, keep dozing state until fully unlocked. boolean dozing = Loading @@ -225,10 +222,10 @@ public final class DozeServiceHost implements DozeHost { dozing = false; } mStatusBarStateController.setIsDozing(dozing); if (mFoldAodAnimationController != null) { mFoldAodAnimationController.setIsDozing(dozing); for (Callback callback : mCallbacks) { callback.onDozingChanged(dozing); } mStatusBarStateController.setIsDozing(dozing); } @Override Loading Loading @@ -452,6 +449,7 @@ public final class DozeServiceHost implements DozeHost { return; } mAlwaysOnSuppressed = suppressed; Assert.isMainThread(); for (Callback callback : mCallbacks) { callback.onAlwaysOnSuppressedChanged(suppressed); } Loading packages/SystemUI/src/com/android/systemui/unfold/FoldAodAnimationController.kt +33 −18 Original line number Diff line number Diff line Loading @@ -18,22 +18,31 @@ package com.android.systemui.unfold import android.content.Context import android.hardware.devicestate.DeviceStateManager import android.os.Handler import android.os.PowerManager import android.provider.Settings import androidx.annotation.VisibleForTesting import androidx.core.view.OneShotPreDrawListener import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle import com.android.internal.util.LatencyTracker import com.android.systemui.dagger.qualifiers.Main 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.phone.CentralSurfaces import com.android.systemui.statusbar.phone.ScreenOffAnimation import com.android.systemui.statusbar.policy.CallbackController import com.android.systemui.unfold.FoldAodAnimationController.FoldAodAnimationStatus import com.android.systemui.util.concurrency.DelayableExecutor import com.android.systemui.util.settings.GlobalSettings import java.util.concurrent.Executor import dagger.Lazy import java.util.function.Consumer 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 Loading @@ -43,16 +52,16 @@ import javax.inject.Inject class FoldAodAnimationController @Inject constructor( @Main private val handler: Handler, @Main private val executor: Executor, @Main private val executor: DelayableExecutor, private val context: Context, private val deviceStateManager: DeviceStateManager, private val wakefulnessLifecycle: WakefulnessLifecycle, private val globalSettings: GlobalSettings, private val latencyTracker: LatencyTracker, private val keyguardInteractor: Lazy<KeyguardInteractor>, ) : CallbackController<FoldAodAnimationStatus>, ScreenOffAnimation, WakefulnessLifecycle.Observer { private lateinit var mCentralSurfaces: CentralSurfaces private lateinit var centralSurfaces: CentralSurfaces private var isFolded = false private var isFoldHandled = true Loading @@ -64,12 +73,13 @@ constructor( private var shouldPlayAnimation = false private var isAnimationPlaying = false private var cancelAnimation: Runnable? = null private val statusListeners = arrayListOf<FoldAodAnimationStatus>() private val foldToAodLatencyTracker = FoldToAodLatencyTracker() private val startAnimationRunnable = Runnable { mCentralSurfaces.notificationPanelViewController.startFoldToAodAnimation( centralSurfaces.notificationPanelViewController.startFoldToAodAnimation( /* startAction= */ { foldToAodLatencyTracker.onAnimationStarted() }, /* endAction= */ { setAnimationState(playing = false) }, /* cancelAction= */ { setAnimationState(playing = false) }, Loading @@ -77,10 +87,14 @@ constructor( } override fun initialize(centralSurfaces: CentralSurfaces, lightRevealScrim: LightRevealScrim) { this.mCentralSurfaces = centralSurfaces this.centralSurfaces = centralSurfaces deviceStateManager.registerCallback(executor, FoldListener()) wakefulnessLifecycle.addObserver(this) centralSurfaces.notificationPanelViewController.view.repeatWhenAttached { repeatOnLifecycle(Lifecycle.State.STARTED) { listenForDozing(this) } } } /** Returns true if we should run fold to AOD animation */ Loading @@ -94,7 +108,7 @@ constructor( override fun startAnimation(): Boolean = if (shouldStartAnimation()) { setAnimationState(playing = true) mCentralSurfaces.notificationPanelViewController.prepareFoldToAodAnimation() centralSurfaces.notificationPanelViewController.prepareFoldToAodAnimation() true } else { setAnimationState(playing = false) Loading @@ -104,8 +118,8 @@ constructor( override fun onStartedWakingUp() { if (isAnimationPlaying) { foldToAodLatencyTracker.cancel() handler.removeCallbacks(startAnimationRunnable) mCentralSurfaces.notificationPanelViewController.cancelFoldToAodAnimation() cancelAnimation?.run() centralSurfaces.notificationPanelViewController.cancelFoldToAodAnimation() } setAnimationState(playing = false) Loading Loading @@ -138,13 +152,13 @@ constructor( // We should play the folding to AOD animation setAnimationState(playing = true) mCentralSurfaces.notificationPanelViewController.prepareFoldToAodAnimation() centralSurfaces.notificationPanelViewController.prepareFoldToAodAnimation() // 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 // (setting initial alpha/translation) OneShotPreDrawListener.add( mCentralSurfaces.notificationPanelViewController.view, centralSurfaces.notificationPanelViewController.view, onReady ) } else { Loading @@ -165,18 +179,14 @@ constructor( fun onScreenTurnedOn() { if (shouldPlayAnimation) { handler.removeCallbacks(startAnimationRunnable) cancelAnimation?.run() // 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 } } fun setIsDozing(dozing: Boolean) { isDozing = dozing } override fun isAnimationPlaying(): Boolean = isAnimationPlaying override fun isKeyguardHideDelayed(): Boolean = isAnimationPlaying() Loading Loading @@ -204,6 +214,11 @@ constructor( statusListeners.remove(listener) } @VisibleForTesting internal suspend fun listenForDozing(scope: CoroutineScope): Job { return scope.launch { keyguardInteractor.get().isDozing.collect { isDozing = it } } } interface FoldAodAnimationStatus { fun onFoldToAodAnimationChanged() } Loading packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt +11 −4 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.systemui.keyguard.data.repository import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase 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.statusbar.policy.KeyguardStateController import com.android.systemui.util.mockito.argumentCaptor Loading @@ -40,6 +41,7 @@ import org.mockito.MockitoAnnotations class KeyguardRepositoryImplTest : SysuiTestCase() { @Mock private lateinit var statusBarStateController: StatusBarStateController @Mock private lateinit var dozeHost: DozeHost @Mock private lateinit var keyguardStateController: KeyguardStateController private lateinit var underTest: KeyguardRepositoryImpl Loading @@ -48,7 +50,12 @@ class KeyguardRepositoryImplTest : SysuiTestCase() { fun setUp() { MockitoAnnotations.initMocks(this) underTest = KeyguardRepositoryImpl(statusBarStateController, keyguardStateController) underTest = KeyguardRepositoryImpl( statusBarStateController, keyguardStateController, dozeHost, ) } @Test Loading Loading @@ -129,8 +136,8 @@ class KeyguardRepositoryImplTest : SysuiTestCase() { var latest: Boolean? = null val job = underTest.isDozing.onEach { latest = it }.launchIn(this) val captor = argumentCaptor<StatusBarStateController.StateListener>() verify(statusBarStateController).addCallback(captor.capture()) val captor = argumentCaptor<DozeHost.Callback>() verify(dozeHost).addCallback(captor.capture()) captor.value.onDozingChanged(true) assertThat(latest).isTrue() Loading @@ -139,7 +146,7 @@ class KeyguardRepositoryImplTest : SysuiTestCase() { assertThat(latest).isFalse() job.cancel() verify(statusBarStateController).removeCallback(captor.value) verify(dozeHost).removeCallback(captor.value) } @Test Loading Loading
packages/SystemUI/src/com/android/systemui/doze/DozeHost.java +5 −0 Original line number Diff line number Diff line Loading @@ -101,6 +101,11 @@ public interface DozeHost { * Called when the always on suppression state changes. See {@link #isAlwaysOnSuppressed()}. */ default void onAlwaysOnSuppressedChanged(boolean suppressed) {} /** * Called when the dozing state may have been updated. */ default void onDozingChanged(boolean isDozing) {} } interface PulseCallback { Loading
packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt +16 −11 Original line number Diff line number Diff line Loading @@ -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.shared.model.Position import com.android.systemui.dagger.SysUISingleton import com.android.systemui.doze.DozeHost import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.statusbar.policy.KeyguardStateController import javax.inject.Inject Loading @@ -28,6 +29,7 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.distinctUntilChanged /** Defines interface for classes that encapsulate application state for the keyguard. */ interface KeyguardRepository { Loading Loading @@ -102,6 +104,7 @@ class KeyguardRepositoryImpl constructor( statusBarStateController: StatusBarStateController, keyguardStateController: KeyguardStateController, dozeHost: DozeHost, ) : KeyguardRepository { private val _animateBottomAreaDozingTransitions = MutableStateFlow(false) override val animateBottomAreaDozingTransitions = Loading Loading @@ -136,19 +139,21 @@ constructor( awaitClose { keyguardStateController.removeCallback(callback) } } override val isDozing: Flow<Boolean> = conflatedCallbackFlow { override val isDozing: Flow<Boolean> = conflatedCallbackFlow { val callback = object : StatusBarStateController.StateListener { object : DozeHost.Callback { override fun onDozingChanged(isDozing: Boolean) { trySendWithFailureLogging(isDozing, TAG, "updated isDozing") } } dozeHost.addCallback(callback) trySendWithFailureLogging(false, TAG, "initial isDozing: false") statusBarStateController.addCallback(callback) trySendWithFailureLogging(statusBarStateController.isDozing, TAG, "initial isDozing") awaitClose { statusBarStateController.removeCallback(callback) } awaitClose { dozeHost.removeCallback(callback) } } .distinctUntilChanged() override val dozeAmount: Flow<Float> = conflatedCallbackFlow { val callback = object : StatusBarStateController.StateListener { Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java +11 −13 Original line number Diff line number Diff line Loading @@ -28,8 +28,6 @@ import android.util.Log; import android.view.MotionEvent; import android.view.View; import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.assist.AssistManager; Loading @@ -50,11 +48,9 @@ import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.unfold.FoldAodAnimationController; import com.android.systemui.unfold.SysUIUnfoldComponent; import com.android.systemui.util.Assert; import java.util.ArrayList; import java.util.Optional; import javax.inject.Inject; Loading @@ -80,8 +76,6 @@ public final class DozeServiceHost implements DozeHost { private final WakefulnessLifecycle mWakefulnessLifecycle; private final SysuiStatusBarStateController mStatusBarStateController; private final DeviceProvisionedController mDeviceProvisionedController; @Nullable private final FoldAodAnimationController mFoldAodAnimationController; private final HeadsUpManagerPhone mHeadsUpManagerPhone; private final BatteryController mBatteryController; private final ScrimController mScrimController; Loading Loading @@ -114,7 +108,6 @@ public final class DozeServiceHost implements DozeHost { Lazy<AssistManager> assistManagerLazy, DozeScrimController dozeScrimController, KeyguardUpdateMonitor keyguardUpdateMonitor, PulseExpansionHandler pulseExpansionHandler, Optional<SysUIUnfoldComponent> sysUIUnfoldComponent, NotificationShadeWindowController notificationShadeWindowController, NotificationWakeUpCoordinator notificationWakeUpCoordinator, AuthController authController, Loading @@ -138,8 +131,6 @@ public final class DozeServiceHost implements DozeHost { mNotificationWakeUpCoordinator = notificationWakeUpCoordinator; mAuthController = authController; 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. Loading Loading @@ -167,6 +158,7 @@ public final class DozeServiceHost implements DozeHost { } void firePowerSaveChanged(boolean active) { Assert.isMainThread(); for (Callback callback : mCallbacks) { callback.onPowerSaveChanged(active); } Loading @@ -177,6 +169,7 @@ public final class DozeServiceHost implements DozeHost { entry.setPulseSuppressed(true); mNotificationIconAreaController.updateAodNotificationIcons(); }; Assert.isMainThread(); for (Callback callback : mCallbacks) { callback.onNotificationAlerted(pulseSuppressedListener); } Loading @@ -193,11 +186,13 @@ public final class DozeServiceHost implements DozeHost { @Override public void addCallback(@NonNull Callback callback) { Assert.isMainThread(); mCallbacks.add(callback); } @Override public void removeCallback(@NonNull Callback callback) { Assert.isMainThread(); mCallbacks.remove(callback); } Loading @@ -212,6 +207,8 @@ public final class DozeServiceHost implements DozeHost { } void updateDozing() { Assert.isMainThread(); // When in wake-and-unlock while pulsing, keep dozing state until fully unlocked. boolean dozing = Loading @@ -225,10 +222,10 @@ public final class DozeServiceHost implements DozeHost { dozing = false; } mStatusBarStateController.setIsDozing(dozing); if (mFoldAodAnimationController != null) { mFoldAodAnimationController.setIsDozing(dozing); for (Callback callback : mCallbacks) { callback.onDozingChanged(dozing); } mStatusBarStateController.setIsDozing(dozing); } @Override Loading Loading @@ -452,6 +449,7 @@ public final class DozeServiceHost implements DozeHost { return; } mAlwaysOnSuppressed = suppressed; Assert.isMainThread(); for (Callback callback : mCallbacks) { callback.onAlwaysOnSuppressedChanged(suppressed); } Loading
packages/SystemUI/src/com/android/systemui/unfold/FoldAodAnimationController.kt +33 −18 Original line number Diff line number Diff line Loading @@ -18,22 +18,31 @@ package com.android.systemui.unfold import android.content.Context import android.hardware.devicestate.DeviceStateManager import android.os.Handler import android.os.PowerManager import android.provider.Settings import androidx.annotation.VisibleForTesting import androidx.core.view.OneShotPreDrawListener import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle import com.android.internal.util.LatencyTracker import com.android.systemui.dagger.qualifiers.Main 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.phone.CentralSurfaces import com.android.systemui.statusbar.phone.ScreenOffAnimation import com.android.systemui.statusbar.policy.CallbackController import com.android.systemui.unfold.FoldAodAnimationController.FoldAodAnimationStatus import com.android.systemui.util.concurrency.DelayableExecutor import com.android.systemui.util.settings.GlobalSettings import java.util.concurrent.Executor import dagger.Lazy import java.util.function.Consumer 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 Loading @@ -43,16 +52,16 @@ import javax.inject.Inject class FoldAodAnimationController @Inject constructor( @Main private val handler: Handler, @Main private val executor: Executor, @Main private val executor: DelayableExecutor, private val context: Context, private val deviceStateManager: DeviceStateManager, private val wakefulnessLifecycle: WakefulnessLifecycle, private val globalSettings: GlobalSettings, private val latencyTracker: LatencyTracker, private val keyguardInteractor: Lazy<KeyguardInteractor>, ) : CallbackController<FoldAodAnimationStatus>, ScreenOffAnimation, WakefulnessLifecycle.Observer { private lateinit var mCentralSurfaces: CentralSurfaces private lateinit var centralSurfaces: CentralSurfaces private var isFolded = false private var isFoldHandled = true Loading @@ -64,12 +73,13 @@ constructor( private var shouldPlayAnimation = false private var isAnimationPlaying = false private var cancelAnimation: Runnable? = null private val statusListeners = arrayListOf<FoldAodAnimationStatus>() private val foldToAodLatencyTracker = FoldToAodLatencyTracker() private val startAnimationRunnable = Runnable { mCentralSurfaces.notificationPanelViewController.startFoldToAodAnimation( centralSurfaces.notificationPanelViewController.startFoldToAodAnimation( /* startAction= */ { foldToAodLatencyTracker.onAnimationStarted() }, /* endAction= */ { setAnimationState(playing = false) }, /* cancelAction= */ { setAnimationState(playing = false) }, Loading @@ -77,10 +87,14 @@ constructor( } override fun initialize(centralSurfaces: CentralSurfaces, lightRevealScrim: LightRevealScrim) { this.mCentralSurfaces = centralSurfaces this.centralSurfaces = centralSurfaces deviceStateManager.registerCallback(executor, FoldListener()) wakefulnessLifecycle.addObserver(this) centralSurfaces.notificationPanelViewController.view.repeatWhenAttached { repeatOnLifecycle(Lifecycle.State.STARTED) { listenForDozing(this) } } } /** Returns true if we should run fold to AOD animation */ Loading @@ -94,7 +108,7 @@ constructor( override fun startAnimation(): Boolean = if (shouldStartAnimation()) { setAnimationState(playing = true) mCentralSurfaces.notificationPanelViewController.prepareFoldToAodAnimation() centralSurfaces.notificationPanelViewController.prepareFoldToAodAnimation() true } else { setAnimationState(playing = false) Loading @@ -104,8 +118,8 @@ constructor( override fun onStartedWakingUp() { if (isAnimationPlaying) { foldToAodLatencyTracker.cancel() handler.removeCallbacks(startAnimationRunnable) mCentralSurfaces.notificationPanelViewController.cancelFoldToAodAnimation() cancelAnimation?.run() centralSurfaces.notificationPanelViewController.cancelFoldToAodAnimation() } setAnimationState(playing = false) Loading Loading @@ -138,13 +152,13 @@ constructor( // We should play the folding to AOD animation setAnimationState(playing = true) mCentralSurfaces.notificationPanelViewController.prepareFoldToAodAnimation() centralSurfaces.notificationPanelViewController.prepareFoldToAodAnimation() // 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 // (setting initial alpha/translation) OneShotPreDrawListener.add( mCentralSurfaces.notificationPanelViewController.view, centralSurfaces.notificationPanelViewController.view, onReady ) } else { Loading @@ -165,18 +179,14 @@ constructor( fun onScreenTurnedOn() { if (shouldPlayAnimation) { handler.removeCallbacks(startAnimationRunnable) cancelAnimation?.run() // 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 } } fun setIsDozing(dozing: Boolean) { isDozing = dozing } override fun isAnimationPlaying(): Boolean = isAnimationPlaying override fun isKeyguardHideDelayed(): Boolean = isAnimationPlaying() Loading Loading @@ -204,6 +214,11 @@ constructor( statusListeners.remove(listener) } @VisibleForTesting internal suspend fun listenForDozing(scope: CoroutineScope): Job { return scope.launch { keyguardInteractor.get().isDozing.collect { isDozing = it } } } interface FoldAodAnimationStatus { fun onFoldToAodAnimationChanged() } Loading
packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt +11 −4 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.systemui.keyguard.data.repository import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase 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.statusbar.policy.KeyguardStateController import com.android.systemui.util.mockito.argumentCaptor Loading @@ -40,6 +41,7 @@ import org.mockito.MockitoAnnotations class KeyguardRepositoryImplTest : SysuiTestCase() { @Mock private lateinit var statusBarStateController: StatusBarStateController @Mock private lateinit var dozeHost: DozeHost @Mock private lateinit var keyguardStateController: KeyguardStateController private lateinit var underTest: KeyguardRepositoryImpl Loading @@ -48,7 +50,12 @@ class KeyguardRepositoryImplTest : SysuiTestCase() { fun setUp() { MockitoAnnotations.initMocks(this) underTest = KeyguardRepositoryImpl(statusBarStateController, keyguardStateController) underTest = KeyguardRepositoryImpl( statusBarStateController, keyguardStateController, dozeHost, ) } @Test Loading Loading @@ -129,8 +136,8 @@ class KeyguardRepositoryImplTest : SysuiTestCase() { var latest: Boolean? = null val job = underTest.isDozing.onEach { latest = it }.launchIn(this) val captor = argumentCaptor<StatusBarStateController.StateListener>() verify(statusBarStateController).addCallback(captor.capture()) val captor = argumentCaptor<DozeHost.Callback>() verify(dozeHost).addCallback(captor.capture()) captor.value.onDozingChanged(true) assertThat(latest).isTrue() Loading @@ -139,7 +146,7 @@ class KeyguardRepositoryImplTest : SysuiTestCase() { assertThat(latest).isFalse() job.cancel() verify(statusBarStateController).removeCallback(captor.value) verify(dozeHost).removeCallback(captor.value) } @Test Loading