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/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;
+    }
 }