Support for passive interrupts
Bug: 111414690
Test: manual, lift, swipe down, go to shade locked
Test: adb shell setprop persist.sysui.expand_shade_on_wake_up 0
Test: adb shell setprop persist.sysui.go_to_shade_on_wake_up 0
Change-Id: I59018a72b85cfcf75344d83bbf9e3a122a66c018
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
index bb05980..1e61a77 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
@@ -47,6 +47,12 @@
void onIgnoreTouchWhilePulsing(boolean ignore);
+ /**
+ * If the device was waken up by a passive interrupt that will show the lock screen without
+ * expanding the notification panel/shade.
+ */
+ void setPassiveInterrupt(boolean lightInterrupt);
+
interface Callback {
/**
* Called when a high priority notification is added.
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index cb91d78..d69b1bf 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -142,6 +142,7 @@
mDozeHost.onDoubleTap(screenX, screenY);
mMachine.wakeUp();
} else if (isPickup || isWakeLockScreen) {
+ mDozeHost.setPassiveInterrupt(true);
mMachine.wakeUp();
} else {
mDozeHost.extendPulse();
@@ -210,6 +211,7 @@
case INITIALIZED:
mBroadcastReceiver.register(mContext);
mDozeHost.addCallback(mHostCallback);
+ mDozeHost.setPassiveInterrupt(false);
checkTriggersAtInit();
break;
case DOZE:
@@ -219,6 +221,7 @@
mDozeSensors.reregisterAllSensors();
}
mDozeSensors.setListening(true);
+ mDozeHost.setPassiveInterrupt(false);
break;
case DOZE_AOD_PAUSED:
case DOZE_AOD_PAUSING:
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
index 30d9ef7..8526afd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
@@ -131,7 +131,7 @@
if (!isFalseTouch() && mDragDownCallback.onDraggedDown(mStartingChild,
(int) (y - mInitialTouchY))) {
if (mStartingChild == null) {
- mDragDownCallback.setEmptyDragAmount(0f);
+ cancelExpansion();
} else {
mCallback.setUserLockedChild(mStartingChild, false);
mStartingChild = null;
@@ -206,11 +206,8 @@
ValueAnimator anim = ValueAnimator.ofFloat(mLastHeight, 0);
anim.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
anim.setDuration(SPRING_BACK_ANIMATION_LENGTH_MS);
- anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- mDragDownCallback.setEmptyDragAmount((Float) animation.getAnimatedValue());
- }
+ anim.addUpdateListener(animation -> {
+ mDragDownCallback.setEmptyDragAmount((Float) animation.getAnimatedValue());
});
anim.start();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 7fa0426..1495abf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -793,7 +793,7 @@
private void setOpenedAmount(float openedAmount) {
mNoAnimationsInThisFrame = openedAmount == 1.0f && mOpenedAmount == 0.0f;
mOpenedAmount = openedAmount;
- if (!mAmbientState.isPanelFullWidth()) {
+ if (!mAmbientState.isPanelFullWidth() || mAmbientState.isDark()) {
// We don't do a transformation at all, lets just assume we are fully opened
openedAmount = 1.0f;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 0bc54a3..659f6c7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -5654,19 +5654,21 @@
@Override
public boolean onDraggedDown(View startingChild, int dragLengthY) {
if (mStatusBarState == StatusBarState.KEYGUARD
- && hasActiveNotifications() && (!mStatusBar.isDozing()
- || mStatusBar.isPulsing())) {
+ && hasActiveNotifications()) {
mLockscreenGestureLogger.write(
MetricsEvent.ACTION_LS_SHADE,
(int) (dragLengthY / mDisplayMetrics.density),
0 /* velocityDp - N/A */);
- // We have notifications, go to locked shade.
- mStatusBar.goToLockedShade(startingChild);
- if (startingChild instanceof ExpandableNotificationRow) {
- ExpandableNotificationRow row = (ExpandableNotificationRow) startingChild;
- row.onExpandedByGesture(true /* drag down is always an open */);
+ if (mNotificationPanel.onDraggedDown() || startingChild != null) {
+ // We have notifications, go to locked shade.
+ mStatusBar.goToLockedShade(startingChild);
+ if (startingChild instanceof ExpandableNotificationRow) {
+ ExpandableNotificationRow row = (ExpandableNotificationRow) startingChild;
+ row.onExpandedByGesture(true /* drag down is always an open */);
+ }
}
+
return true;
} else {
// abort gesture.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
index 33bc164..836a55f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
@@ -108,11 +108,7 @@
* Dozing and receiving a notification (AOD notification.)
*/
private boolean mPulsing;
-
- /**
- * Distance in pixels between the top of the screen and the first view of the bouncer.
- */
- private int mBouncerTop;
+ private float mEmptyDragAmount;
/**
* Refreshes the dimension values.
@@ -131,9 +127,8 @@
}
public void setup(int minTopMargin, int maxShadeBottom, int notificationStackHeight,
- float panelExpansion, int parentHeight,
- int keyguardStatusHeight, float dark, boolean secure, boolean pulsing,
- int bouncerTop) {
+ float panelExpansion, int parentHeight, int keyguardStatusHeight, float dark,
+ boolean secure, boolean pulsing, float emptyDragAmount) {
mMinTopMargin = minTopMargin + mContainerTopPadding;
mMaxShadeBottom = maxShadeBottom;
mNotificationStackHeight = notificationStackHeight;
@@ -143,7 +138,7 @@
mDarkAmount = dark;
mCurrentlySecure = secure;
mPulsing = pulsing;
- mBouncerTop = bouncerTop;
+ mEmptyDragAmount = emptyDragAmount;
}
public void run(Result result) {
@@ -194,15 +189,14 @@
}
float clockYRegular = getExpandedClockPosition();
- boolean hasEnoughSpace = mMinTopMargin + mKeyguardStatusHeight < mBouncerTop;
- float clockYTarget = mCurrentlySecure && hasEnoughSpace ?
- mMinTopMargin : -mKeyguardStatusHeight;
+ float clockYBouncer = -mKeyguardStatusHeight;
// Move clock up while collapsing the shade
float shadeExpansion = Interpolators.FAST_OUT_LINEAR_IN.getInterpolation(mPanelExpansion);
- final float clockY = MathUtils.lerp(clockYTarget, clockYRegular, shadeExpansion);
+ float clockY = MathUtils.lerp(clockYBouncer, clockYRegular, shadeExpansion);
+ clockYDark = MathUtils.lerp(clockYBouncer, clockYDark, shadeExpansion);
- return (int) MathUtils.lerp(clockY, clockYDark, mDarkAmount);
+ return (int) (MathUtils.lerp(clockY, clockYDark, mDarkAmount) + mEmptyDragAmount);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 7507702..e31bad65 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -38,6 +38,7 @@
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.os.PowerManager;
+import android.os.SystemProperties;
import android.util.AttributeSet;
import android.util.FloatProperty;
import android.util.Log;
@@ -104,6 +105,11 @@
private static final boolean DEBUG = false;
+ private static final boolean EXPAND_ON_WAKE_UP = SystemProperties.getBoolean(
+ "persist.sysui.expand_shade_on_wake_up", true);
+ private static final boolean WAKE_UP_TO_SHADE = SystemProperties.getBoolean(
+ "persist.sysui.go_to_shade_on_wake_up", true);
+
/**
* Fling expanding QS.
*/
@@ -280,6 +286,12 @@
*/
private float mLinearDarkAmount;
+ /**
+ * State where the device isn't dozing anymore, but the lock screen isn't fully awake.
+ * The screen will be dimmed down with the shade collapsed.
+ */
+ private boolean mSemiAwake;
+
private float mDarkAmountTarget;
private boolean mPulsing;
private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
@@ -573,7 +585,7 @@
mInterpolatedDarkAmount,
mStatusBar.isKeyguardCurrentlySecure(),
mPulsing,
- mBouncerTop);
+ mEmptyDragAmount);
mClockPositionAlgorithm.run(mClockPositionResult);
PropertyAnimator.setProperty(mKeyguardStatusView, AnimatableProperty.X,
mClockPositionResult.clockX, CLOCK_ANIMATION_PROPERTIES, animateClock);
@@ -1235,6 +1247,12 @@
if (keyguardShowing) {
updateDozingVisibilities(false /* animate */);
}
+
+ // Expand notification shade if the device was is semi-awake state
+ if (mBarState == StatusBarState.SHADE && isSemiAwake()) {
+ mNotificationStackScroller.setDark(false /* dark */, false /* animated */,
+ null /* touchLocation */);
+ }
resetVerticalPanelPosition();
updateQsState();
}
@@ -2335,13 +2353,7 @@
}
public void setEmptyDragAmount(float amount) {
- float factor = 0.8f;
- if (mNotificationStackScroller.getNotGoneChildCount() > 0) {
- factor = 0.4f;
- } else if (!mStatusBar.hasActiveNotifications()) {
- factor = 0.4f;
- }
- mEmptyDragAmount = amount * factor;
+ mEmptyDragAmount = amount * 0.2f;
positionClockAndNotifications();
}
@@ -2769,11 +2781,14 @@
mNotificationStackScroller.setAnimationsEnabled(!disabled);
}
- public void setDozing(boolean dozing, boolean animate,
- PointF wakeUpTouchLocation) {
- mNotificationStackScroller.setDark(mDozing, animate, wakeUpTouchLocation);
+ public void setDozing(boolean dozing, boolean animate, PointF wakeUpTouchLocation,
+ boolean passiveInterrupted) {
if (dozing == mDozing) return;
mDozing = dozing;
+ mSemiAwake = !EXPAND_ON_WAKE_UP && !mDozing && passiveInterrupted;
+ if (!mSemiAwake) {
+ mNotificationStackScroller.setDark(mDozing, animate, wakeUpTouchLocation);
+ }
if (mBarState == StatusBarState.KEYGUARD
|| mBarState == StatusBarState.SHADE_LOCKED) {
@@ -2787,24 +2802,38 @@
} else {
mDarkAnimator.cancel();
}
+ if (mSemiAwake) {
+ setDarkAmount(0, 0);
+ }
}
mDarkAmountTarget = darkAmount;
- if (animate) {
- if (mInterpolatedDarkAmount == 0f || mInterpolatedDarkAmount == 1f) {
- mDarkInterpolator = dozing
- ? Interpolators.FAST_OUT_SLOW_IN
- : Interpolators.TOUCH_RESPONSE_REVERSE;
+ if (!mSemiAwake) {
+ if (animate) {
+ startDarkAnimation();
+ } else {
+ setDarkAmount(darkAmount, darkAmount);
}
- mNotificationStackScroller.notifyDarkAnimationStart(dozing);
- mDarkAnimator = ObjectAnimator.ofFloat(this, SET_DARK_AMOUNT_PROPERTY, darkAmount);
- mDarkAnimator.setInterpolator(Interpolators.LINEAR);
- mDarkAnimator.setDuration(mNotificationStackScroller.getDarkAnimationDuration(dozing));
- mDarkAnimator.start();
- } else {
- setDarkAmount(darkAmount, darkAmount);
}
}
+ public boolean isSemiAwake() {
+ return mSemiAwake;
+ }
+
+ private void startDarkAnimation() {
+ if (mInterpolatedDarkAmount == 0f || mInterpolatedDarkAmount == 1f) {
+ mDarkInterpolator = mDozing
+ ? Interpolators.FAST_OUT_SLOW_IN
+ : Interpolators.TOUCH_RESPONSE_REVERSE;
+ }
+ mNotificationStackScroller.notifyDarkAnimationStart(mDozing);
+ mDarkAnimator = ObjectAnimator.ofFloat(this, SET_DARK_AMOUNT_PROPERTY, mDozing ? 1 : 0);
+ mDarkAnimator.setInterpolator(Interpolators.LINEAR);
+ mDarkAnimator.setDuration(
+ mNotificationStackScroller.getDarkAnimationDuration(mDozing));
+ mDarkAnimator.start();
+ }
+
private void setDarkAmount(float linearAmount, float amount) {
mInterpolatedDarkAmount = amount;
mLinearDarkAmount = linearAmount;
@@ -2989,4 +3018,22 @@
mNotificationStackScroller.setScrimController(scrimController);
updateShowEmptyShadeView();
}
+
+ /**
+ * Whenever a user drags down on the empty area (pulling down the shade and clock) and lets go.
+ *
+ * @return {@code true} if dragging down should take the user to SHADE_LOCKED.
+ */
+ public boolean onDraggedDown() {
+ if (isSemiAwake()) {
+ mSemiAwake = false;
+ mNotificationStackScroller.setDark(false /* dark */, true /* animate */,
+ null /* touchLocation */);
+ startDarkAnimation();
+ mStatusBar.updateScrimController();
+
+ return WAKE_UP_TO_SHADE;
+ }
+ return true;
+ }
}
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 e3a7b75..1bed26d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -63,7 +63,7 @@
public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnColorsChangedListener,
Dumpable {
- private static final String TAG = "ScrimController";
+ static final String TAG = "ScrimController";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
/**
@@ -96,6 +96,11 @@
*/
public static final float GRADIENT_SCRIM_ALPHA_BUSY = 0.70f;
/**
+ * A scrim varies its opacity based on a busyness factor, for example
+ * how many notifications are currently visible.
+ */
+ public static final float GRADIENT_SCRIM_DARK_KEYGUARD = 0.80f;
+ /**
* The most common scrim, the one under the keyguard.
*/
protected static final float SCRIM_BEHIND_ALPHA_KEYGUARD = GRADIENT_SCRIM_ALPHA;
@@ -361,7 +366,7 @@
mExpansionFraction = fraction;
final boolean keyguardOrUnlocked = mState == ScrimState.UNLOCKED
- || mState == ScrimState.KEYGUARD;
+ || mState == ScrimState.KEYGUARD || mState == ScrimState.DARK_KEYGUARD;
if (!keyguardOrUnlocked || !mExpansionAffectsAlpha) {
return;
}
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 085f7b6..ade063d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -49,6 +49,8 @@
// fade it out afterwards.
mBlankScreen = true;
}
+ } else if (previousState == ScrimState.KEYGUARD) {
+ mAnimationDuration = StackStateAnimator.ANIMATION_DURATION_WAKEUP;
} else {
mAnimationDuration = ScrimController.ANIMATION_DURATION;
}
@@ -59,8 +61,24 @@
@Override
public float getBehindAlpha(float busynessFactor) {
return MathUtils.map(0 /* start */, 1 /* stop */,
- mScrimBehindAlphaKeyguard, ScrimController.GRADIENT_SCRIM_ALPHA_BUSY,
- busynessFactor);
+ mScrimBehindAlphaKeyguard, ScrimController.GRADIENT_SCRIM_ALPHA_BUSY,
+ busynessFactor);
+ }
+ },
+
+ /**
+ * On semi-awake lock screen.
+ */
+ DARK_KEYGUARD(7) {
+
+ @Override
+ public void prepare(ScrimState previousState) {
+ mBlankScreen = mDisplayRequiresBlanking && previousState != ScrimState.AOD;
+ mAnimationDuration = StackStateAnimator.ANIMATION_DURATION_WAKEUP;
+ mCurrentBehindAlpha = ScrimController.GRADIENT_SCRIM_DARK_KEYGUARD;
+ mCurrentInFrontAlpha = 0;
+ mCurrentInFrontTint = Color.BLACK;
+ mCurrentBehindTint = Color.BLACK;
}
},
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 cc9adb8..56e5a1e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -3617,7 +3617,8 @@
mDozeScrimController.setDozing(mDozing);
mKeyguardIndicationController.setDozing(mDozing);
- mNotificationPanel.setDozing(mDozing, animate, mWakeUpTouchLocation);
+ mNotificationPanel.setDozing(mDozing, animate, mWakeUpTouchLocation,
+ mDozeServiceHost.wasPassivelyInterrupted());
mNotificationLogger.setDozing(mDozing);
mGroupManager.setDozing(mDozing);
updateQsExpansionEnabled();
@@ -4203,7 +4204,6 @@
mAmbientPulseManager.releaseAllImmediately();
mVisualStabilityManager.setScreenOn(true);
mNotificationPanel.setTouchAndAnimationDisabled(false);
- mDozeServiceHost.stopDozing();
updateVisibleToUser();
updateIsKeyguard();
updateScrimController();
@@ -4401,6 +4401,9 @@
// FLAG_DISMISS_KEYGUARD_ACTIVITY.
ScrimState state = mStatusBarKeyguardViewManager.bouncerNeedsScrimming()
? ScrimState.BOUNCER_SCRIMMED : ScrimState.BOUNCER;
+ if (mNotificationPanel.isSemiAwake()) {
+ state = ScrimState.DARK_KEYGUARD;
+ }
mScrimController.transitionTo(state);
} else if (isInLaunchTransition() || mLaunchCameraOnScreenTurningOn
|| launchingAffordanceWithPreview) {
@@ -4412,7 +4415,8 @@
} else if (mDozing) {
mScrimController.transitionTo(ScrimState.AOD);
} else if (mIsKeyguard && !wakeAndUnlocking) {
- mScrimController.transitionTo(ScrimState.KEYGUARD);
+ mScrimController.transitionTo(mNotificationPanel.isSemiAwake()
+ ? ScrimState.DARK_KEYGUARD : ScrimState.KEYGUARD);
} else {
mScrimController.transitionTo(ScrimState.UNLOCKED, mUnlockScrimCallback);
}
@@ -4432,6 +4436,7 @@
private boolean mAnimateWakeup;
private boolean mAnimateScreenOff;
private boolean mIgnoreTouchWhilePulsing;
+ private boolean mPassivelyInterrupted;
@Override
public String toString() {
@@ -4515,6 +4520,11 @@
}
@Override
+ public void setPassiveInterrupt(boolean passiveInterrupt) {
+ mPassivelyInterrupted = passiveInterrupt;
+ }
+
+ @Override
public void onIgnoreTouchWhilePulsing(boolean ignore) {
if (ignore != mIgnoreTouchWhilePulsing) {
DozeLog.tracePulseTouchDisabledByProx(mContext, ignore);
@@ -4633,6 +4643,10 @@
public boolean shouldAnimateScreenOff() {
return mAnimateScreenOff;
}
+
+ public boolean wasPassivelyInterrupted() {
+ return mPassivelyInterrupted;
+ }
}
public boolean shouldIgnoreTouch() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java
index 2398fd3..6abd407 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java
@@ -115,6 +115,11 @@
}
@Override
+ public void setPassiveInterrupt(boolean lightInterrupt) {
+
+ }
+
+ @Override
public void setDozeScreenBrightness(int value) {
}