summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Josh Tsuji <tsuji@google.com> 2021-05-26 18:40:12 -0400
committer Josh Tsuji <tsuji@google.com> 2021-05-27 16:26:22 -0400
commitee89a547f15bfc6d07553304f295ad7204ebec23 (patch)
tree0a3262ce5b0955acb18ffe697f13f7ade6de064f
parent018e1142021bb8f9a2b0332921c16d4e86804acf (diff)
Adds the ScreenOffAnimationController, which fixes multiple issues with unlocked screen off.
This changes the screen off animation so that the controller directly animates the LightRevealScrim and the shade keyguard UI, rather then tying these to the dozeAmount. This makes it easier for us to manage/cancel these animations, such as during the camera launch gesture, since the various doze components update their state asynchronously. This approach also means that instead of actually changing everything to KEYGUARD as soon as the power button is pressed, we actually just show the LightRevealScrim and the shade's AOD UI. This results in far less jank. We then actually show the keyguard once the animation finishes or is cancelled. Bug: 169693662 Bug: 169739682 Bug: 181020504 Fixes: 185567665 Fixes: 189342687 Fixes: 185567665 Fixes: 183195436 Test: atest SystemUITests Test: trigger screen off and cancel it Test: trigger screen off and don't cancel it, make sure it wakes up fine Test: disable 'power button locks instantly' and make sure it doesn't lock the device, both when the animation finishes or when it's cancelled Test: press the power button twice in rapid succession Test: press the power button twice in slower succession about 200ms apart (which triggers the camera onWakingUp vs onFinishedGoingToSleep) Test: press the power button 5 times, make sure emergency gesture comes up Test: disable AOD, observe no screen off animation and lock functionality works Change-Id: I1c44304becdadfd37bab7fd81286a9702e5d6141
-rw-r--r--core/java/com/android/internal/policy/IKeyguardService.aidl4
-rw-r--r--packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java39
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java13
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java48
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java63
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java31
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java28
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java35
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt178
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java4
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java12
-rw-r--r--services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java8
-rw-r--r--services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java5
24 files changed, 406 insertions, 131 deletions
diff --git a/core/java/com/android/internal/policy/IKeyguardService.aidl b/core/java/com/android/internal/policy/IKeyguardService.aidl
index b01e4a83a438..76aa7a015d2f 100644
--- a/core/java/com/android/internal/policy/IKeyguardService.aidl
+++ b/core/java/com/android/internal/policy/IKeyguardService.aidl
@@ -63,8 +63,10 @@ oneway interface IKeyguardService {
* @param pmWakeReason One of PowerManager.WAKE_REASON_*, detailing the reason we're waking up,
* such as WAKE_REASON_POWER_BUTTON or WAKE_REASON_GESTURE.
+ * @param cameraGestureTriggered Whether we're waking up due to a power button double tap
+ * gesture.
*/
- void onStartedWakingUp(int pmWakeReason);
+ void onStartedWakingUp(int pmWakeReason, boolean cameraGestureTriggered);
/**
* Called when the device has finished waking up.
diff --git a/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java b/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java
index 7cb4846cf7e7..92af58eb9af4 100644
--- a/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java
@@ -107,6 +107,21 @@ public class AnimatableClockController extends ViewController<AnimatableClockVie
}
};
+ private final StatusBarStateController.StateListener mStatusBarStatePersistentListener =
+ new StatusBarStateController.StateListener() {
+ @Override
+ public void onDozeAmountChanged(float linear, float eased) {
+ boolean noAnimation = (mDozeAmount == 0f && linear == 1f)
+ || (mDozeAmount == 1f && linear == 0f);
+ boolean isDozing = linear > mDozeAmount;
+ mDozeAmount = linear;
+ if (mIsDozing != isDozing) {
+ mIsDozing = isDozing;
+ mView.animateDoze(mIsDozing, !noAnimation);
+ }
+ }
+ };
+
private final KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback =
new KeyguardUpdateMonitorCallback() {
@Override
@@ -133,14 +148,15 @@ public class AnimatableClockController extends ViewController<AnimatableClockVie
updateLocale();
mBroadcastDispatcher.registerReceiver(mLocaleBroadcastReceiver,
new IntentFilter(Intent.ACTION_LOCALE_CHANGED));
- mStatusBarStateController.addCallback(mStatusBarStateListener);
-
mIsDozing = mStatusBarStateController.isDozing();
mDozeAmount = mStatusBarStateController.getDozeAmount();
mBatteryController.addCallback(mBatteryCallback);
mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateMonitorCallback);
mKeyguardShowing = true;
+ mStatusBarStateController.removeCallback(mStatusBarStatePersistentListener);
+ mStatusBarStateController.addCallback(mStatusBarStatePersistentListener);
+
refreshTime();
initColors();
mView.animateDoze(mIsDozing, false);
@@ -149,9 +165,11 @@ public class AnimatableClockController extends ViewController<AnimatableClockVie
@Override
protected void onViewDetached() {
mBroadcastDispatcher.unregisterReceiver(mLocaleBroadcastReceiver);
- mStatusBarStateController.removeCallback(mStatusBarStateListener);
mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateMonitorCallback);
mBatteryController.removeCallback(mBatteryCallback);
+ if (!mView.isAttachedToWindow()) {
+ mStatusBarStateController.removeCallback(mStatusBarStatePersistentListener);
+ }
}
/** Animate the clock appearance */
@@ -199,19 +217,4 @@ public class AnimatableClockController extends ViewController<AnimatableClockVie
mView.setColors(mDozingColor, mLockScreenColor);
mView.animateDoze(mIsDozing, false);
}
-
- private final StatusBarStateController.StateListener mStatusBarStateListener =
- new StatusBarStateController.StateListener() {
- @Override
- public void onDozeAmountChanged(float linear, float eased) {
- boolean noAnimation = (mDozeAmount == 0f && linear == 1f)
- || (mDozeAmount == 1f && linear == 0f);
- boolean isDozing = linear > mDozeAmount;
- mDozeAmount = linear;
- if (mIsDozing != isDozing) {
- mIsDozing = isDozing;
- mView.animateDoze(mIsDozing, !noAnimation);
- }
- }
- };
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
index 7b6514a63195..89ca507aad8d 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
@@ -27,6 +27,7 @@ import com.android.systemui.statusbar.notification.PropertyAnimator;
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.ViewController;
@@ -66,7 +67,8 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
ConfigurationController configurationController,
DozeParameters dozeParameters,
KeyguardUnlockAnimationController keyguardUnlockAnimationController,
- SmartspaceTransitionController smartspaceTransitionController) {
+ SmartspaceTransitionController smartspaceTransitionController,
+ UnlockedScreenOffAnimationController unlockedScreenOffAnimationController) {
super(keyguardStatusView);
mKeyguardSliceViewController = keyguardSliceViewController;
mKeyguardClockSwitchController = keyguardClockSwitchController;
@@ -75,7 +77,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
mDozeParameters = dozeParameters;
mKeyguardStateController = keyguardStateController;
mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, keyguardStateController,
- dozeParameters);
+ dozeParameters, unlockedScreenOffAnimationController);
mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
mSmartspaceTransitionController = smartspaceTransitionController;
@@ -238,13 +240,6 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
}
/**
- * @return {@code true} if we are currently animating the screen off from unlock
- */
- public boolean isAnimatingScreenOffFromUnlocked() {
- return mKeyguardVisibilityHelper.isAnimatingScreenOffFromUnlocked();
- }
-
- /**
* Set the visibility of the keyguard status view based on some new state.
*/
public void setKeyguardStatusViewVisibility(
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java b/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java
index b6a58dc7cb91..7edecc80a27e 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java
@@ -27,6 +27,7 @@ import com.android.systemui.statusbar.notification.PropertyAnimator;
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
/**
@@ -38,16 +39,19 @@ public class KeyguardVisibilityHelper {
private View mView;
private final KeyguardStateController mKeyguardStateController;
private final DozeParameters mDozeParameters;
+ private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
private boolean mKeyguardViewVisibilityAnimating;
private boolean mLastOccludedState = false;
- private boolean mAnimatingScreenOff;
private final AnimationProperties mAnimationProperties = new AnimationProperties();
- public KeyguardVisibilityHelper(View view, KeyguardStateController keyguardStateController,
- DozeParameters dozeParameters) {
+ public KeyguardVisibilityHelper(View view,
+ KeyguardStateController keyguardStateController,
+ DozeParameters dozeParameters,
+ UnlockedScreenOffAnimationController unlockedScreenOffAnimationController) {
mView = view;
mKeyguardStateController = keyguardStateController;
mDozeParameters = dozeParameters;
+ mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
}
public boolean isVisibilityAnimating() {
@@ -122,32 +126,14 @@ public class KeyguardVisibilityHelper {
.alpha(1f)
.withEndAction(mAnimateKeyguardStatusViewVisibleEndRunnable)
.start();
- } else if (mDozeParameters.shouldControlUnlockedScreenOff()) {
+ } else if (mUnlockedScreenOffAnimationController
+ .isScreenOffLightRevealAnimationPlaying()) {
mKeyguardViewVisibilityAnimating = true;
- mAnimatingScreenOff = true;
-
- mView.setVisibility(View.VISIBLE);
- mView.setAlpha(0f);
- float currentY = mView.getY();
- mView.setY(currentY - mView.getHeight() * 0.1f);
- int duration = StackStateAnimator.ANIMATION_DURATION_WAKEUP;
- int delay = (int) (duration * .6f);
- // We animate the Y properly separately using the PropertyAnimator, as the panel
- // view als needs to update the end position.
- mAnimationProperties.setDuration(duration).setDelay(delay);
- PropertyAnimator.cancelAnimation(mView, AnimatableProperty.Y);
- PropertyAnimator.setProperty(mView, AnimatableProperty.Y, currentY,
- mAnimationProperties,
- true /* animate */);
-
- mView.animate()
- .setStartDelay(delay)
- .setDuration(duration)
- .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
- .alpha(1f)
- .withEndAction(mAnimateKeyguardStatusViewVisibleEndRunnable)
- .start();
+ // Ask the screen off animation controller to animate the keyguard visibility for us
+ // since it may need to be cancelled due to keyguard lifecycle events.
+ mUnlockedScreenOffAnimationController.animateInKeyguard(
+ mView, mAnimateKeyguardStatusViewVisibleEndRunnable);
} else {
mView.setVisibility(View.VISIBLE);
mView.setAlpha(1f);
@@ -172,13 +158,5 @@ public class KeyguardVisibilityHelper {
private final Runnable mAnimateKeyguardStatusViewVisibleEndRunnable = () -> {
mKeyguardViewVisibilityAnimating = false;
- mAnimatingScreenOff = false;
};
-
- /**
- * @return {@code true} if we are currently animating the screen off from unlock
- */
- public boolean isAnimatingScreenOffFromUnlocked() {
- return mAnimatingScreenOff;
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index 666afed41c35..009134361a69 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -232,10 +232,11 @@ public class KeyguardService extends Service {
}
@Override // Binder interface
- public void onStartedWakingUp(@PowerManager.WakeReason int pmWakeReason) {
+ public void onStartedWakingUp(
+ @PowerManager.WakeReason int pmWakeReason, boolean cameraGestureTriggered) {
Trace.beginSection("KeyguardService.mBinder#onStartedWakingUp");
checkPermission();
- mKeyguardViewMediator.onStartedWakingUp();
+ mKeyguardViewMediator.onStartedWakingUp(cameraGestureTriggered);
mKeyguardLifecyclesDispatcher.dispatch(
KeyguardLifecyclesDispatcher.STARTED_WAKING_UP, pmWakeReason);
Trace.endSection();
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 36a0acc6fb4c..30d152542d76 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -104,12 +104,14 @@ import com.android.systemui.keyguard.dagger.KeyguardModule;
import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.shared.system.QuickStepContract;
+import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.phone.BiometricUnlockController;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationPanelViewController;
import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.DeviceConfigProxy;
@@ -232,6 +234,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable,
private StatusBarManager mStatusBarManager;
private final SysuiStatusBarStateController mStatusBarStateController;
private final Executor mUiBgExecutor;
+ private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
private boolean mSystemReady;
private boolean mBootCompleted;
@@ -385,6 +388,19 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable,
private boolean mPendingLock;
/**
+ * Whether a power button gesture (such as double tap for camera) has been detected. This is
+ * delivered directly from {@link KeyguardService}, immediately upon the gesture being detected.
+ * This is used in {@link #onStartedWakingUp} to decide whether to execute the pending lock, or
+ * ignore and reset it because we are actually launching an activity.
+ *
+ * This needs to be delivered directly to us, rather than waiting for
+ * {@link CommandQueue#onCameraLaunchGestureDetected}, because that call is asynchronous and is
+ * often delivered after the call to {@link #onStartedWakingUp}, which results in us locking the
+ * keyguard and then launching the activity behind it.
+ */
+ private boolean mPowerGestureIntercepted = false;
+
+ /**
* Controller for showing individual "work challenge" lock screen windows inside managed profile
* tasks when the current user has been unlocked but the profile is still locked.
*/
@@ -783,7 +799,8 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable,
DozeParameters dozeParameters,
SysuiStatusBarStateController statusBarStateController,
KeyguardStateController keyguardStateController,
- Lazy<KeyguardUnlockAnimationController> keyguardUnlockAnimationControllerLazy) {
+ Lazy<KeyguardUnlockAnimationController> keyguardUnlockAnimationControllerLazy,
+ UnlockedScreenOffAnimationController unlockedScreenOffAnimationController) {
super(context);
mFalsingCollector = falsingCollector;
mLockPatternUtils = lockPatternUtils;
@@ -815,6 +832,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable,
mKeyguardStateController = keyguardStateController;
mKeyguardUnlockAnimationControllerLazy = keyguardUnlockAnimationControllerLazy;
+ mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
}
public void userActivity() {
@@ -934,6 +952,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable,
if (DEBUG) Log.d(TAG, "onStartedGoingToSleep(" + offReason + ")");
synchronized (this) {
mDeviceInteractive = false;
+ mPowerGestureIntercepted = false;
mGoingToSleep = true;
// Reset keyguard going away state so we can start listening for fingerprint. We
@@ -1003,7 +1022,6 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable,
notifyFinishedGoingToSleep();
if (cameraGestureTriggered) {
- Log.i(TAG, "Camera gesture was triggered, preventing Keyguard locking.");
// Just to make sure, make sure the device is awake.
mContext.getSystemService(PowerManager.class).wakeUp(SystemClock.uptimeMillis(),
@@ -1018,10 +1036,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable,
mPendingReset = false;
}
- if (mPendingLock) {
- doKeyguardLocked(null);
- mPendingLock = false;
- }
+ maybeHandlePendingLock();
// We do not have timeout and power button instant lock setting for profile lock.
// So we use the personal setting if there is any. But if there is no device
@@ -1034,6 +1049,20 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable,
mUpdateMonitor.dispatchFinishedGoingToSleep(offReason);
}
+ /**
+ * Locks the keyguard if {@link #mPendingLock} is true, unless we're playing the screen off
+ * animation.
+ *
+ * If we are, we will lock the keyguard either when the screen off animation ends, or in
+ * {@link #onStartedWakingUp} if the animation is cancelled.
+ */
+ public void maybeHandlePendingLock() {
+ if (mPendingLock && !mUnlockedScreenOffAnimationController.isScreenOffAnimationPlaying()) {
+ doKeyguardLocked(null);
+ mPendingLock = false;
+ }
+ }
+
private boolean isKeyguardServiceEnabled() {
try {
return mContext.getPackageManager().getServiceInfo(
@@ -1142,12 +1171,15 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable,
/**
* Let's us know when the device is waking up.
*/
- public void onStartedWakingUp() {
+ public void onStartedWakingUp(boolean cameraGestureTriggered) {
Trace.beginSection("KeyguardViewMediator#onStartedWakingUp");
// TODO: Rename all screen off/on references to interactive/sleeping
synchronized (this) {
mDeviceInteractive = true;
+ if (mPendingLock && !cameraGestureTriggered) {
+ doKeyguardLocked(null);
+ }
mAnimatingScreenOff = false;
cancelDoKeyguardLaterLocked();
cancelDoKeyguardForChildProfilesLocked();
@@ -1954,6 +1986,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable,
mHiding = false;
mWakeAndUnlocking = false;
+ mPendingLock = false;
setShowingLocked(true);
mKeyguardViewControllerLazy.get().show(options);
resetKeyguardDonePendingLocked();
@@ -2577,7 +2610,12 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable,
if (!dozing) {
mAnimatingScreenOff = false;
}
- setShowingLocked(mShowing);
+
+ // Don't hide the keyguard due to a doze change if there's a lock pending, because we're
+ // just going to show it again.
+ if (mShowing || !mPendingLock) {
+ setShowingLocked(mShowing);
+ }
}
@Override
@@ -2634,14 +2672,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable,
mAodShowing = aodShowing;
if (notifyDefaultDisplayCallbacks) {
notifyDefaultDisplayCallbacks(showing);
-
- if (!showing || !mAnimatingScreenOff) {
- // Update the activity lock screen state unless we're animating in the keyguard
- // for a screen off animation. In that case, we want the activity to remain visible
- // until the animation completes. setShowingLocked is called again when the
- // animation ends, so the activity lock screen will be shown at that time.
- updateActivityLockScreenState(showing, aodShowing);
- }
+ updateActivityLockScreenState(showing, aodShowing);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
index 119e9c433f67..b071b943d8f0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
@@ -51,6 +51,7 @@ import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.KeyguardLiftController;
import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.util.sensors.AsyncSensorManager;
@@ -97,7 +98,8 @@ public class KeyguardModule {
DozeParameters dozeParameters,
SysuiStatusBarStateController statusBarStateController,
KeyguardStateController keyguardStateController,
- Lazy<KeyguardUnlockAnimationController> keyguardUnlockAnimationController) {
+ Lazy<KeyguardUnlockAnimationController> keyguardUnlockAnimationController,
+ UnlockedScreenOffAnimationController unlockedScreenOffAnimationController) {
return new KeyguardViewMediator(
context,
falsingCollector,
@@ -116,7 +118,8 @@ public class KeyguardModule {
dozeParameters,
statusBarStateController,
keyguardStateController,
- keyguardUnlockAnimationController
+ keyguardUnlockAnimationController,
+ unlockedScreenOffAnimationController
);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
index 7afb0151aeda..84728f699e91 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
@@ -28,6 +28,7 @@ import com.android.systemui.statusbar.notification.stack.StackStateAnimator
import com.android.systemui.statusbar.phone.DozeParameters
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.phone.PanelExpansionListener
+import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController
import com.android.systemui.statusbar.policy.HeadsUpManager
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener
import javax.inject.Inject
@@ -38,7 +39,8 @@ class NotificationWakeUpCoordinator @Inject constructor(
private val mHeadsUpManager: HeadsUpManager,
private val statusBarStateController: StatusBarStateController,
private val bypassController: KeyguardBypassController,
- private val dozeParameters: DozeParameters
+ private val dozeParameters: DozeParameters,
+ private val unlockedScreenOffAnimationController: UnlockedScreenOffAnimationController
) : OnHeadsUpChangedListener, StatusBarStateController.StateListener, PanelExpansionListener {
private val mNotificationVisibility = object : FloatProperty<NotificationWakeUpCoordinator>(
@@ -264,7 +266,7 @@ class NotificationWakeUpCoordinator @Inject constructor(
}
override fun onStateChanged(newState: Int) {
- if (dozeParameters.shouldControlUnlockedScreenOff()) {
+ if (unlockedScreenOffAnimationController.shouldPlayScreenOffAnimation()) {
if (animatingScreenOff &&
state == StatusBarState.KEYGUARD &&
newState == StatusBarState.SHADE) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index efcde46a7fb7..56b1a8e1f891 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -335,6 +335,8 @@ public class NotificationPanelViewController extends PanelViewController {
private NotificationsQuickSettingsContainer mNotificationContainerParent;
private boolean mAnimateNextPositionUpdate;
private float mQuickQsOffsetHeight;
+ private UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
+
private int mTrackingPointer;
private VelocityTracker mQsVelocityTracker;
private boolean mQsTracking;
@@ -671,7 +673,8 @@ public class NotificationPanelViewController extends PanelViewController {
FragmentService fragmentService,
QuickAccessWalletController quickAccessWalletController,
@Main Executor uiExecutor,
- SecureSettings secureSettings) {
+ SecureSettings secureSettings,
+ UnlockedScreenOffAnimationController unlockedScreenOffAnimationController) {
super(view, falsingManager, dozeLog, keyguardStateController,
(SysuiStatusBarStateController) statusBarStateController, vibratorHelper,
statusBarKeyguardViewManager, latencyTracker, flingAnimationUtilsBuilder.get(),
@@ -766,6 +769,7 @@ public class NotificationPanelViewController extends PanelViewController {
mConversationNotificationManager = conversationNotificationManager;
mAuthController = authController;
mLockIconViewController = lockIconViewController;
+ mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
mView.setBackgroundColor(Color.TRANSPARENT);
OnAttachStateChangeListener onAttachStateChangeListener = new OnAttachStateChangeListener();
@@ -1241,10 +1245,11 @@ public class NotificationPanelViewController extends PanelViewController {
int userIconHeight = mKeyguardQsUserSwitchController != null
? mKeyguardQsUserSwitchController.getUserIconHeight() : 0;
float expandedFraction =
- mKeyguardStatusViewController.isAnimatingScreenOffFromUnlocked() ? 1.0f
- : getExpandedFraction();
- float darkamount = mKeyguardStatusViewController.isAnimatingScreenOffFromUnlocked() ? 1.0f
- : mInterpolatedDarkAmount;
+ mUnlockedScreenOffAnimationController.isScreenOffAnimationPlaying()
+ ? 1.0f : getExpandedFraction();
+ float darkamount =
+ mUnlockedScreenOffAnimationController.isScreenOffAnimationPlaying()
+ ? 1.0f : mInterpolatedDarkAmount;
mClockPositionAlgorithm.setup(mStatusBarHeaderHeightKeyguard,
totalHeight - bottomPadding,
mNotificationStackScrollLayoutController.getIntrinsicContentHeight(),
@@ -4210,7 +4215,9 @@ public class NotificationPanelViewController extends PanelViewController {
int oldState = mBarState;
boolean keyguardShowing = statusBarState == KEYGUARD;
- if (mDozeParameters.shouldControlUnlockedScreenOff() && isDozing() && keyguardShowing) {
+ if (mUnlockedScreenOffAnimationController.shouldPlayScreenOffAnimation()
+ && oldState == StatusBarState.SHADE
+ && statusBarState == KEYGUARD) {
// This means we're doing the screen off animation - position the keyguard status
// view where it'll be on AOD, so we can animate it in.
mKeyguardStatusViewController.updatePosition(
@@ -4281,6 +4288,18 @@ public class NotificationPanelViewController extends PanelViewController {
}
/**
+ * Reconfigures the shade to show the AOD UI (clock, smartspace, etc). This is called by the
+ * screen off animation controller in order to animate in AOD without "actually" fully switching
+ * to the KEYGUARD state.
+ */
+ public void showAodUi() {
+ setDozing(true /* dozing */, false /* animate */, null);
+ mStatusBarStateListener.onStateChanged(KEYGUARD);
+ mStatusBarStateListener.onDozeAmountChanged(1f, 1f);
+ setExpandedFraction(1f);
+ }
+
+ /**
* Sets the overstretch amount in raw pixels when dragging down.
*/
public void setOverStrechAmount(float amount) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index b92f7c034b57..1331829201b8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -169,6 +169,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
private final KeyguardVisibilityCallback mKeyguardVisibilityCallback;
private final Handler mHandler;
private final Executor mMainExecutor;
+ private UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
private GradientColors mColors;
private boolean mNeedsDrawableColorUpdate;
@@ -224,7 +225,8 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
AlarmManager alarmManager, KeyguardStateController keyguardStateController,
DelayedWakeLock.Builder delayedWakeLockBuilder, Handler handler,
KeyguardUpdateMonitor keyguardUpdateMonitor, DockManager dockManager,
- ConfigurationController configurationController, @Main Executor mainExecutor) {
+ ConfigurationController configurationController, @Main Executor mainExecutor,
+ UnlockedScreenOffAnimationController unlockedScreenOffAnimationController) {
mScrimStateListener = lightBarController::setScrimState;
mDefaultScrimAlpha = BUSY_SCRIM_ALPHA;
ScrimState.BUBBLE_EXPANDED.setBubbleAlpha(BUBBLE_SCRIM_ALPHA);
@@ -235,6 +237,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
mKeyguardVisibilityCallback = new KeyguardVisibilityCallback();
mHandler = handler;
mMainExecutor = mainExecutor;
+ mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
mTimeTicker = new AlarmTimeout(alarmManager, this::onHideWallpaperTimeout,
"hide_aod_wallpaper", mHandler);
mWakeLock = delayedWakeLockBuilder.setHandler(mHandler).setTag("Scrims").build();
@@ -640,17 +643,20 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
}
if (mState == ScrimState.UNLOCKED) {
- // Darken scrim as you pull down the shade when unlocked
- float behindFraction = getInterpolatedFraction();
- behindFraction = (float) Math.pow(behindFraction, 0.8f);
- if (mClipsQsScrim) {
- mBehindAlpha = 1;
- mNotificationsAlpha = behindFraction * mDefaultScrimAlpha;
- } else {
- mBehindAlpha = behindFraction * mDefaultScrimAlpha;
- mNotificationsAlpha = mBehindAlpha;
+ // Darken scrim as you pull down the shade when unlocked, unless the shade is expanding
+ // because we're doing the screen off animation.
+ if (!mUnlockedScreenOffAnimationController.isScreenOffAnimationPlaying()) {
+ float behindFraction = getInterpolatedFraction();
+ behindFraction = (float) Math.pow(behindFraction, 0.8f);
+ if (mClipsQsScrim) {
+ mBehindAlpha = 1;
+ mNotificationsAlpha = behindFraction * mDefaultScrimAlpha;
+ } else {
+ mBehindAlpha = behindFraction * mDefaultScrimAlpha;
+ mNotificationsAlpha = mBehindAlpha;
+ }
+ mInFrontAlpha = 0;
}
- mInFrontAlpha = 0;
} else if (mState == ScrimState.BUBBLE_EXPANDED) {
// Darken scrim as you pull down the shade when unlocked
float behindFraction = getInterpolatedFraction();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
index 35dda4426849..e52e1fa5f39f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -189,9 +189,11 @@ public enum ScrimState {
mBubbleAlpha = ScrimController.TRANSPARENT;
mAnimationDuration = ScrimController.ANIMATION_DURATION_LONG;
- // DisplayPowerManager may blank the screen for us,
- // in this case we just need to set our state.
- mAnimateChange = mDozeParameters.shouldControlScreenOff();
+ // DisplayPowerManager may blank the screen for us, or we might blank it for ourselves
+ // by animating the screen off via the LightRevelScrim. In either case we just need to
+ // set our state.
+ mAnimateChange = mDozeParameters.shouldControlScreenOff()
+ && !mDozeParameters.shouldControlUnlockedScreenOff();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index c27497e43400..a490ee0bd250 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -465,6 +465,7 @@ public class StatusBar extends SystemUI implements DemoMode,
private final BrightnessSlider.Factory mBrightnessSliderFactory;
private final FeatureFlags mFeatureFlags;
private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
+ private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
private final List<ExpansionChangedListener> mExpansionChangedListeners;
@@ -803,7 +804,8 @@ public class StatusBar extends SystemUI implements DemoMode,
StatusBarLocationPublisher locationPublisher,
LockscreenShadeTransitionController lockscreenShadeTransitionController,
FeatureFlags featureFlags,
- KeyguardUnlockAnimationController keyguardUnlockAnimationController) {
+ KeyguardUnlockAnimationController keyguardUnlockAnimationController,
+ UnlockedScreenOffAnimationController unlockedScreenOffAnimationController) {
super(context);
mNotificationsController = notificationsController;
mLightBarController = lightBarController;
@@ -887,6 +889,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mStatusBarLocationPublisher = locationPublisher;
mFeatureFlags = featureFlags;
mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
+ mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
lockscreenShadeTransitionController.setStatusbar(this);
@@ -1241,6 +1244,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mScrimController.attachViews(scrimBehind, notificationsScrim, scrimInFront, scrimForBubble);
mLightRevealScrim = mNotificationShadeWindowView.findViewById(R.id.light_reveal_scrim);
+ mUnlockedScreenOffAnimationController.initialize(this, mLightRevealScrim);
updateLightRevealScrimVisibility();
mNotificationPanelViewController.initDependencies(
@@ -1471,7 +1475,9 @@ public class StatusBar extends SystemUI implements DemoMode,
* @param why the reason for the wake up
*/
public void wakeUpIfDozing(long time, View where, String why) {
- if (mDozing && !mKeyguardViewMediator.isAnimatingScreenOff()) {
+ if (mDozing && !(mKeyguardViewMediator.isAnimatingScreenOff()
+ || mUnlockedScreenOffAnimationController
+ .isScreenOffLightRevealAnimationPlaying())) {
mPowerManager.wakeUp(
time, PowerManager.WAKE_REASON_GESTURE, "com.android.systemui:" + why);
mWakeUpComingFromTouch = true;
@@ -3377,8 +3383,9 @@ public class StatusBar extends SystemUI implements DemoMode,
updatePanelExpansionForKeyguard();
}
if (shouldBeKeyguard) {
- if (isGoingToSleep()
- && mScreenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_TURNING_OFF) {
+ if (mUnlockedScreenOffAnimationController.isScreenOffAnimationPlaying()
+ || (isGoingToSleep()
+ && mScreenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_TURNING_OFF)) {
// Delay showing the keyguard until screen turned off.
} else {
showKeyguardImpl();
@@ -3549,6 +3556,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mNotificationPanelViewController.cancelAnimation();
mNotificationPanelViewController.setAlpha(1f);
mNotificationPanelViewController.resetViewGroupFade();
+ updateDozingState();
updateScrimController();
Trace.endSection();
return staying;
@@ -4011,6 +4019,13 @@ public class StatusBar extends SystemUI implements DemoMode,
mWakeUpCoordinator.setFullyAwake(false);
mBypassHeadsUpNotifier.setFullyAwake(false);
mKeyguardBypassController.onStartedGoingToSleep();
+
+ // The screen off animation uses our LightRevealScrim - we need to be expanded for it to
+ // be visible.
+ if (mUnlockedScreenOffAnimationController.shouldPlayScreenOffAnimation()) {
+ makeExpandedVisible(true);
+ }
+
DejankUtils.stopDetectingBlockingIpcs(tag);
}
@@ -4031,6 +4046,13 @@ public class StatusBar extends SystemUI implements DemoMode,
// once we fully woke up.
updateNotificationPanelTouchState();
mPulseExpansionHandler.onStartedWakingUp();
+
+ // If we are waking up during the screen off animation, we should undo making the
+ // expanded visible (we did that so the LightRevealScrim would be visible).
+ if (mUnlockedScreenOffAnimationController.isScreenOffLightRevealAnimationPlaying()) {
+ makeExpandedInvisible();
+ }
+
DejankUtils.stopDetectingBlockingIpcs(tag);
}
@@ -4403,8 +4425,9 @@ public class StatusBar extends SystemUI implements DemoMode,
}
public boolean shouldIgnoreTouch() {
- return mStatusBarStateController.isDozing()
- && mDozeServiceHost.getIgnoreTouchWhilePulsing();
+ return (mStatusBarStateController.isDozing()
+ && mDozeServiceHost.getIgnoreTouchWhilePulsing())
+ || mUnlockedScreenOffAnimationController.isScreenOffAnimationPlaying();
}
// Begin Extra BaseStatusBar methods.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
new file mode 100644
index 000000000000..e135cc51a7bc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
@@ -0,0 +1,178 @@
+package com.android.systemui.statusbar.phone
+
+import android.animation.Animator
+import android.animation.AnimatorListenerAdapter
+import android.animation.ValueAnimator
+import android.os.Handler
+import android.view.View
+import com.android.systemui.animation.Interpolators
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.KeyguardViewMediator
+import com.android.systemui.keyguard.WakefulnessLifecycle
+import com.android.systemui.statusbar.LightRevealScrim
+import com.android.systemui.statusbar.StatusBarState
+import com.android.systemui.statusbar.StatusBarStateControllerImpl
+import com.android.systemui.statusbar.notification.AnimatableProperty
+import com.android.systemui.statusbar.notification.PropertyAnimator
+import com.android.systemui.statusbar.notification.stack.AnimationProperties
+import com.android.systemui.statusbar.notification.stack.StackStateAnimator
+import javax.inject.Inject
+
+/**
+ * When to show the keyguard (AOD) view. This should be once the light reveal scrim is barely
+ * visible, because the transition to KEYGUARD causes brief jank.
+ */
+private const val ANIMATE_IN_KEYGUARD_DELAY = 600L
+
+/**
+ * Duration for the light reveal portion of the animation.
+ */
+private const val LIGHT_REVEAL_ANIMATION_DURATION = 750L
+
+/**
+ * Controller for the unlocked screen off animation, which runs when the device is going to sleep
+ * and we're unlocked.
+ *
+ * This animation uses a [LightRevealScrim] that lives in the status bar to hide the screen contents
+ * and then animates in the AOD UI.
+ */
+@SysUISingleton
+class UnlockedScreenOffAnimationController @Inject constructor(
+ private val wakefulnessLifecycle: WakefulnessLifecycle,
+ private val statusBarStateControllerImpl: StatusBarStateControllerImpl,
+ private val keyguardViewMediatorLazy: dagger.Lazy<KeyguardViewMediator>,
+ private val dozeParameters: DozeParameters
+) : WakefulnessLifecycle.Observer {
+ private val handler = Handler()
+
+ private lateinit var statusBar: StatusBar
+ private lateinit var lightRevealScrim: LightRevealScrim
+
+ private var lightRevealAnimationPlaying = false
+ private var aodUiAnimationPlaying = false
+
+ private val lightRevealAnimator = ValueAnimator.ofFloat(1f, 0f).apply {
+ duration = LIGHT_REVEAL_ANIMATION_DURATION
+ interpolator = Interpolators.FAST_OUT_SLOW_IN_REVERSE
+ addUpdateListener { lightRevealScrim.revealAmount = it.animatedValue as Float }
+ addListener(object : AnimatorListenerAdapter() {
+ override fun onAnimationCancel(animation: Animator?) {
+ lightRevealScrim.revealAmount = 1f
+ lightRevealAnimationPlaying = false
+ }
+
+ override fun onAnimationEnd(animation: Animator?) {
+ lightRevealAnimationPlaying = false
+ }
+ })
+ }
+
+ fun initialize(
+ statusBar: StatusBar,
+ lightRevealScrim: LightRevealScrim
+ ) {
+ this.lightRevealScrim = lightRevealScrim
+ this.statusBar = statusBar
+
+ wakefulnessLifecycle.addObserver(this)
+ }
+
+ /**
+ * Animates in the provided keyguard view, ending in the same position that it will be in on
+ * AOD.
+ */
+ fun animateInKeyguard(keyguardView: View, after: Runnable) {
+ keyguardView.alpha = 0f
+ keyguardView.visibility = View.VISIBLE
+
+ val currentY = keyguardView.y
+
+ // Move the keyguard up by 10% so we can animate it back down.
+ keyguardView.y = currentY - keyguardView.height * 0.1f
+
+ val duration = StackStateAnimator.ANIMATION_DURATION_WAKEUP
+
+ // We animate the Y properly separately using the PropertyAnimator, as the panel
+ // view also needs to update the end position.
+ PropertyAnimator.cancelAnimation(keyguardView, AnimatableProperty.Y)
+ PropertyAnimator.setProperty<View>(keyguardView, AnimatableProperty.Y, currentY,
+ AnimationProperties().setDuration(duration.toLong()),
+ true /* animate */)
+
+ keyguardView.animate()
+ .setDuration(duration.toLong())
+ .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+ .alpha(1f)
+ .withEndAction {
+ aodUiAnimationPlaying = false
+
+ // Lock the keyguard if it was waiting for the screen off animation to end.
+ keyguardViewMediatorLazy.get().maybeHandlePendingLock()
+
+ // Tell the StatusBar to become keyguard for real - we waited on that since it
+ // is slow and would have caused the animation to jank.
+ statusBar.updateIsKeyguard()
+
+ // Run the callback given to us by the KeyguardVisibilityHelper.
+ after.run()
+ }
+ .start()
+ }
+
+ override fun onStartedWakingUp() {
+ lightRevealAnimator.cancel()
+ handler.removeCallbacksAndMessages(null)
+ }
+
+ override fun onFinishedWakingUp() {
+ // Set this to false in onFinishedWakingUp rather than onStartedWakingUp so that other
+ // observers (such as StatusBar) can ask us whether we were playing the screen off animation
+ // and reset accordingly.
+ lightRevealAnimationPlaying = false
+ aodUiAnimationPlaying = false
+
+ // Make sure the status bar is in the correct keyguard state, since we might have left it in
+ // the KEYGUARD state if this wakeup cancelled the screen off animation.
+ statusBar.updateIsKeyguard()
+ }
+
+ override fun onStartedGoingToSleep() {
+ if (shouldPlayScreenOffAnimation()) {
+ lightRevealAnimationPlaying = true
+ lightRevealAnimator.start()
+
+ handler.postDelayed({
+ aodUiAnimationPlaying = true
+
+ // Show AOD. That'll cause the KeyguardVisibilityHelper to call #animateInKeyguard.
+ statusBar.notificationPanelViewController.showAodUi()
+ }, ANIMATE_IN_KEYGUARD_DELAY)
+ }
+ }
+
+ /**
+ * Whether we should play the screen off animation when the phone starts going to sleep. We can
+ * do that if dozeParameters says we can control the unlocked screen off animation and we are in
+ * the SHADE state. If we're in KEYGUARD or SHADE_LOCKED, the regular
+ */
+ fun shouldPlayScreenOffAnimation(): Boolean {
+ return dozeParameters.shouldControlUnlockedScreenOff() &&
+ statusBarStateControllerImpl.state == StatusBarState.SHADE
+ }
+
+ /**
+ * Whether we're doing the light reveal animation or we're done with that and animating in the
+ * AOD UI.
+ */
+ fun isScreenOffAnimationPlaying(): Boolean {
+ return lightRevealAnimationPlaying || aodUiAnimationPlaying
+ }
+
+ /**
+ * Whether the light reveal animation is playing. The second part of the screen off animation,
+ * where AOD animates in, might still be playing if this returns false.
+ */
+ fun isScreenOffLightRevealAnimationPlaying(): Boolean {
+ return lightRevealAnimationPlaying
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
index 9722d6841c62..2611ab5f7016 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
@@ -94,6 +94,7 @@ import com.android.systemui.statusbar.phone.StatusBarLocationPublisher;
import com.android.systemui.statusbar.phone.StatusBarNotificationActivityStarter;
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy;
import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager;
+import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -216,7 +217,8 @@ public interface StatusBarPhoneModule {
StatusBarLocationPublisher locationPublisher,
LockscreenShadeTransitionController transitionController,
FeatureFlags featureFlags,
- KeyguardUnlockAnimationController keyguardUnlockAnimationController) {
+ KeyguardUnlockAnimationController keyguardUnlockAnimationController,
+ UnlockedScreenOffAnimationController unlockedScreenOffAnimationController) {
return new StatusBar(
context,
notificationsController,
@@ -303,6 +305,7 @@ public interface StatusBarPhoneModule {
locationPublisher,
transitionController,
featureFlags,
- keyguardUnlockAnimationController);
+ keyguardUnlockAnimationController,
+ unlockedScreenOffAnimationController);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java
index 9d667805fade..2ecd4b3db5a1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java
@@ -45,6 +45,7 @@ import com.android.systemui.statusbar.notification.stack.AnimationProperties;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.NotificationPanelViewController;
+import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
import com.android.systemui.statusbar.phone.UserAvatarView;
import com.android.systemui.util.ViewController;
@@ -122,7 +123,8 @@ public class KeyguardQsUserSwitchController extends ViewController<UserAvatarVie
ConfigurationController configurationController,
SysuiStatusBarStateController statusBarStateController,
DozeParameters dozeParameters,
- Provider<UserDetailView.Adapter> userDetailViewAdapterProvider) {
+ Provider<UserDetailView.Adapter> userDetailViewAdapterProvider,
+ UnlockedScreenOffAnimationController unlockedScreenOffAnimationController) {
super(view);
if (DEBUG) Log.d(TAG, "New KeyguardQsUserSwitchController");
mContext = context;
@@ -135,7 +137,7 @@ public class KeyguardQsUserSwitchController extends ViewController<UserAvatarVie
mConfigurationController = configurationController;
mStatusBarStateController = statusBarStateController;
mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView,
- keyguardStateController, dozeParameters);
+ keyguardStateController, dozeParameters, unlockedScreenOffAnimationController);
mUserDetailAdapter = new KeyguardUserDetailAdapter(context, userDetailViewAdapterProvider);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java
index e2c52f9a3961..68f2a62a4fec 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java
@@ -51,6 +51,7 @@ import com.android.systemui.statusbar.notification.PropertyAnimator;
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
import com.android.systemui.util.ViewController;
import java.util.ArrayList;
@@ -159,7 +160,8 @@ public class KeyguardUserSwitcherController extends ViewController<KeyguardUserS
KeyguardStateController keyguardStateController,
SysuiStatusBarStateController statusBarStateController,
KeyguardUpdateMonitor keyguardUpdateMonitor,
- DozeParameters dozeParameters) {
+ DozeParameters dozeParameters,
+ UnlockedScreenOffAnimationController unlockedScreenOffAnimationController) {
super(keyguardUserSwitcherView);
if (DEBUG) Log.d(TAG, "New KeyguardUserSwitcherController");
mContext = context;
@@ -171,7 +173,7 @@ public class KeyguardUserSwitcherController extends ViewController<KeyguardUserS
mAdapter = new KeyguardUserAdapter(mContext, resources, layoutInflater,
mUserSwitcherController, this);
mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView,
- keyguardStateController, dozeParameters);
+ keyguardStateController, dozeParameters, unlockedScreenOffAnimationController);
mBackground = new KeyguardUserSwitcherScrim(context);
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
index f9b6d4467e3c..83c2227ffc12 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
@@ -25,6 +25,7 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.shared.system.smartspace.SmartspaceTransitionController;
import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -56,6 +57,8 @@ public class KeyguardStatusViewControllerTest extends SysuiTestCase {
KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
@Mock
SmartspaceTransitionController mSmartSpaceTransitionController;
+ @Mock
+ UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
private KeyguardStatusViewController mController;
@@ -72,7 +75,8 @@ public class KeyguardStatusViewControllerTest extends SysuiTestCase {
mConfigurationController,
mDozeParameters,
mKeyguardUnlockAnimationController,
- mSmartSpaceTransitionController);
+ mSmartSpaceTransitionController,
+ mUnlockedScreenOffAnimationController);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
index 6f03f5d975d0..e6f9aaf78080 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -49,6 +49,7 @@ import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.util.DeviceConfigProxyFake;
@@ -82,6 +83,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
private @Mock SysuiStatusBarStateController mStatusBarStateController;
private @Mock KeyguardStateController mKeyguardStateController;
private @Mock KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
+ private @Mock UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
private DeviceConfigProxy mDeviceConfig = new DeviceConfigProxyFake();
private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
@@ -101,7 +103,8 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
mDismissCallbackRegistry, mUpdateMonitor, mDumpManager, mUiBgExecutor,
mPowerManager, mTrustManager, mDeviceConfig, mNavigationModeController,
mKeyguardDisplayManager, mDozeParameters, mStatusBarStateController,
- mKeyguardStateController, () -> mKeyguardUnlockAnimationController);
+ mKeyguardStateController, () -> mKeyguardUnlockAnimationController,
+ mUnlockedScreenOffAnimationController);
mViewMediator.start();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
index ee8d1209a5cb..ffb53a8b2e11 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
@@ -160,6 +160,8 @@ public class NotificationPanelViewTest extends SysuiTestCase {
@Mock
private DozeParameters mDozeParameters;
@Mock
+ private UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
+ @Mock
private NotificationPanelView mView;
@Mock
private LayoutInflater mLayoutInflater;
@@ -328,7 +330,8 @@ public class NotificationPanelViewTest extends SysuiTestCase {
mock(HeadsUpManagerPhone.class),
new StatusBarStateControllerImpl(new UiEventLoggerFake()),
mKeyguardBypassController,
- mDozeParameters);
+ mDozeParameters,
+ mUnlockedScreenOffAnimationController);
PulseExpansionHandler expansionHandler = new PulseExpansionHandler(
mContext,
coordinator,
@@ -386,7 +389,8 @@ public class NotificationPanelViewTest extends SysuiTestCase {
mFragmentService,
mQuickAccessWalletController,
new FakeExecutor(new FakeSystemClock()),
- mSecureSettings);
+ mSecureSettings,
+ mUnlockedScreenOffAnimationController);
mNotificationPanelViewController.initDependencies(
mStatusBar,
mNotificationShelfController);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index 8b0b579bea54..075d1dd626e2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -108,6 +108,8 @@ public class ScrimControllerTest extends SysuiTestCase {
private DockManager mDockManager;
@Mock
private ConfigurationController mConfigurationController;
+ @Mock
+ private UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
private static class AnimatorListener implements Animator.AnimatorListener {
@@ -221,7 +223,8 @@ public class ScrimControllerTest extends SysuiTestCase {
mScrimController = new ScrimController(mLightBarController,
mDozeParameters, mAlarmManager, mKeyguardStateController, mDelayedWakeLockBuilder,
new FakeHandler(mLooper.getLooper()), mKeyguardUpdateMonitor,
- mDockManager, mConfigurationController, new FakeExecutor(new FakeSystemClock()));
+ mDockManager, mConfigurationController, new FakeExecutor(new FakeSystemClock()),
+ mUnlockedScreenOffAnimationController);
mScrimController.setScrimVisibleListener(visible -> mScrimVisibility = visible);
mScrimController.attachViews(mScrimBehind, mNotificationsScrim, mScrimInFront,
mScrimForBubble);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 5a3683e8e3f4..deff2043f6dc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -272,6 +272,7 @@ public class StatusBarTest extends SysuiTestCase {
@Mock private FeatureFlags mFeatureFlags;
@Mock private IWallpaperManager mWallpaperManager;
@Mock private KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
+ @Mock private UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
private ShadeController mShadeController;
private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
private InitController mInitController = new InitController();
@@ -441,7 +442,8 @@ public class StatusBarTest extends SysuiTestCase {
mLocationPublisher,
mLockscreenTransitionController,
mFeatureFlags,
- mKeyguardUnlockAnimationController);
+ mKeyguardUnlockAnimationController,
+ mUnlockedScreenOffAnimationController);
when(mKeyguardViewMediator.registerStatusBar(any(StatusBar.class), any(ViewGroup.class),
any(NotificationPanelViewController.class), any(BiometricUnlockController.class),
any(ViewGroup.class), any(KeyguardBypassController.class)))
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 9c25159faef1..ae8f967ade64 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -436,6 +436,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
volatile boolean mPowerKeyHandled;
volatile boolean mBackKeyHandled;
volatile boolean mEndCallKeyHandled;
+ volatile boolean mCameraGestureTriggered;
volatile boolean mCameraGestureTriggeredDuringGoingToSleep;
/**
@@ -3833,6 +3834,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
final MutableBoolean outLaunched = new MutableBoolean(false);
final boolean gesturedServiceIntercepted = gestureService.interceptPowerKeyDown(event,
interactive, outLaunched);
+ if (outLaunched.value) {
+ mCameraGestureTriggered = true;
+ }
if (outLaunched.value && mRequestedOrSleepingDefaultDisplay) {
mCameraGestureTriggeredDuringGoingToSleep = true;
}
@@ -4209,13 +4213,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mDefaultDisplayRotation.updateOrientationListener();
if (mKeyguardDelegate != null) {
- mKeyguardDelegate.onFinishedGoingToSleep(pmSleepReason,
- mCameraGestureTriggeredDuringGoingToSleep);
+ mKeyguardDelegate.onFinishedGoingToSleep(pmSleepReason, mCameraGestureTriggered);
}
if (mDisplayFoldController != null) {
mDisplayFoldController.finishedGoingToSleep();
}
mCameraGestureTriggeredDuringGoingToSleep = false;
+ mCameraGestureTriggered = false;
}
// Called on the PowerManager's Notifier thread.
@@ -4242,8 +4246,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mDefaultDisplayRotation.updateOrientationListener();
if (mKeyguardDelegate != null) {
- mKeyguardDelegate.onStartedWakingUp(pmWakeReason);
+ mKeyguardDelegate.onStartedWakingUp(pmWakeReason, mCameraGestureTriggered);
}
+
+ mCameraGestureTriggered = false;
}
// Called on the PowerManager's Notifier thread.
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
index 44f14b4d5b0d..cdce660835b6 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
@@ -178,7 +178,8 @@ public class KeyguardServiceDelegate {
// This is used to hide the scrim once keyguard displays.
if (mKeyguardState.interactiveState == INTERACTIVE_STATE_AWAKE
|| mKeyguardState.interactiveState == INTERACTIVE_STATE_WAKING) {
- mKeyguardService.onStartedWakingUp(PowerManager.WAKE_REASON_UNKNOWN);
+ mKeyguardService.onStartedWakingUp(PowerManager.WAKE_REASON_UNKNOWN,
+ false /* cameraGestureTriggered */);
}
if (mKeyguardState.interactiveState == INTERACTIVE_STATE_AWAKE) {
mKeyguardService.onFinishedWakingUp();
@@ -297,10 +298,11 @@ public class KeyguardServiceDelegate {
mKeyguardState.dreaming = false;
}
- public void onStartedWakingUp(@PowerManager.WakeReason int pmWakeReason) {
+ public void onStartedWakingUp(
+ @PowerManager.WakeReason int pmWakeReason, boolean cameraGestureTriggered) {
if (mKeyguardService != null) {
if (DEBUG) Log.v(TAG, "onStartedWakingUp()");
- mKeyguardService.onStartedWakingUp(pmWakeReason);
+ mKeyguardService.onStartedWakingUp(pmWakeReason, cameraGestureTriggered);
}
mKeyguardState.interactiveState = INTERACTIVE_STATE_WAKING;
}
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
index 0872b3a5fd42..855a1ccc172d 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
@@ -121,9 +121,10 @@ public class KeyguardServiceWrapper implements IKeyguardService {
}
@Override
- public void onStartedWakingUp(@PowerManager.WakeReason int pmWakeReason) {
+ public void onStartedWakingUp(
+ @PowerManager.WakeReason int pmWakeReason, boolean cameraGestureTriggered) {
try {
- mService.onStartedWakingUp(pmWakeReason);
+ mService.onStartedWakingUp(pmWakeReason, cameraGestureTriggered);
} catch (RemoteException e) {
Slog.w(TAG , "Remote Exception", e);
}