Keep alternate reference to mStatusBar and mNavigationBar for flexible insets

Needed in order to ensure the immersive confirmation dialog and behavior
work correctly and for the swipe directions to updated based on system
bar position

Bug: 156304383
Test: manual (change immersive behavior), atest WindowInsetsControllerTests
Change-Id: Id4258d06e9d02a55b46afd53eefb7ec19a50a2ed
diff --git a/core/java/android/view/WindowManagerPolicyConstants.java b/core/java/android/view/WindowManagerPolicyConstants.java
index 492ab6f..8c35520 100644
--- a/core/java/android/view/WindowManagerPolicyConstants.java
+++ b/core/java/android/view/WindowManagerPolicyConstants.java
@@ -49,6 +49,13 @@
     int PRESENCE_INTERNAL = 1 << 0;
     int PRESENCE_EXTERNAL = 1 << 1;
 
+    // Alternate bars position values
+    int ALT_BAR_UNKNOWN = -1;
+    int ALT_BAR_LEFT = 1 << 0;
+    int ALT_BAR_RIGHT = 1 << 1;
+    int ALT_BAR_BOTTOM = 1 << 2;
+    int ALT_BAR_TOP = 1 << 3;
+
     // Navigation bar position values
     int NAV_BAR_INVALID = -1;
     int NAV_BAR_LEFT = 1 << 0;
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index 8868a6c..a1d42d3 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -141,6 +141,10 @@
     @IntDef({NAV_BAR_LEFT, NAV_BAR_RIGHT, NAV_BAR_BOTTOM})
     @interface NavigationBarPosition {}
 
+    @Retention(SOURCE)
+    @IntDef({ALT_BAR_UNKNOWN, ALT_BAR_LEFT, ALT_BAR_RIGHT, ALT_BAR_BOTTOM, ALT_BAR_TOP})
+    @interface AltBarPosition {}
+
     /**
      * Pass this event to the user / app.  To be returned from
      * {@link #interceptKeyBeforeQueueing}.
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 5ae6f80b..3b5c242 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -102,6 +102,11 @@
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 import static android.view.WindowManagerGlobal.ADD_OKAY;
 import static android.view.WindowManagerPolicyConstants.ACTION_HDMI_PLUGGED;
+import static android.view.WindowManagerPolicyConstants.ALT_BAR_BOTTOM;
+import static android.view.WindowManagerPolicyConstants.ALT_BAR_LEFT;
+import static android.view.WindowManagerPolicyConstants.ALT_BAR_RIGHT;
+import static android.view.WindowManagerPolicyConstants.ALT_BAR_TOP;
+import static android.view.WindowManagerPolicyConstants.ALT_BAR_UNKNOWN;
 import static android.view.WindowManagerPolicyConstants.EXTRA_HDMI_PLUGGED_STATE;
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_BOTTOM;
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
@@ -314,6 +319,17 @@
     private int[] mNavigationBarHeightForRotationInCarMode = new int[4];
     private int[] mNavigationBarWidthForRotationInCarMode = new int[4];
 
+    // Alternative status bar for when flexible insets mapping is used to place the status bar on
+    // another side of the screen.
+    private WindowState mStatusBarAlt = null;
+    @WindowManagerPolicy.AltBarPosition
+    private int mStatusBarAltPosition = ALT_BAR_UNKNOWN;
+    // Alternative navigation bar for when flexible insets mapping is used to place the navigation
+    // bar elsewhere on the screen.
+    private WindowState mNavigationBarAlt = null;
+    @WindowManagerPolicy.AltBarPosition
+    private int mNavigationBarAltPosition = ALT_BAR_UNKNOWN;
+
     /** See {@link #getNavigationBarFrameHeight} */
     private int[] mNavigationBarFrameHeightForRotationDefault = new int[4];
 
@@ -431,7 +447,7 @@
                 case MSG_REQUEST_TRANSIENT_BARS:
                     synchronized (mLock) {
                         WindowState targetBar = (msg.arg1 == MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS)
-                                ? mStatusBar : mNavigationBar;
+                                ? getStatusBar() : getNavigationBar();
                         if (targetBar != null) {
                             requestTransientBars(targetBar);
                         }
@@ -494,6 +510,7 @@
                             if (mStatusBar != null) {
                                 requestTransientBars(mStatusBar);
                             }
+                            checkAltBarSwipeForTransientBars(ALT_BAR_TOP);
                         }
                     }
 
@@ -504,6 +521,7 @@
                                     && mNavigationBarPosition == NAV_BAR_BOTTOM) {
                                 requestTransientBars(mNavigationBar);
                             }
+                            checkAltBarSwipeForTransientBars(ALT_BAR_BOTTOM);
                         }
                     }
 
@@ -520,6 +538,7 @@
                                             excludedRegion)) {
                                 requestTransientBars(mNavigationBar);
                             }
+                            checkAltBarSwipeForTransientBars(ALT_BAR_RIGHT);
                         }
                         excludedRegion.recycle();
                     }
@@ -537,6 +556,7 @@
                                             excludedRegion)) {
                                 requestTransientBars(mNavigationBar);
                             }
+                            checkAltBarSwipeForTransientBars(ALT_BAR_LEFT);
                         }
                         excludedRegion.recycle();
                     }
@@ -638,6 +658,15 @@
         mHandler.post(mGestureNavigationSettingsObserver::register);
     }
 
+    private void checkAltBarSwipeForTransientBars(@WindowManagerPolicy.AltBarPosition int pos) {
+        if (mStatusBarAlt != null && mStatusBarAltPosition == pos) {
+            requestTransientBars(mStatusBarAlt);
+        }
+        if (mNavigationBarAlt != null && mNavigationBarAltPosition == pos) {
+            requestTransientBars(mNavigationBarAlt);
+        }
+    }
+
     void systemReady() {
         mSystemGestures.systemReady();
         if (mService.mPointerLocationEnabled) {
@@ -899,6 +928,14 @@
                 }
                 break;
         }
+
+        // Check if alternate bars positions were updated.
+        if (mStatusBarAlt == win) {
+            mStatusBarAltPosition = getAltBarPosition(attrs);
+        }
+        if (mNavigationBarAlt == win) {
+            mNavigationBarAltPosition = getAltBarPosition(attrs);
+        }
     }
 
     /**
@@ -938,10 +975,9 @@
                 mContext.enforcePermission(
                         android.Manifest.permission.STATUS_BAR_SERVICE, callingPid, callingUid,
                         "DisplayPolicy");
-                if (mStatusBar != null) {
-                    if (mStatusBar.isAlive()) {
-                        return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
-                    }
+                if ((mStatusBar != null && mStatusBar.isAlive())
+                        || (mStatusBarAlt != null && mStatusBarAlt.isAlive())) {
+                    return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
                 }
                 break;
             case TYPE_NOTIFICATION_SHADE:
@@ -958,10 +994,9 @@
                 mContext.enforcePermission(
                         android.Manifest.permission.STATUS_BAR_SERVICE, callingPid, callingUid,
                         "DisplayPolicy");
-                if (mNavigationBar != null) {
-                    if (mNavigationBar.isAlive()) {
-                        return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
-                    }
+                if ((mNavigationBar != null && mNavigationBar.isAlive())
+                        || (mNavigationBarAlt != null && mNavigationBarAlt.isAlive())) {
+                    return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
                 }
                 break;
             case TYPE_NAVIGATION_BAR_PANEL:
@@ -993,6 +1028,23 @@
                     android.Manifest.permission.STATUS_BAR_SERVICE, callingPid, callingUid,
                     "DisplayPolicy");
             enforceSingleInsetsTypeCorrespondingToWindowType(attrs.providesInsetsTypes);
+
+            for (@InternalInsetsType int insetType : attrs.providesInsetsTypes) {
+                switch (insetType) {
+                    case ITYPE_STATUS_BAR:
+                        if ((mStatusBar != null && mStatusBar.isAlive())
+                                || (mStatusBarAlt != null && mStatusBarAlt.isAlive())) {
+                            return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
+                        }
+                        break;
+                    case ITYPE_NAVIGATION_BAR:
+                        if ((mNavigationBar != null && mNavigationBar.isAlive())
+                                || (mNavigationBarAlt != null && mNavigationBarAlt.isAlive())) {
+                            return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
+                        }
+                        break;
+                }
+            }
         }
         return ADD_OKAY;
     }
@@ -1084,7 +1136,19 @@
                 break;
             default:
                 if (attrs.providesInsetsTypes != null) {
-                    for (int insetsType : attrs.providesInsetsTypes) {
+                    for (@InternalInsetsType int insetsType : attrs.providesInsetsTypes) {
+                        switch (insetsType) {
+                            case ITYPE_STATUS_BAR:
+                                mStatusBarAlt = win;
+                                mStatusBarController.setWindow(mStatusBarAlt);
+                                mStatusBarAltPosition = getAltBarPosition(attrs);
+                                break;
+                            case ITYPE_NAVIGATION_BAR:
+                                mNavigationBarAlt = win;
+                                mNavigationBarController.setWindow(mNavigationBarAlt);
+                                mNavigationBarAltPosition = getAltBarPosition(attrs);
+                                break;
+                        }
                         mDisplayContent.setInsetProvider(insetsType, win, null);
                     }
                 }
@@ -1092,6 +1156,22 @@
         }
     }
 
+    @WindowManagerPolicy.AltBarPosition
+    private int getAltBarPosition(WindowManager.LayoutParams params) {
+        switch (params.gravity) {
+            case Gravity.LEFT:
+                return ALT_BAR_LEFT;
+            case Gravity.RIGHT:
+                return ALT_BAR_RIGHT;
+            case Gravity.BOTTOM:
+                return ALT_BAR_BOTTOM;
+            case Gravity.TOP:
+                return ALT_BAR_TOP;
+            default:
+                return ALT_BAR_UNKNOWN;
+        }
+    }
+
     TriConsumer<DisplayFrames, WindowState, Rect> getImeSourceFrameProvider() {
         return (displayFrames, windowState, inOutFrame) -> {
             if (mNavigationBar != null && navigationBarPosition(displayFrames.mDisplayWidth,
@@ -1132,12 +1212,14 @@
      * @param win The window being removed.
      */
     void removeWindowLw(WindowState win) {
-        if (mStatusBar == win) {
+        if (mStatusBar == win || mStatusBarAlt == win) {
             mStatusBar = null;
+            mStatusBarAlt = null;
             mStatusBarController.setWindow(null);
             mDisplayContent.setInsetProvider(ITYPE_STATUS_BAR, null, null);
-        } else if (mNavigationBar == win) {
+        } else if (mNavigationBar == win || mNavigationBarAlt == win) {
             mNavigationBar = null;
+            mNavigationBarAlt = null;
             mNavigationBarController.setWindow(null);
             mDisplayContent.setInsetProvider(ITYPE_NAVIGATION_BAR, null, null);
         } else if (mNotificationShade == win) {
@@ -1163,7 +1245,7 @@
     }
 
     WindowState getStatusBar() {
-        return mStatusBar;
+        return mStatusBar != null ? mStatusBar : mStatusBarAlt;
     }
 
     WindowState getNotificationShade() {
@@ -1171,7 +1253,7 @@
     }
 
     WindowState getNavigationBar() {
-        return mNavigationBar;
+        return mNavigationBar != null ? mNavigationBar : mNavigationBarAlt;
     }
 
     /**
@@ -1233,6 +1315,46 @@
                     return R.anim.dock_left_enter;
                 }
             }
+        } else if (win == mStatusBarAlt || win == mNavigationBarAlt) {
+            if (win.getAttrs().windowAnimations != 0) {
+                return ANIMATION_STYLEABLE;
+            }
+
+            int pos = (win == mStatusBarAlt) ? mStatusBarAltPosition : mNavigationBarAltPosition;
+
+            boolean isExitOrHide = transit == TRANSIT_EXIT || transit == TRANSIT_HIDE;
+            boolean isEnterOrShow = transit == TRANSIT_ENTER || transit == TRANSIT_SHOW;
+
+            switch (pos) {
+                case ALT_BAR_LEFT:
+                    if (isExitOrHide) {
+                        return R.anim.dock_left_exit;
+                    } else if (isEnterOrShow) {
+                        return R.anim.dock_left_enter;
+                    }
+                    break;
+                case ALT_BAR_RIGHT:
+                    if (isExitOrHide) {
+                        return R.anim.dock_right_exit;
+                    } else if (isEnterOrShow) {
+                        return R.anim.dock_right_enter;
+                    }
+                    break;
+                case ALT_BAR_BOTTOM:
+                    if (isExitOrHide) {
+                        return R.anim.dock_bottom_exit;
+                    } else if (isEnterOrShow) {
+                        return R.anim.dock_bottom_enter;
+                    }
+                    break;
+                case ALT_BAR_TOP:
+                    if (isExitOrHide) {
+                        return R.anim.dock_top_exit;
+                    } else if (isEnterOrShow) {
+                        return R.anim.dock_top_enter;
+                    }
+                    break;
+            }
         }
 
         if (transit == TRANSIT_PREVIEW_DONE) {
@@ -1591,7 +1713,7 @@
                 mInputConsumer = null;
                 Slog.v(TAG, INPUT_CONSUMER_NAVIGATION + " dismissed.");
             }
-        } else if (mInputConsumer == null && mStatusBar != null && canHideNavigationBar()) {
+        } else if (mInputConsumer == null && getStatusBar() != null && canHideNavigationBar()) {
             mInputConsumer = mDisplayContent.getInputMonitor().createInputConsumer(
                     mHandler.getLooper(),
                     INPUT_CONSUMER_NAVIGATION,
@@ -2677,10 +2799,10 @@
             mDreamingLockscreen = mService.mPolicy.isKeyguardShowingAndNotOccluded();
         }
 
-        if (mStatusBar != null) {
+        if (getStatusBar() != null) {
             if (DEBUG_LAYOUT) Slog.i(TAG, "force=" + mForceStatusBar
                     + " top=" + mTopFullscreenOpaqueWindowState);
-            final boolean forceShowStatusBar = (mStatusBar.getAttrs().privateFlags
+            final boolean forceShowStatusBar = (getStatusBar().getAttrs().privateFlags
                     & PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR) != 0;
             final boolean notificationShadeForcesShowingNavigation =
                     mNotificationShade != null
@@ -3166,6 +3288,16 @@
         return mNavigationBarPosition;
     }
 
+    @WindowManagerPolicy.AltBarPosition
+    int getAlternateStatusBarPosition() {
+        return mStatusBarAltPosition;
+    }
+
+    @WindowManagerPolicy.AltBarPosition
+    int getAlternateNavBarPosition() {
+        return mNavigationBarAltPosition;
+    }
+
     /**
      * A new window has been focused.
      */
@@ -3327,8 +3459,8 @@
         final boolean isFullscreen = (visibility & (View.SYSTEM_UI_FLAG_FULLSCREEN
                         | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION)) != 0
                 || (PolicyControl.getWindowFlags(win, win.mAttrs) & FLAG_FULLSCREEN) != 0
-                || (mStatusBar != null && insetsPolicy.isHidden(ITYPE_STATUS_BAR))
-                || (mNavigationBar != null && insetsPolicy.isHidden(
+                || (getStatusBar() != null && insetsPolicy.isHidden(ITYPE_STATUS_BAR))
+                || (getNavigationBar() != null && insetsPolicy.isHidden(
                         ITYPE_NAVIGATION_BAR));
         final int behavior = win.mAttrs.insetsFlags.behavior;
         final boolean isImmersive = (visibility & (View.SYSTEM_UI_FLAG_IMMERSIVE
@@ -3583,7 +3715,7 @@
         final boolean hideNavBarSysui =
                 (vis & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0;
 
-        final boolean transientStatusBarAllowed = mStatusBar != null
+        final boolean transientStatusBarAllowed = getStatusBar() != null
                 && (notificationShadeHasFocus || (!mForceShowSystemBars
                 && (hideStatusBarWM || (hideStatusBarSysui && immersiveSticky))));
 
@@ -3741,7 +3873,7 @@
     // TODO(b/118118435): Remove this after migration
     private boolean isImmersiveMode(int vis) {
         final int flags = View.SYSTEM_UI_FLAG_IMMERSIVE | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
-        return mNavigationBar != null
+        return getNavigationBar() != null
                 && (vis & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0
                 && (vis & flags) != 0
                 && canHideNavigationBar();
@@ -3749,7 +3881,7 @@
 
     private boolean isImmersiveMode(WindowState win) {
         final int behavior = win.mAttrs.insetsFlags.behavior;
-        return mNavigationBar != null
+        return getNavigationBar() != null
                 && canHideNavigationBar()
                 && (behavior == BEHAVIOR_SHOW_BARS_BY_SWIPE
                         || behavior == BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE)
@@ -3830,8 +3962,8 @@
     public void takeScreenshot(int screenshotType, int source) {
         if (mScreenshotHelper != null) {
             mScreenshotHelper.takeScreenshot(screenshotType,
-                    mStatusBar != null && mStatusBar.isVisibleLw(),
-                    mNavigationBar != null && mNavigationBar.isVisibleLw(),
+                    getStatusBar() != null && getStatusBar().isVisibleLw(),
+                    getNavigationBar() != null && getNavigationBar().isVisibleLw(),
                     source, mHandler, null /* completionConsumer */);
         }
     }
@@ -3869,6 +4001,11 @@
         if (mStatusBar != null) {
             pw.print(prefix); pw.print("mStatusBar="); pw.print(mStatusBar);
         }
+        if (mStatusBarAlt != null) {
+            pw.print(prefix); pw.print("mStatusBarAlt="); pw.print(mStatusBarAlt);
+            pw.print(prefix); pw.print("mStatusBarAltPosition=");
+            pw.println(mStatusBarAltPosition);
+        }
         if (mNotificationShade != null) {
             pw.print(prefix); pw.print("mExpandedPanel="); pw.print(mNotificationShade);
         }
@@ -3880,6 +4017,11 @@
             pw.print(prefix); pw.print("mNavigationBarPosition=");
             pw.println(mNavigationBarPosition);
         }
+        if (mNavigationBarAlt != null) {
+            pw.print(prefix); pw.print("mNavigationBarAlt="); pw.println(mNavigationBarAlt);
+            pw.print(prefix); pw.print("mNavigationBarAltPosition=");
+            pw.println(mNavigationBarAltPosition);
+        }
         if (mFocusedWindow != null) {
             pw.print(prefix); pw.print("mFocusedWindow="); pw.println(mFocusedWindow);
         }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 3cfb5f7..b71fefc 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2163,6 +2163,10 @@
                     throw new IllegalArgumentException(
                             "Window type can not be changed after the window is added.");
                 }
+                if (!Arrays.equals(win.mAttrs.providesInsetsTypes, attrs.providesInsetsTypes)) {
+                    throw new IllegalArgumentException(
+                            "Insets types can not be changed after the window is added.");
+                }
 
                 // Odd choice but less odd than embedding in copyFrom()
                 if ((attrs.privateFlags & WindowManager.LayoutParams.PRIVATE_FLAG_PRESERVE_GEOMETRY)
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
index 278de56..2f3afbc 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
@@ -40,8 +40,13 @@
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;
+import static android.view.WindowManagerPolicyConstants.ALT_BAR_BOTTOM;
+import static android.view.WindowManagerPolicyConstants.ALT_BAR_LEFT;
+import static android.view.WindowManagerPolicyConstants.ALT_BAR_RIGHT;
+import static android.view.WindowManagerPolicyConstants.ALT_BAR_TOP;
 
 import static org.hamcrest.Matchers.is;
 import static org.junit.Assert.assertEquals;
@@ -60,6 +65,7 @@
 import android.util.SparseArray;
 import android.view.DisplayCutout;
 import android.view.DisplayInfo;
+import android.view.Gravity;
 import android.view.InsetsState;
 import android.view.WindowInsets.Side;
 import android.view.WindowInsets.Type;
@@ -147,6 +153,8 @@
 
     @Test
     public void addingWindow_withInsetsTypes() {
+        mDisplayPolicy.removeWindowLw(mStatusBarWindow);  // Removes the existing one.
+
         WindowState win = createWindow(null, TYPE_STATUS_BAR_SUB_PANEL, "StatusBarSubPanel");
         win.mAttrs.providesInsetsTypes = new int[]{ITYPE_STATUS_BAR, ITYPE_TOP_GESTURES};
         win.getFrameLw().set(0, 0, 500, 100);
@@ -196,6 +204,47 @@
     }
 
     @Test
+    public void addingWindow_variousGravities_alternateBarPosUpdated() {
+        mDisplayPolicy.removeWindowLw(mNavBarWindow);  // Removes the existing one.
+
+        WindowState win1 = createWindow(null, TYPE_NAVIGATION_BAR_PANEL, "NavBarPanel1");
+        win1.mAttrs.providesInsetsTypes = new int[]{ITYPE_NAVIGATION_BAR};
+        win1.mAttrs.gravity = Gravity.TOP;
+        win1.getFrameLw().set(0, 0, 200, 500);
+        addWindow(win1);
+
+        assertEquals(mDisplayPolicy.getAlternateNavBarPosition(), ALT_BAR_TOP);
+        mDisplayPolicy.removeWindowLw(win1);
+
+        WindowState win2 = createWindow(null, TYPE_NAVIGATION_BAR_PANEL, "NavBarPanel2");
+        win2.mAttrs.providesInsetsTypes = new int[]{ITYPE_NAVIGATION_BAR};
+        win2.mAttrs.gravity = Gravity.BOTTOM;
+        win2.getFrameLw().set(0, 0, 200, 500);
+        addWindow(win2);
+
+        assertEquals(mDisplayPolicy.getAlternateNavBarPosition(), ALT_BAR_BOTTOM);
+        mDisplayPolicy.removeWindowLw(win2);
+
+        WindowState win3 = createWindow(null, TYPE_NAVIGATION_BAR_PANEL, "NavBarPanel3");
+        win3.mAttrs.providesInsetsTypes = new int[]{ITYPE_NAVIGATION_BAR};
+        win3.mAttrs.gravity = Gravity.LEFT;
+        win3.getFrameLw().set(0, 0, 200, 500);
+        addWindow(win3);
+
+        assertEquals(mDisplayPolicy.getAlternateNavBarPosition(), ALT_BAR_LEFT);
+        mDisplayPolicy.removeWindowLw(win3);
+
+        WindowState win4 = createWindow(null, TYPE_NAVIGATION_BAR_PANEL, "NavBarPanel4");
+        win4.mAttrs.providesInsetsTypes = new int[]{ITYPE_NAVIGATION_BAR};
+        win4.mAttrs.gravity = Gravity.RIGHT;
+        win4.getFrameLw().set(0, 0, 200, 500);
+        addWindow(win4);
+
+        assertEquals(mDisplayPolicy.getAlternateNavBarPosition(), ALT_BAR_RIGHT);
+        mDisplayPolicy.removeWindowLw(win4);
+    }
+
+    @Test
     public void layoutWindowLw_fitStatusBars() {
         mWindow.mAttrs.setFitInsetsTypes(Type.statusBars());
         addWindow(mWindow);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ScreenDecorWindowTests.java b/services/tests/wmtests/src/com/android/server/wm/ScreenDecorWindowTests.java
index 31a102a..ef74861 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ScreenDecorWindowTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ScreenDecorWindowTests.java
@@ -25,8 +25,8 @@
 import static android.view.Gravity.LEFT;
 import static android.view.Gravity.RIGHT;
 import static android.view.Gravity.TOP;
-import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
-import static android.view.InsetsState.ITYPE_STATUS_BAR;
+import static android.view.InsetsState.ITYPE_CLIMATE_BAR;
+import static android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
@@ -190,7 +190,7 @@
 
     @Test
     public void testProvidesInsetsTypes() {
-        int[] providesInsetsTypes = new int[]{ITYPE_STATUS_BAR};
+        int[] providesInsetsTypes = new int[]{ITYPE_CLIMATE_BAR};
         final View win = createWindow("StatusBarSubPanel", TOP, MATCH_PARENT, mDecorThickness, RED,
                 FLAG_LAYOUT_IN_SCREEN, 0, providesInsetsTypes);
 
@@ -199,7 +199,7 @@
 
     private View createDecorWindow(int gravity, int width, int height) {
         int[] providesInsetsTypes =
-                new int[]{gravity == TOP ? ITYPE_STATUS_BAR : ITYPE_NAVIGATION_BAR};
+                new int[]{gravity == TOP ? ITYPE_CLIMATE_BAR : ITYPE_EXTRA_NAVIGATION_BAR};
         return createWindow("decorWindow", gravity, width, height, RED,
                 FLAG_LAYOUT_IN_SCREEN, PRIVATE_FLAG_IS_SCREEN_DECOR, providesInsetsTypes);
     }