Add support for seamless transion from/to AoD

Bug: 64155983
Test: runtest -x packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java
Test: manual
Change-Id: I06e72cd5964944c79fb7bfda6881fc4a5a79ca7b
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
index 3f57c2f..50cbd69 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -119,6 +119,28 @@
         return mAmbientDisplayConfiguration.alwaysOnEnabled(UserHandle.USER_CURRENT);
     }
 
+    /**
+     * Some screens need to be completely black before changing the display power mode,
+     * unexpected behavior might happen if this parameter isn't respected.
+     *
+     * @return true if screen needs to be completely black before a power transition.
+     */
+    public boolean getDisplayNeedsBlanking() {
+        return mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_displayBlanksAfterDoze);
+    }
+
+    /**
+     * Whether we can implement our own screen off animation or if we need
+     * to rely on DisplayPowerManager to dim the display.
+     *
+     * @return true if SystemUI can control the screen off animation.
+     */
+    public boolean getCanControlScreenOffAnimation() {
+        return !mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_dozeAfterScreenOff);
+    }
+
     private boolean getBoolean(String propName, int resId) {
         return SystemProperties.getBoolean(propName, mContext.getResources().getBoolean(resId));
     }
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 0db98f3..c33cc50 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -20,6 +20,7 @@
 import android.os.Trace;
 
 import com.android.systemui.statusbar.ScrimView;
+import com.android.systemui.statusbar.stack.StackStateAnimator;
 
 /**
  * Possible states of the ScrimController state machine.
@@ -38,12 +39,18 @@
 
         @Override
         public void prepare(ScrimState previousState) {
-            // DisplayPowerManager will blank the screen, we'll just
-            // set our scrim to black in this frame to avoid flickering and
-            // fade it out afterwards.
-            mBlankScreen = previousState == ScrimState.AOD;
+            mBlankScreen = false;
             if (previousState == ScrimState.AOD) {
-                updateScrimColor(mScrimInFront, 1, Color.BLACK);
+                mAnimationDuration = StackStateAnimator.ANIMATION_DURATION_WAKEUP;
+                if (mDisplayRequiresBlanking) {
+                    // DisplayPowerManager will blank the screen, we'll just
+                    // set our scrim to black in this frame to avoid flickering and
+                    // fade it out afterwards.
+                    mBlankScreen = true;
+                    updateScrimColor(mScrimInFront, 1, Color.BLACK);
+                }
+            } else {
+                mAnimationDuration = ScrimController.ANIMATION_DURATION;
             }
             mCurrentBehindAlpha = mScrimBehindAlphaKeyguard;
             mCurrentInFrontAlpha = 0;
@@ -78,7 +85,7 @@
     AOD {
         @Override
         public void prepare(ScrimState previousState) {
-            if (previousState == ScrimState.PULSING) {
+            if (previousState == ScrimState.PULSING && !mCanControlScreenOff) {
                 updateScrimColor(mScrimInFront, 1, Color.BLACK);
             }
             final boolean alwaysOnEnabled = mDozeParameters.getAlwaysOn();
@@ -89,7 +96,7 @@
             mCurrentBehindTint = Color.BLACK;
             // DisplayPowerManager will blank the screen for us, we just need
             // to set our state.
-            mAnimateChange = false;
+            mAnimateChange = mCanControlScreenOff;
         }
     },
 
@@ -103,8 +110,10 @@
             mCurrentInFrontAlpha = 0;
             mCurrentInFrontTint = Color.BLACK;
             mCurrentBehindTint = Color.BLACK;
-            mBlankScreen = true;
-            updateScrimColor(mScrimInFront, 1, Color.BLACK);
+            mBlankScreen = mDisplayRequiresBlanking;
+            if (mDisplayRequiresBlanking) {
+                updateScrimColor(mScrimInFront, 1, Color.BLACK);
+            }
         }
     },
 
@@ -147,11 +156,15 @@
     ScrimView mScrimInFront;
     ScrimView mScrimBehind;
     DozeParameters mDozeParameters;
+    boolean mDisplayRequiresBlanking;
+    boolean mCanControlScreenOff;
 
     public void init(ScrimView scrimInFront, ScrimView scrimBehind, DozeParameters dozeParameters) {
         mScrimInFront = scrimInFront;
         mScrimBehind = scrimBehind;
         mDozeParameters = dozeParameters;
+        mDisplayRequiresBlanking = dozeParameters.getDisplayNeedsBlanking();
+        mCanControlScreenOff = dozeParameters.getCanControlScreenOffAnimation();
     }
 
     public void prepare(ScrimState previousState) {
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 c61b7e8..7b04f19 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -4407,7 +4407,8 @@
     private void updateDozingState() {
         Trace.traceCounter(Trace.TRACE_TAG_APP, "dozing", mDozing ? 1 : 0);
         Trace.beginSection("StatusBar#updateDozingState");
-        boolean animate = !mDozing && mDozeServiceHost.shouldAnimateWakeup();
+        boolean animate = (!mDozing && mDozeServiceHost.shouldAnimateWakeup())
+                || (mDozing && mDozeServiceHost.shouldAnimateScreenOff());
         mNotificationPanel.setDozing(mDozing, animate);
         mStackScroller.setDark(mDozing, animate, mWakeUpTouchLocation);
         mDozeScrimController.setDozing(mDozing);
@@ -5175,6 +5176,7 @@
     private final class DozeServiceHost implements DozeHost {
         private final ArrayList<Callback> mCallbacks = new ArrayList<>();
         private boolean mAnimateWakeup;
+        private boolean mAnimateScreenOff;
         private boolean mIgnoreTouchWhilePulsing;
 
         @Override
@@ -5322,6 +5324,11 @@
         }
 
         @Override
+        public void setAnimateScreenOff(boolean animateScreenOff) {
+            mAnimateScreenOff = animateScreenOff;
+        }
+
+        @Override
         public void onDoubleTap(float screenX, float screenY) {
             if (screenX > 0 && screenY > 0 && mAmbientIndicationContainer != null
                 && mAmbientIndicationContainer.getVisibility() == View.VISIBLE) {
@@ -5365,6 +5372,10 @@
         private boolean shouldAnimateWakeup() {
             return mAnimateWakeup;
         }
+
+        public boolean shouldAnimateScreenOff() {
+            return mAnimateScreenOff;
+        }
     }
 
     public boolean shouldIgnoreTouch() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
index f78a718..236c348 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
@@ -40,7 +40,7 @@
 public class StackStateAnimator {
 
     public static final int ANIMATION_DURATION_STANDARD = 360;
-    public static final int ANIMATION_DURATION_WAKEUP = 200;
+    public static final int ANIMATION_DURATION_WAKEUP = 500;
     public static final int ANIMATION_DURATION_GO_TO_FULL_SHADE = 448;
     public static final int ANIMATION_DURATION_APPEAR_DISAPPEAR = 464;
     public static final int ANIMATION_DURATION_DIMMED_ACTIVATED = 220;