Window Manager Flag Migration (5/n)

Completely remove the system UI visibility from the SystemUI side.

Bug: 118118435
Test: atest InsetsSourceProviderTest InsetsStateControllerTest
            InsetsPolicyTest WindowStateTests CommandQueueTest
            RegisterStatusBarResultTest InsetsFlagsTest
            LightBarControllerTest RegisterStatusBarResultTest
Test: build on specific target
Change-Id: Ibc866c5fbb35582dad8fd1a90376ce47dc501377
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
index ec64ee6..b6934c9 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
@@ -16,7 +16,6 @@
 
 package com.android.server.statusbar;
 
-import android.graphics.Rect;
 import android.os.Bundle;
 import android.view.InsetsState.InternalInsetType;
 import android.view.WindowInsetsController.Appearance;
@@ -79,9 +78,7 @@
     void startAssist(Bundle args);
     void onCameraLaunchGestureDetected(int source);
     void topAppWindowChanged(int displayId, boolean isFullscreen, boolean isImmersive);
-    void setSystemUiVisibility(int displayId, int vis, int fullscreenStackVis, int dockedStackVis,
-            int mask, Rect fullscreenBounds, Rect dockedBounds, boolean isNavbarColorManagedByIme,
-            String cause);
+    void setDisableFlags(int displayId, int flags, String cause);
     void toggleSplitScreen();
     void appTransitionFinished(int displayId);
 
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 489c343..661ca19 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -25,7 +25,6 @@
 import android.app.StatusBarManager;
 import android.content.ComponentName;
 import android.content.Context;
-import android.graphics.Rect;
 import android.hardware.biometrics.IBiometricServiceReceiverInternal;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayManager.DisplayListener;
@@ -43,10 +42,11 @@
 import android.service.notification.NotificationStats;
 import android.text.TextUtils;
 import android.util.ArrayMap;
-import android.util.Log;
+import android.util.ArraySet;
 import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.view.InsetsState.InternalInsetType;
 import android.view.WindowInsetsController.Appearance;
 
 import com.android.internal.R;
@@ -263,12 +263,8 @@
         }
 
         @Override
-        public void setSystemUiVisibility(int displayId, int vis, int fullscreenStackVis,
-                int dockedStackVis, int mask, Rect fullscreenBounds, Rect dockedBounds,
-                boolean isNavbarColorManagedByIme, String cause) {
-            StatusBarManagerService.this.setSystemUiVisibility(displayId, vis, fullscreenStackVis,
-                    dockedStackVis, mask, fullscreenBounds, dockedBounds, isNavbarColorManagedByIme,
-                    cause);
+        public void setDisableFlags(int displayId, int flags, String cause) {
+            StatusBarManagerService.this.setDisableFlags(displayId, flags, cause);
         }
 
         @Override
@@ -473,7 +469,10 @@
         @Override
         public void onSystemBarAppearanceChanged(int displayId, @Appearance int appearance,
                 AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme) {
-            // TODO (b/118118435): save the information to UiState
+            final UiState state = getUiState(displayId);
+            if (!state.appearanceEquals(appearance, appearanceRegions, navbarColorManagedByIme)) {
+                state.setAppearance(appearance, appearanceRegions, navbarColorManagedByIme);
+            }
             if (mBar != null) {
                 try {
                     mBar.onSystemBarAppearanceChanged(displayId, appearance, appearanceRegions,
@@ -483,7 +482,8 @@
         }
 
         @Override
-        public void showTransient(int displayId, int[] types) {
+        public void showTransient(int displayId, @InternalInsetType int[] types) {
+            getUiState(displayId).showTransient(types);
             if (mBar != null) {
                 try {
                     mBar.showTransient(displayId, types);
@@ -492,7 +492,8 @@
         }
 
         @Override
-        public void abortTransient(int displayId, int[] types) {
+        public void abortTransient(int displayId, @InternalInsetType int[] types) {
+            getUiState(displayId).clearTransient(types);
             if (mBar != null) {
                 try {
                     mBar.abortTransient(displayId, types);
@@ -896,54 +897,20 @@
         }
     }
 
-    @Override
-    public void setSystemUiVisibility(int displayId, int vis, int mask, String cause) {
-        final UiState state = getUiState(displayId);
-        setSystemUiVisibility(displayId, vis, 0, 0, mask,
-                state.mFullscreenStackBounds, state.mDockedStackBounds,
-                state.mNavbarColorManagedByIme, cause);
-    }
-
-    private void setSystemUiVisibility(int displayId, int vis, int fullscreenStackVis,
-            int dockedStackVis, int mask, Rect fullscreenBounds, Rect dockedBounds,
-            boolean isNavbarColorManagedByIme, String cause) {
+    private void setDisableFlags(int displayId, int flags, String cause) {
         // also allows calls from window manager which is in this process.
         enforceStatusBarService();
 
-        if (SPEW) Slog.d(TAG, "setSystemUiVisibility(0x" + Integer.toHexString(vis) + ")");
+        final int unknownFlags = flags & ~StatusBarManager.DISABLE_MASK;
+        if (unknownFlags != 0) {
+            Slog.e(TAG, "Unknown disable flags: 0x" + Integer.toHexString(unknownFlags),
+                    new RuntimeException());
+        }
+
+        if (SPEW) Slog.d(TAG, "setDisableFlags(0x" + Integer.toHexString(flags) + ")");
 
         synchronized (mLock) {
-            updateUiVisibilityLocked(displayId, vis, fullscreenStackVis, dockedStackVis, mask,
-                    fullscreenBounds, dockedBounds, isNavbarColorManagedByIme);
-            disableLocked(
-                    displayId,
-                    mCurrentUserId,
-                    vis & StatusBarManager.DISABLE_MASK,
-                    mSysUiVisToken,
-                    cause, 1);
-        }
-    }
-
-    private void updateUiVisibilityLocked(final int displayId, final int vis,
-            final int fullscreenStackVis, final int dockedStackVis, final int mask,
-            final Rect fullscreenBounds, final Rect dockedBounds,
-            final boolean isNavbarColorManagedByIme) {
-        final UiState state = getUiState(displayId);
-        if (!state.systemUiStateEquals(vis, fullscreenStackVis, dockedStackVis,
-                fullscreenBounds, dockedBounds, isNavbarColorManagedByIme)) {
-            state.setSystemUiState(vis, fullscreenStackVis, dockedStackVis, fullscreenBounds,
-                    dockedBounds, isNavbarColorManagedByIme);
-            mHandler.post(() -> {
-                if (mBar != null) {
-                    try {
-                        mBar.setSystemUiVisibility(displayId, vis, fullscreenStackVis,
-                                dockedStackVis, mask, fullscreenBounds, dockedBounds,
-                                isNavbarColorManagedByIme);
-                    } catch (RemoteException ex) {
-                        Log.w(TAG, "Can not get StatusBar!");
-                    }
-                }
-            });
+            disableLocked(displayId, mCurrentUserId, flags, mSysUiVisToken, cause, 1);
         }
     }
 
@@ -965,11 +932,10 @@
     }
 
     private class UiState {
-        private int mSystemUiVisibility = 0;
-        private int mFullscreenStackSysUiVisibility = 0;
-        private int mDockedStackSysUiVisibility = 0;
-        private final Rect mFullscreenStackBounds = new Rect();
-        private final Rect mDockedStackBounds = new Rect();
+        private @Appearance int mAppearance = 0;
+        private AppearanceRegion[] mAppearanceRegions = new AppearanceRegion[0];
+        private ArraySet<Integer> mTransientBarTypes = new ArraySet<>();
+        private boolean mNavbarColorManagedByIme = false;
         private boolean mFullscreen = false;
         private boolean mImmersive = false;
         private int mDisabled1 = 0;
@@ -978,7 +944,47 @@
         private int mImeBackDisposition = 0;
         private boolean mShowImeSwitcher = false;
         private IBinder mImeToken = null;
-        private boolean mNavbarColorManagedByIme = false;
+
+        private void setAppearance(@Appearance int appearance,
+                AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme) {
+            mAppearance = appearance;
+            mAppearanceRegions = appearanceRegions;
+            mNavbarColorManagedByIme = navbarColorManagedByIme;
+        }
+
+        private boolean appearanceEquals(@Appearance int appearance,
+                AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme) {
+            if (mAppearance != appearance || mAppearanceRegions.length != appearanceRegions.length
+                    || mNavbarColorManagedByIme != navbarColorManagedByIme) {
+                return false;
+            }
+            for (int i = appearanceRegions.length - 1; i >= 0; i--) {
+                if (!mAppearanceRegions[i].equals(appearanceRegions[i])) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        private void showTransient(@InternalInsetType int[] types) {
+            for (int type : types) {
+                mTransientBarTypes.add(type);
+            }
+        }
+
+        private void clearTransient(@InternalInsetType int[] types) {
+            for (int type : types) {
+                mTransientBarTypes.remove(type);
+            }
+        }
+
+        private void setFullscreen(boolean isFullscreen) {
+            mFullscreen = isFullscreen;
+        }
+
+        private void setImmersive(boolean isImmersive) {
+            mImmersive = isImmersive;
+        }
 
         private int getDisabled1() {
             return mDisabled1;
@@ -993,40 +999,10 @@
             mDisabled2 = disabled2;
         }
 
-        private void setFullscreen(boolean isFullscreen) {
-            mFullscreen = isFullscreen;
-        }
-
-        private void setImmersive(boolean immersive) {
-            mImmersive = immersive;
-        }
-
         private boolean disableEquals(int disabled1, int disabled2) {
             return mDisabled1 == disabled1 && mDisabled2 == disabled2;
         }
 
-        private void setSystemUiState(final int vis, final int fullscreenStackVis,
-                final int dockedStackVis, final Rect fullscreenBounds, final Rect dockedBounds,
-                final boolean navbarColorManagedByIme) {
-            mSystemUiVisibility = vis;
-            mFullscreenStackSysUiVisibility = fullscreenStackVis;
-            mDockedStackSysUiVisibility = dockedStackVis;
-            mFullscreenStackBounds.set(fullscreenBounds);
-            mDockedStackBounds.set(dockedBounds);
-            mNavbarColorManagedByIme = navbarColorManagedByIme;
-        }
-
-        private boolean systemUiStateEquals(final int vis, final int fullscreenStackVis,
-                final int dockedStackVis, final Rect fullscreenBounds, final Rect dockedBounds,
-                final boolean navbarColorManagedByIme) {
-            return mSystemUiVisibility == vis
-                && mFullscreenStackSysUiVisibility == fullscreenStackVis
-                && mDockedStackSysUiVisibility == dockedStackVis
-                && mFullscreenStackBounds.equals(fullscreenBounds)
-                && mDockedStackBounds.equals(dockedBounds)
-                && mNavbarColorManagedByIme == navbarColorManagedByIme;
-        }
-
         private void setImeWindowState(final int vis, final int backDisposition,
                 final boolean showImeSwitcher, final IBinder token) {
             mImeWindowVis = vis;
@@ -1084,13 +1060,16 @@
             // TODO(b/118592525): Currently, status bar only works on the default display.
             // Make it aware of multi-display if needed.
             final UiState state = mDisplayUiState.get(DEFAULT_DISPLAY);
+            final int[] transientBarTypes = new int[state.mTransientBarTypes.size()];
+            for (int i = 0; i < transientBarTypes.length; i++) {
+                transientBarTypes[i] = state.mTransientBarTypes.valueAt(i);
+            }
             return new RegisterStatusBarResult(icons, gatherDisableActionsLocked(mCurrentUserId, 1),
-                    state.mSystemUiVisibility, state.mImeWindowVis,
+                    state.mAppearance, state.mAppearanceRegions, state.mImeWindowVis,
                     state.mImeBackDisposition, state.mShowImeSwitcher,
-                    gatherDisableActionsLocked(mCurrentUserId, 2),
-                    state.mFullscreenStackSysUiVisibility, state.mDockedStackSysUiVisibility,
-                    state.mImeToken, state.mFullscreenStackBounds, state.mDockedStackBounds,
-                    state.mNavbarColorManagedByIme, state.mFullscreen, state.mImmersive);
+                    gatherDisableActionsLocked(mCurrentUserId, 2), state.mImeToken,
+                    state.mNavbarColorManagedByIme, state.mFullscreen, state.mImmersive,
+                    transientBarTypes);
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 6e238b3..fcfd9de 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -144,13 +144,16 @@
 import android.view.InputDevice;
 import android.view.InputEvent;
 import android.view.InputEventReceiver;
+import android.view.InsetsFlags;
 import android.view.InsetsState;
+import android.view.InsetsState.InternalInsetType;
 import android.view.MotionEvent;
 import android.view.PointerIcon;
 import android.view.Surface;
 import android.view.View;
 import android.view.ViewRootImpl;
 import android.view.WindowInsets;
+import android.view.WindowInsetsController.Appearance;
 import android.view.WindowManager;
 import android.view.WindowManager.LayoutParams;
 import android.view.WindowManagerGlobal;
@@ -332,8 +335,6 @@
     private int mResettingSystemUiFlags = 0;
     // Bits that we are currently always keeping cleared.
     private int mForceClearedSystemUiFlags = 0;
-    private int mLastFullscreenStackSysUiFlags;
-    private int mLastDockedStackSysUiFlags;
     private int mLastAppearance;
     private int mLastFullscreenAppearance;
     private int mLastDockedAppearance;
@@ -3172,11 +3173,6 @@
                     &= ~PolicyControl.adjustClearableFlags(win, View.SYSTEM_UI_CLEARABLE_FLAGS);
         }
 
-        final int appearance = win.mAttrs.insetsFlags.appearance;
-        final int fullscreenVisibility = updateLightStatusBarLw(0 /* vis */,
-                mTopFullscreenOpaqueWindowState, mTopFullscreenOpaqueOrDimmingWindowState);
-        final int dockedVisibility = updateLightStatusBarLw(0 /* vis */,
-                mTopDockedOpaqueWindowState, mTopDockedOpaqueOrDimmingWindowState);
         final int fullscreenAppearance = updateLightStatusBarAppearanceLw(0 /* vis */,
                 mTopFullscreenOpaqueWindowState, mTopFullscreenOpaqueOrDimmingWindowState);
         final int dockedAppearance = updateLightStatusBarAppearanceLw(0 /* vis */,
@@ -3190,9 +3186,9 @@
         final Pair<Integer, Boolean> result =
                 updateSystemBarsLw(win, mLastSystemUiFlags, tmpVisibility);
         final int visibility = result.first;
+        final int appearance = win.mAttrs.insetsFlags.appearance
+                | InsetsFlags.getAppearance(visibility);
         final int diff = visibility ^ mLastSystemUiFlags;
-        final int fullscreenDiff = fullscreenVisibility ^ mLastFullscreenStackSysUiFlags;
-        final int dockedDiff = dockedVisibility ^ mLastDockedStackSysUiFlags;
         final InsetsPolicy insetsPolicy = getInsetsPolicy();
         final boolean isFullscreen = (visibility & (View.SYSTEM_UI_FLAG_FULLSCREEN
                         | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION)) != 0
@@ -3205,7 +3201,7 @@
                         | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)) != 0
                 || behavior == BEHAVIOR_SHOW_BARS_BY_SWIPE
                 || behavior == BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
-        if (diff == 0 && fullscreenDiff == 0 && dockedDiff == 0
+        if (diff == 0
                 && mLastAppearance == appearance
                 && mLastFullscreenAppearance == fullscreenAppearance
                 && mLastDockedAppearance == dockedAppearance
@@ -3216,9 +3212,12 @@
                 && mLastDockedStackBounds.equals(mDockedStackBounds)) {
             return 0;
         }
+
+        // Obtains which types should show transient and which types should abort transient.
+        // If there is no transient state change, this pair will contain two empty arrays.
+        final Pair<int[], int[]> transientState = getTransientState(visibility, mLastSystemUiFlags);
+
         mLastSystemUiFlags = visibility;
-        mLastFullscreenStackSysUiFlags = fullscreenVisibility;
-        mLastDockedStackSysUiFlags = dockedVisibility;
         mLastAppearance = appearance;
         mLastFullscreenAppearance = fullscreenAppearance;
         mLastDockedAppearance = dockedAppearance;
@@ -3240,14 +3239,16 @@
             StatusBarManagerInternal statusBar = getStatusBarManagerInternal();
             if (statusBar != null) {
                 final int displayId = getDisplayId();
-                // TODO(b/118118435): disabled flags only
-                statusBar.setSystemUiVisibility(displayId, visibility, fullscreenVisibility,
-                        dockedVisibility, 0xffffffff, fullscreenStackBounds,
-                        dockedStackBounds, isNavbarColorManagedByIme, win.toString());
-                if (ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_FULL) {
-                    statusBar.onSystemBarAppearanceChanged(displayId, appearance,
-                            appearanceRegions, isNavbarColorManagedByIme);
+                statusBar.setDisableFlags(displayId, visibility & StatusBarManager.DISABLE_MASK,
+                        win.toString());
+                if (transientState.first.length > 0) {
+                    statusBar.showTransient(displayId, transientState.first);
                 }
+                if (transientState.second.length > 0) {
+                    statusBar.abortTransient(displayId, transientState.second);
+                }
+                statusBar.onSystemBarAppearanceChanged(displayId, appearance,
+                        appearanceRegions, isNavbarColorManagedByIme);
                 statusBar.topAppWindowChanged(displayId, isFullscreen, isImmersive);
 
                 // TODO(b/118118435): Remove this after removing system UI visibilities.
@@ -3258,23 +3259,28 @@
         return diff;
     }
 
-    private int updateLightStatusBarLw(int vis, WindowState opaque, WindowState opaqueOrDimming) {
-        final boolean onKeyguard = isStatusBarKeyguard() && !isKeyguardOccluded();
-        final WindowState statusColorWin = onKeyguard ? mStatusBar : opaqueOrDimming;
-        if (statusColorWin != null && (statusColorWin == opaque || onKeyguard)) {
-            // If the top fullscreen-or-dimming window is also the top fullscreen, respect
-            // its light flag.
-            vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
-            vis |= PolicyControl.getSystemUiVisibility(statusColorWin, null)
-                    & View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
-        } else if (statusColorWin != null && statusColorWin.isDimming()) {
-            // Otherwise if it's dimming, clear the light flag.
-            vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
-        }
-        return vis;
+    private static Pair<int[], int[]> getTransientState(int vis, int oldVis) {
+        final IntArray typesToShow = new IntArray(0);
+        final IntArray typesToAbort = new IntArray(0);
+        updateTransientState(vis, oldVis, View.STATUS_BAR_TRANSIENT, TYPE_TOP_BAR, typesToShow,
+                typesToAbort);
+        updateTransientState(vis, oldVis, View.NAVIGATION_BAR_TRANSIENT,
+                InsetsState.TYPE_NAVIGATION_BAR, typesToShow, typesToAbort);
+        return Pair.create(typesToShow.toArray(), typesToAbort.toArray());
     }
 
-    private int updateLightStatusBarAppearanceLw(int appearance, WindowState opaque,
+    private static void updateTransientState(int vis, int oldVis, int transientFlag,
+            @InternalInsetType int type, IntArray typesToShow, IntArray typesToAbort) {
+        final boolean wasTransient = (oldVis & transientFlag) != 0;
+        final boolean isTransient = (vis & transientFlag) != 0;
+        if (!wasTransient && isTransient) {
+            typesToShow.add(type);
+        } else if (wasTransient && !isTransient) {
+            typesToAbort.add(type);
+        }
+    }
+
+    private int updateLightStatusBarAppearanceLw(@Appearance int appearance, WindowState opaque,
             WindowState opaqueOrDimming) {
         final boolean onKeyguard = isStatusBarKeyguard() && !isKeyguardOccluded();
         final WindowState statusColorWin = onKeyguard ? mStatusBar : opaqueOrDimming;
@@ -3282,7 +3288,10 @@
             // If the top fullscreen-or-dimming window is also the top fullscreen, respect
             // its light flag.
             appearance &= ~APPEARANCE_LIGHT_TOP_BAR;
-            appearance |= statusColorWin.mAttrs.insetsFlags.appearance & APPEARANCE_LIGHT_TOP_BAR;
+            final int legacyAppearance = InsetsFlags.getAppearance(
+                    PolicyControl.getSystemUiVisibility(statusColorWin, null));
+            appearance |= (statusColorWin.mAttrs.insetsFlags.appearance | legacyAppearance)
+                    & APPEARANCE_LIGHT_TOP_BAR;
         } else if (statusColorWin != null && statusColorWin.isDimming()) {
             // Otherwise if it's dimming, clear the light flag.
             appearance &= ~APPEARANCE_LIGHT_TOP_BAR;
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 17e67eb..e5327fb 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -638,7 +638,7 @@
     private boolean mIsDimming = false;
 
     private @Nullable InsetsSourceProvider mControllableInsetProvider;
-    private InsetsState mClientInsetsState = new InsetsState();
+    private InsetsState mClientInsetsState;
 
     private static final float DEFAULT_DIM_AMOUNT_DEAD_WINDOW = 0.5f;
     private KeyInterceptionInfo mKeyInterceptionInfo;
@@ -767,6 +767,8 @@
         mSeq = seq;
         mPowerManagerWrapper = powerManagerWrapper;
         mForceSeamlesslyRotate = token.mRoundedCornerOverlay;
+        mClientInsetsState =
+                getDisplayContent().getInsetsStateController().getInsetsForDispatch(this);
         if (DEBUG) {
             Slog.v(TAG, "Window " + this + " client=" + c.asBinder()
                             + " token=" + token + " (" + mAttrs.token + ")" + " params=" + a);