Don't flash system bars while showing an immersive app on lockscreen

Before applying this patch, when a show-when-locked immersive app is
showing, the system bars would quickly show and hide, which are
redundant to the user.

The root cause is that, for nav bar, we have a policy to show nav bar
if the width and height of status bar are MATCH_PARENT and status bar
has no PRIVATE_FLAG_KEYGUARD. When keyguard is becoming status bar,
its keyguard flag would be removed first, and then the height would
be changed to the bar height. So the nav bar would be shown between
these events. For status bar, we force showing it when it is expanded
by checking its width and height are MATCH_PARENT or not.

To fix the issue, this change introduces a new private flag which
indicates that the status bar window is now in an explicit expanded
state. We check this flag instead of checking the width and height of
status bar.

This change also fix a bug that: when AOD is enabled, if the
foreground app has FLAG_SHOW_WHEN_LOCKED, FLAG_TURN_SCREEN_ON, and
FLAG_FULLSCREEN, clicking on the power key would make it show the app
again instead of AOD. (not 100%, but chances)

Bug: 80147982
Test: 1. go/wm-smoke
      2. Launch a show-when-locked turn-screen-on immersive app on
         AOD, and see if any system bar flashes.
      3. Launch a show-when-locked turn-screen-on immersive app on
         lockscreen, and see if any system bar flashes.
      4. a. Enable AOD in Settings.
         b. Open a show-when-locked turn-screen-on immersive app.
         c. Click on power key, and see if AOD shows.
      5. Launch an immersive app and drag down the status bar, see
         if nav bar keeps there as long as status bar is expanded.

Change-Id: Ie885d504eb73ae8a86736b2c3ed4fb03eb9f739e
Merged-In: Ie885d504eb73ae8a86736b2c3ed4fb03eb9f739e
(cherry picked from commit 3404601e073ee2fb7867e3aa50a730bcf51eda07)
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index fc34a25..67e06e7 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1693,6 +1693,15 @@
         public static final int PRIVATE_FLAG_IS_SCREEN_DECOR = 0x00400000;
 
         /**
+         * Flag to indicate that the status bar window is now in an explicit expanded state, meaning
+         * that status bar will not be hidden by any window with flag {@link #FLAG_FULLSCREEN} or
+         * {@link View#SYSTEM_UI_FLAG_FULLSCREEN} set.
+         * This can only be set by {@link LayoutParams#TYPE_STATUS_BAR}.
+         * @hide
+         */
+        public static final int PRIVATE_FLAG_STATUS_BAR_EXPANDED = 0x00800000;
+
+        /**
          * Control flags that are private to the platform.
          * @hide
          */
@@ -1780,7 +1789,11 @@
                 @ViewDebug.FlagToString(
                         mask = PRIVATE_FLAG_IS_SCREEN_DECOR,
                         equals = PRIVATE_FLAG_IS_SCREEN_DECOR,
-                        name = "IS_SCREEN_DECOR")
+                        name = "IS_SCREEN_DECOR"),
+                @ViewDebug.FlagToString(
+                        mask = PRIVATE_FLAG_STATUS_BAR_EXPANDED,
+                        equals = PRIVATE_FLAG_STATUS_BAR_EXPANDED,
+                        name = "STATUS_BAR_EXPANDED")
         })
         @TestApi
         public int privateFlags;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
index fadc0ea..a38328a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
@@ -180,6 +180,15 @@
         mLpChanged.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
     }
 
+    private void applyExpandedFlag(State state) {
+        if (state.panelExpanded || state.isKeyguardShowingAndNotOccluded() || state.bouncerShowing
+                || ENABLE_REMOTE_INPUT && state.remoteInputActive) {
+            mLpChanged.privateFlags |= LayoutParams.PRIVATE_FLAG_STATUS_BAR_EXPANDED;
+        } else {
+            mLpChanged.privateFlags &= ~LayoutParams.PRIVATE_FLAG_STATUS_BAR_EXPANDED;
+        }
+    }
+
     private void applyHeight(State state) {
         boolean expanded = isExpanded(state);
         if (state.forcePluginOpen) {
@@ -234,6 +243,7 @@
         applyKeyguardFlags(state);
         applyForceStatusBarVisibleFlag(state);
         applyFocusableFlag(state);
+        applyExpandedFlag(state);
         adjustScreenOrientation(state);
         applyHeight(state);
         applyUserActivityTimeout(state);
diff --git a/services/core/java/com/android/server/policy/BarController.java b/services/core/java/com/android/server/policy/BarController.java
index eca6f9f..14c985c 100644
--- a/services/core/java/com/android/server/policy/BarController.java
+++ b/services/core/java/com/android/server/policy/BarController.java
@@ -196,7 +196,7 @@
     }
 
     protected boolean skipAnimation() {
-        return false;
+        return !mWin.isDrawnLw();
     }
 
     private int computeStateLw(boolean wasVis, boolean wasAnim, WindowState win, boolean change) {
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 7d6b896..c2a24d8 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -76,6 +76,7 @@
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_STATUS_BAR_EXPANDED;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR;
 import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE;
 import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_JUMPCUT;
@@ -4692,8 +4693,7 @@
                 navTranslucent &= areTranslucentBarsAllowed();
             }
             boolean statusBarExpandedNotKeyguard = !isKeyguardShowing && mStatusBar != null
-                    && mStatusBar.getAttrs().height == MATCH_PARENT
-                    && mStatusBar.getAttrs().width == MATCH_PARENT;
+                    && (mStatusBar.getAttrs().privateFlags & PRIVATE_FLAG_STATUS_BAR_EXPANDED) != 0;
 
             // When the navigation bar isn't visible, we put up a fake input window to catch all
             // touch events. This way we can detect when the user presses anywhere to bring back the
@@ -5696,7 +5696,7 @@
         }
 
         // Take note if a window wants to acquire a sleep token.
-        if (win.isVisibleLw() && (attrs.privateFlags & PRIVATE_FLAG_ACQUIRES_SLEEP_TOKEN) != 0
+        if ((attrs.privateFlags & PRIVATE_FLAG_ACQUIRES_SLEEP_TOKEN) != 0
                 && win.canAcquireSleepToken()) {
             mWindowSleepTokenNeeded = true;
         }
@@ -5752,9 +5752,8 @@
                 mStatusBarController.setShowTransparent(true /* transparent */);
             }
 
-            WindowManager.LayoutParams statusBarAttrs = mStatusBar.getAttrs();
-            boolean statusBarExpanded = statusBarAttrs.height == MATCH_PARENT
-                    && statusBarAttrs.width == MATCH_PARENT;
+            boolean statusBarExpanded =
+                    (mStatusBar.getAttrs().privateFlags & PRIVATE_FLAG_STATUS_BAR_EXPANDED) != 0;
             boolean topAppHidesStatusBar = topAppHidesStatusBar();
             if (mForceStatusBar || mForceStatusBarFromKeyguard || mForceStatusBarTransparent
                     || statusBarExpanded) {