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
diff --git a/core/java/com/android/internal/policy/IKeyguardService.aidl b/core/java/com/android/internal/policy/IKeyguardService.aidl
index b01e4a8..76aa7a0 100644
--- a/core/java/com/android/internal/policy/IKeyguardService.aidl
+++ b/core/java/com/android/internal/policy/IKeyguardService.aidl
@@ -63,8 +63,10 @@
* @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 7cb4846..92af58e 100644
--- a/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java
@@ -107,6 +107,21 @@
}
};
+ 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 @@
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 @@
@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 @@
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 7b6514a..89ca507 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.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 @@
ConfigurationController configurationController,
DozeParameters dozeParameters,
KeyguardUnlockAnimationController keyguardUnlockAnimationController,
- SmartspaceTransitionController smartspaceTransitionController) {
+ SmartspaceTransitionController smartspaceTransitionController,
+ UnlockedScreenOffAnimationController unlockedScreenOffAnimationController) {
super(keyguardStatusView);
mKeyguardSliceViewController = keyguardSliceViewController;
mKeyguardClockSwitchController = keyguardClockSwitchController;
@@ -75,7 +77,7 @@
mDozeParameters = dozeParameters;
mKeyguardStateController = keyguardStateController;
mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, keyguardStateController,
- dozeParameters);
+ dozeParameters, unlockedScreenOffAnimationController);
mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
mSmartspaceTransitionController = smartspaceTransitionController;
@@ -238,13 +240,6 @@
}
/**
- * @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 b6a58dc..7edecc8 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.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 @@
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 @@
.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 @@
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 666afed..0091343 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 @@
}
@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 36a0acc..30d1525 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.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 @@
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 @@
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 @@
DozeParameters dozeParameters,
SysuiStatusBarStateController statusBarStateController,
KeyguardStateController keyguardStateController,
- Lazy<KeyguardUnlockAnimationController> keyguardUnlockAnimationControllerLazy) {
+ Lazy<KeyguardUnlockAnimationController> keyguardUnlockAnimationControllerLazy,
+ UnlockedScreenOffAnimationController unlockedScreenOffAnimationController) {
super(context);
mFalsingCollector = falsingCollector;
mLockPatternUtils = lockPatternUtils;
@@ -815,6 +832,7 @@
mKeyguardStateController = keyguardStateController;
mKeyguardUnlockAnimationControllerLazy = keyguardUnlockAnimationControllerLazy;
+ mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
}
public void userActivity() {
@@ -934,6 +952,7 @@
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 @@
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 @@
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 @@
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 @@
/**
* 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 @@
mHiding = false;
mWakeAndUnlocking = false;
+ mPendingLock = false;
setShowingLocked(true);
mKeyguardViewControllerLazy.get().show(options);
resetKeyguardDonePendingLocked();
@@ -2577,7 +2610,12 @@
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 @@
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 119e9c4..b071b943 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.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 @@
DozeParameters dozeParameters,
SysuiStatusBarStateController statusBarStateController,
KeyguardStateController keyguardStateController,
- Lazy<KeyguardUnlockAnimationController> keyguardUnlockAnimationController) {
+ Lazy<KeyguardUnlockAnimationController> keyguardUnlockAnimationController,
+ UnlockedScreenOffAnimationController unlockedScreenOffAnimationController) {
return new KeyguardViewMediator(
context,
falsingCollector,
@@ -116,7 +118,8 @@
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 7afb015..84728f6 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.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 @@
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 @@
}
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 efcde46..56b1a8e 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 @@
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 @@
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 @@
mConversationNotificationManager = conversationNotificationManager;
mAuthController = authController;
mLockIconViewController = lockIconViewController;
+ mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
mView.setBackgroundColor(Color.TRANSPARENT);
OnAttachStateChangeListener onAttachStateChangeListener = new OnAttachStateChangeListener();
@@ -1241,10 +1245,11 @@
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 @@
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 @@
}
/**
+ * 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 b92f7c0..1331829 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 @@
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 @@
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 @@
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 @@
}
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 35dda44..e52e1fa 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 @@
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 c27497e..a490ee0 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 @@
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 @@
StatusBarLocationPublisher locationPublisher,
LockscreenShadeTransitionController lockscreenShadeTransitionController,
FeatureFlags featureFlags,
- KeyguardUnlockAnimationController keyguardUnlockAnimationController) {
+ KeyguardUnlockAnimationController keyguardUnlockAnimationController,
+ UnlockedScreenOffAnimationController unlockedScreenOffAnimationController) {
super(context);
mNotificationsController = notificationsController;
mLightBarController = lightBarController;
@@ -887,6 +889,7 @@
mStatusBarLocationPublisher = locationPublisher;
mFeatureFlags = featureFlags;
mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
+ mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
lockscreenShadeTransitionController.setStatusbar(this);
@@ -1241,6 +1244,7 @@
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 @@
* @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 @@
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 @@
mNotificationPanelViewController.cancelAnimation();
mNotificationPanelViewController.setAlpha(1f);
mNotificationPanelViewController.resetViewGroupFade();
+ updateDozingState();
updateScrimController();
Trace.endSection();
return staying;
@@ -4011,6 +4019,13 @@
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 @@
// 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 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 0000000..e135cc5
--- /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 9722d68..2611ab5 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.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 @@
StatusBarLocationPublisher locationPublisher,
LockscreenShadeTransitionController transitionController,
FeatureFlags featureFlags,
- KeyguardUnlockAnimationController keyguardUnlockAnimationController) {
+ KeyguardUnlockAnimationController keyguardUnlockAnimationController,
+ UnlockedScreenOffAnimationController unlockedScreenOffAnimationController) {
return new StatusBar(
context,
notificationsController,
@@ -303,6 +305,7 @@
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 9d667805f..2ecd4b3 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.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 @@
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 @@
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 e2c52f9..68f2a62 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.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 @@
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 @@
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 f9b6d44..83c2227 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.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 @@
KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
@Mock
SmartspaceTransitionController mSmartSpaceTransitionController;
+ @Mock
+ UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
private KeyguardStatusViewController mController;
@@ -72,7 +75,8 @@
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 6f03f5d..e6f9aaf 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.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 @@
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 @@
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 ee8d120..ffb53a8 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 @@
@Mock
private DozeParameters mDozeParameters;
@Mock
+ private UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
+ @Mock
private NotificationPanelView mView;
@Mock
private LayoutInflater mLayoutInflater;
@@ -328,7 +330,8 @@
mock(HeadsUpManagerPhone.class),
new StatusBarStateControllerImpl(new UiEventLoggerFake()),
mKeyguardBypassController,
- mDozeParameters);
+ mDozeParameters,
+ mUnlockedScreenOffAnimationController);
PulseExpansionHandler expansionHandler = new PulseExpansionHandler(
mContext,
coordinator,
@@ -386,7 +389,8 @@
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 8b0b579..075d1dd 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 @@
private DockManager mDockManager;
@Mock
private ConfigurationController mConfigurationController;
+ @Mock
+ private UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
private static class AnimatorListener implements Animator.AnimatorListener {
@@ -221,7 +223,8 @@
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 5a3683e..deff204 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 @@
@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 @@
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 9c25159..ae8f967 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 @@
volatile boolean mPowerKeyHandled;
volatile boolean mBackKeyHandled;
volatile boolean mEndCallKeyHandled;
+ volatile boolean mCameraGestureTriggered;
volatile boolean mCameraGestureTriggeredDuringGoingToSleep;
/**
@@ -3833,6 +3834,9 @@
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 @@
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 @@
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 44f14b4..cdce660 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 @@
// 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 @@
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 0872b3a..855a1cc 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 @@
}
@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);
}