From 241a78982b0c7385fe7f0d78c31607f9dc0b9b3d Mon Sep 17 00:00:00 2001 From: Nick Chameyev Date: Fri, 18 Feb 2022 17:26:50 +0000 Subject: [PATCH] [Fold to AOD] Play fold to AOD even if we already in AOD on the inner screen Adds logic that plays fold to AOD animation even if we were already dozing on the inner screen. The aprroach is similar to the unfold animation: we use the first screen turn on event after the system reported that we are folded to trigger the animation. Bug: 202844967 Test: phone is dozing on the inner screen, fold => fold to aod animation is playing Test: phone is folded and dozing, distance sensor is covered, uncover distance sensor => fold to aod animation is not playing Test: lock/unlock phone when aod enabled/disabled Change-Id: I85008924d7565bff217696ffa95cca0149f47650 --- .../statusbar/phone/DozeServiceHost.java | 13 +++++ .../unfold/FoldAodAnimationController.kt | 48 +++++++++++++++++-- .../statusbar/phone/DozeServiceHostTest.java | 3 +- 3 files changed, 60 insertions(+), 4 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java index 6d7748388e143..05fba5498ea77 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java @@ -28,6 +28,8 @@ 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; @@ -46,8 +48,11 @@ 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 java.util.ArrayList; +import java.util.Optional; import javax.inject.Inject; @@ -73,6 +78,8 @@ 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; @@ -105,6 +112,7 @@ public final class DozeServiceHost implements DozeHost { Lazy assistManagerLazy, DozeScrimController dozeScrimController, KeyguardUpdateMonitor keyguardUpdateMonitor, PulseExpansionHandler pulseExpansionHandler, + Optional sysUIUnfoldComponent, NotificationShadeWindowController notificationShadeWindowController, NotificationWakeUpCoordinator notificationWakeUpCoordinator, AuthController authController, @@ -128,6 +136,8 @@ 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. @@ -215,6 +225,9 @@ public final class DozeServiceHost implements DozeHost { mStatusBarStateController.setIsDozing(dozing); mNotificationShadeWindowViewController.setDozing(dozing); + if (mFoldAodAnimationController != null) { + mFoldAodAnimationController.setIsDozing(dozing); + } } @Override diff --git a/packages/SystemUI/src/com/android/systemui/unfold/FoldAodAnimationController.kt b/packages/SystemUI/src/com/android/systemui/unfold/FoldAodAnimationController.kt index 2a9076e8f848d..e2374ada15d50 100644 --- a/packages/SystemUI/src/com/android/systemui/unfold/FoldAodAnimationController.kt +++ b/packages/SystemUI/src/com/android/systemui/unfold/FoldAodAnimationController.kt @@ -16,9 +16,12 @@ 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.core.view.OneShotPreDrawListener import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.keyguard.WakefulnessLifecycle import com.android.systemui.statusbar.LightRevealScrim @@ -27,6 +30,8 @@ import com.android.systemui.statusbar.phone.StatusBar import com.android.systemui.statusbar.policy.CallbackController import com.android.systemui.unfold.FoldAodAnimationController.FoldAodAnimationStatus import com.android.systemui.util.settings.GlobalSettings +import java.util.concurrent.Executor +import java.util.function.Consumer import javax.inject.Inject /** @@ -38,13 +43,21 @@ class FoldAodAnimationController @Inject constructor( @Main private val handler: Handler, + @Main private val executor: Executor, + private val context: Context, + private val deviceStateManager: DeviceStateManager, private val wakefulnessLifecycle: WakefulnessLifecycle, private val globalSettings: GlobalSettings ) : CallbackController, ScreenOffAnimation, WakefulnessLifecycle.Observer { - private var alwaysOnEnabled: Boolean = false - private var isScrimOpaque: Boolean = false private lateinit var statusBar: StatusBar + + private var isFolded = false + private var isFoldHandled = true + + private var alwaysOnEnabled: Boolean = false + private var isDozing: Boolean = false + private var isScrimOpaque: Boolean = false private var pendingScrimReadyCallback: Runnable? = null private var shouldPlayAnimation = false @@ -62,6 +75,7 @@ constructor( override fun initialize(statusBar: StatusBar, lightRevealScrim: LightRevealScrim) { this.statusBar = statusBar + deviceStateManager.registerCallback(executor, FoldListener()) wakefulnessLifecycle.addObserver(this) } @@ -84,7 +98,7 @@ constructor( override fun onStartedWakingUp() { if (isAnimationPlaying) { handler.removeCallbacks(startAnimationRunnable) - statusBar.notificationPanelViewController.cancelFoldToAodAnimation(); + statusBar.notificationPanelViewController.cancelFoldToAodAnimation() } setAnimationState(playing = false) @@ -105,11 +119,24 @@ constructor( */ fun onScreenTurningOn(onReady: Runnable) { if (shouldPlayAnimation) { + // The device was not dozing and going to sleep after folding, play the animation + if (isScrimOpaque) { onReady.run() } else { pendingScrimReadyCallback = onReady } + } else if (isFolded && !isFoldHandled && alwaysOnEnabled && isDozing) { + // Screen turning on for the first time after folding and we are already dozing + // We should play the folding to AOD animation + + setAnimationState(playing = true) + statusBar.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(statusBar.notificationPanelViewController.view, onReady) } else { // No animation, call ready callback immediately onReady.run() @@ -136,6 +163,10 @@ constructor( } } + fun setIsDozing(dozing: Boolean) { + isDozing = dozing + } + override fun isAnimationPlaying(): Boolean = isAnimationPlaying override fun isKeyguardHideDelayed(): Boolean = isAnimationPlaying() @@ -166,4 +197,15 @@ constructor( interface FoldAodAnimationStatus { fun onFoldToAodAnimationChanged() } + + private inner class FoldListener : + DeviceStateManager.FoldStateListener( + context, + Consumer { isFolded -> + if (!isFolded) { + // We are unfolded now, reset the fold handle status + isFoldHandled = false + } + this.isFolded = isFolded + }) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java index 38d7ce76f1b95..6ce3b4b7b6f93 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java @@ -59,6 +59,7 @@ import org.mockito.MockitoAnnotations; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; +import java.util.Optional; @SmallTest @RunWith(AndroidTestingRunner.class) @@ -97,7 +98,7 @@ public class DozeServiceHostTest extends SysuiTestCase { mStatusBarStateController, mDeviceProvisionedController, mHeadsUpManager, mBatteryController, mScrimController, () -> mBiometricUnlockController, mKeyguardViewMediator, () -> mAssistManager, mDozeScrimController, - mKeyguardUpdateMonitor, mPulseExpansionHandler, + mKeyguardUpdateMonitor, mPulseExpansionHandler, Optional.empty(), mNotificationShadeWindowController, mNotificationWakeUpCoordinator, mAuthController, mNotificationIconAreaController);