Doze: Wake up on touch, fade between states.

- When dozing, the first motion event triggers a wake up.
- Fade the backgrounds to ease the transition out of doze.

Bug:17167296
Change-Id: I5615ca0839dfa3ed2cf3001baf407c707f0676d5
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 0499b14..9585e17 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -23,6 +23,8 @@
 import android.animation.ValueAnimator;
 import android.content.Context;
 import android.content.res.Configuration;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
 import android.util.AttributeSet;
 import android.util.MathUtils;
 import android.view.MotionEvent;
@@ -60,6 +62,10 @@
     private static final float HEADER_RUBBERBAND_FACTOR = 2.05f;
     private static final float LOCK_ICON_ACTIVE_SCALE = 1.2f;
 
+    private static final int DOZE_BACKGROUND_COLOR = 0xff000000;
+    private static final int TAG_KEY_ANIM = R.id.scrim;
+    private static final long DOZE_BACKGROUND_ANIM_DURATION = ScrimController.ANIMATION_DURATION;
+
     private KeyguardAffordanceHelper mAfforanceHelper;
     private StatusBarHeaderView mHeader;
     private KeyguardUserSwitcher mKeyguardUserSwitcher;
@@ -1724,13 +1730,58 @@
         if (dozing == mDozing) return;
         mDozing = dozing;
         if (mDozing) {
-            setBackgroundColor(0xff000000);
+            setBackgroundColorAlpha(this, DOZE_BACKGROUND_COLOR, 0xff, false /*animate*/);
         } else {
-            setBackground(null);
+            setBackgroundColorAlpha(this, DOZE_BACKGROUND_COLOR, 0, true /*animate*/);
         }
         updateKeyguardStatusBarVisibility();
     }
 
+    private static void setBackgroundColorAlpha(final View target, int rgb, int targetAlpha,
+            boolean animate) {
+        int currentAlpha = getBackgroundAlpha(target);
+        if (currentAlpha == targetAlpha) {
+            return;
+        }
+        final int r = Color.red(rgb);
+        final int g = Color.green(rgb);
+        final int b = Color.blue(rgb);
+        Object runningAnim = target.getTag(TAG_KEY_ANIM);
+        if (runningAnim instanceof ValueAnimator) {
+            ((ValueAnimator) runningAnim).cancel();
+        }
+        if (!animate) {
+            target.setBackgroundColor(Color.argb(targetAlpha, r, g, b));
+            return;
+        }
+        ValueAnimator anim = ValueAnimator.ofInt(currentAlpha, targetAlpha);
+        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                int value = (int) animation.getAnimatedValue();
+                target.setBackgroundColor(Color.argb(value, r, g, b));
+            }
+        });
+        anim.setDuration(DOZE_BACKGROUND_ANIM_DURATION);
+        anim.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                target.setTag(TAG_KEY_ANIM, null);
+            }
+        });
+        anim.start();
+        target.setTag(TAG_KEY_ANIM, anim);
+    }
+
+    private static int getBackgroundAlpha(View view) {
+        if (view.getBackground() instanceof ColorDrawable) {
+            ColorDrawable drawable = (ColorDrawable) view.getBackground();
+            return Color.alpha(drawable.getColor());
+        } else {
+            return 0;
+        }
+    }
+
     public void setShadeEmpty(boolean shadeEmpty) {
         mShadeEmpty = shadeEmpty;
         updateEmptyShadeView();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index e939057..5d4c831 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -3948,6 +3948,13 @@
         return !mNotificationData.getActiveNotifications().isEmpty();
     }
 
+    public void wakeUpIfDozing(long time) {
+        if (mDozeServiceHost != null && mDozeServiceHost.isDozing()) {
+            PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+            pm.wakeUp(time);
+        }
+    }
+
     private final class ShadeUpdates {
         private final ArraySet<String> mVisibleNotifications = new ArraySet<String>();
         private final ArraySet<String> mNewVisibleNotifications = new ArraySet<String>();
@@ -3992,6 +3999,10 @@
                     + mCurrentDozeService + "]";
         }
 
+        public boolean isDozing() {
+            return mCurrentDozeService != null;
+        }
+
         public void firePowerSaveChanged(boolean active) {
             for (Callback callback : mCallbacks) {
                 callback.onPowerSaveChanged(active);
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 455c336..be48df7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -38,11 +38,12 @@
     private static final String TAG = "ScrimController";
     private static final boolean DEBUG = false;
 
+    public static final long ANIMATION_DURATION = 220;
+
     private static final float SCRIM_BEHIND_ALPHA = 0.62f;
     private static final float SCRIM_BEHIND_ALPHA_KEYGUARD = 0.55f;
     private static final float SCRIM_BEHIND_ALPHA_UNLOCKING = 0.2f;
     private static final float SCRIM_IN_FRONT_ALPHA = 0.75f;
-    private static final long ANIMATION_DURATION = 220;
     private static final int TAG_KEY_ANIM = R.id.scrim;
 
     private static final long PULSE_IN_ANIMATION_DURATION = 1000;
@@ -131,6 +132,7 @@
         mDozing = dozing;
         if (!mDozing) {
             cancelPulsing();
+            mAnimateChange = true;
         }
         scheduleUpdate();
     }
@@ -163,7 +165,7 @@
         if (mAnimateKeyguardFadingOut) {
             setScrimInFrontColor(0f);
             setScrimBehindColor(0f);
-        }else if (!mKeyguardShowing && !mBouncerShowing) {
+        } else if (!mKeyguardShowing && !mBouncerShowing) {
             updateScrimNormal();
             setScrimInFrontColor(0);
         } else {
@@ -217,8 +219,8 @@
             mScrimInFront.setClickable(false);
         } else {
 
-            // Eat touch events.
-            mScrimInFront.setClickable(true);
+            // Eat touch events (unless dozing).
+            mScrimInFront.setClickable(!mDozing);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index 1811d8d..a5217ab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -128,6 +128,10 @@
                 && mService.getBarState() == StatusBarState.KEYGUARD
                 && !mService.isBouncerShowing()) {
             intercept = mDragDownHelper.onInterceptTouchEvent(ev);
+            // wake up on a touch down event, if dozing
+            if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
+                mService.wakeUpIfDozing(ev.getEventTime());
+            }
         }
         if (!intercept) {
             super.onInterceptTouchEvent(ev);