Calculate StatusBar height locally in Launcher

When reading the status bar inset on devices with
multiple displays after switching the displays
the inset is not updated immediately (SystemUI
should update the height of the window first by
reacting to the display switch in it's own process).

Due to this race condition Launcher is very likely
to calculate DeviceProfile with incorrect inset
of the previous display first and update it to
the correct one only after SystemUI finished the
window update.

To avoid this adding calculation of the StatusBar
height to Launcher locally using the same utility
method that is used by SystemUI.

Bug: 264656380
Test: manual test that the statusbar height is calculated
 correctly in Launcher on a device with two displays, both on
 the inner and outer display and different rotations
Change-Id: Ia16ecadd8fcac29082d27ca693ab7740ce6161c4
diff --git a/quickstep/src/com/android/quickstep/util/SystemWindowManagerProxy.java b/quickstep/src/com/android/quickstep/util/SystemWindowManagerProxy.java
index 5dc4613..a34888f 100644
--- a/quickstep/src/com/android/quickstep/util/SystemWindowManagerProxy.java
+++ b/quickstep/src/com/android/quickstep/util/SystemWindowManagerProxy.java
@@ -23,6 +23,7 @@
 import android.view.WindowManager;
 import android.view.WindowMetrics;
 
+import com.android.internal.policy.SystemBarUtils;
 import com.android.launcher3.util.WindowBounds;
 import com.android.launcher3.util.window.CachedDisplayInfo;
 import com.android.launcher3.util.window.WindowManagerProxy;
@@ -45,6 +46,13 @@
     }
 
     @Override
+    protected int getStatusBarHeight(Context context, boolean isPortrait, int statusBarInset) {
+        // See b/264656380, calculate the status bar height manually as the inset in the system
+        // server might not be updated by this point yet causing extra DeviceProfile updates
+        return SystemBarUtils.getStatusBarHeight(context);
+    }
+
+    @Override
     public ArrayMap<CachedDisplayInfo, WindowBounds[]> estimateInternalDisplayBounds(
             Context displayInfoContext) {
         ArrayMap<CachedDisplayInfo, WindowBounds[]> result = new ArrayMap<>();
diff --git a/src/com/android/launcher3/util/window/WindowManagerProxy.java b/src/com/android/launcher3/util/window/WindowManagerProxy.java
index fb2ae73..4093bc9 100644
--- a/src/com/android/launcher3/util/window/WindowManagerProxy.java
+++ b/src/com/android/launcher3/util/window/WindowManagerProxy.java
@@ -161,12 +161,10 @@
         insetsBuilder.setInsetsIgnoringVisibility(WindowInsets.Type.navigationBars(), newNavInsets);
 
         Insets statusBarInsets = oldInsets.getInsets(WindowInsets.Type.statusBars());
-        int statusBarHeight = getDimenByName(systemRes,
-                (isPortrait) ? STATUS_BAR_HEIGHT_PORTRAIT : STATUS_BAR_HEIGHT_LANDSCAPE,
-                STATUS_BAR_HEIGHT);
+
         Insets newStatusBarInsets = Insets.of(
                 statusBarInsets.left,
-                Math.max(statusBarInsets.top, statusBarHeight),
+                getStatusBarHeight(context, isPortrait, statusBarInsets.top),
                 statusBarInsets.right,
                 statusBarInsets.bottom);
         insetsBuilder.setInsets(WindowInsets.Type.statusBars(), newStatusBarInsets);
@@ -190,6 +188,15 @@
         return result;
     }
 
+    protected int getStatusBarHeight(Context context, boolean isPortrait, int statusBarInset) {
+        Resources systemRes = context.getResources();
+        int statusBarHeight = getDimenByName(systemRes,
+                isPortrait ? STATUS_BAR_HEIGHT_PORTRAIT : STATUS_BAR_HEIGHT_LANDSCAPE,
+                STATUS_BAR_HEIGHT);
+
+        return Math.max(statusBarInset, statusBarHeight);
+    }
+
     /**
      * Returns a list of possible WindowBounds for the display keyed on the 4 surface rotations
      */
@@ -212,6 +219,9 @@
         boolean isTabletOrGesture = isTablet
                 || (Utilities.ATLEAST_R && isGestureNav(context));
 
+        // Use the status bar height resources because current system API to get the status bar
+        // height doesn't allow to do this for an arbitrary display, it returns value only
+        // for the current active display (see com.android.internal.policy.StatusBarUtils)
         int statusBarHeightPortrait = getDimenByName(systemRes,
                 STATUS_BAR_HEIGHT_PORTRAIT, STATUS_BAR_HEIGHT);
         int statusBarHeightLandscape = getDimenByName(systemRes,