Using WindowContext for listening to configuration changes

Pre-S: Continue to use config-changed broadcast for configuration changes
and display-changed event for rotation changes
S+: Use WindowContext#componentCallbacks for config and rotation changes, and
continue to use display listener for frame-rate changes

Bug: 179308296
Test: Manual and presubmit
Change-Id: I533e69068b5fa6c052a02759ef309dd075ee6a4b
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index dae4f3b..a6fc0f3 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -16,15 +16,20 @@
 
 package com.android.launcher3;
 
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+
 import static com.android.launcher3.ResourceUtils.pxFromDp;
 import static com.android.launcher3.Utilities.dpiFromPx;
 
+import android.annotation.SuppressLint;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
+import android.hardware.display.DisplayManager;
+import android.util.DisplayMetrics;
 import android.util.Log;
 import android.view.Surface;
 import android.view.WindowInsets;
@@ -43,6 +48,7 @@
 
 import java.io.PrintWriter;
 
+@SuppressLint("NewApi")
 public class DeviceProfile {
 
     private static final float TABLET_MIN_DPS = 600;
@@ -51,6 +57,7 @@
 
     public final InvariantDeviceProfile inv;
     private final Info mInfo;
+    private final DisplayMetrics mMetrics;
 
     // Device properties
     public final boolean isTablet;
@@ -214,7 +221,8 @@
         mInfo = info;
 
         // Constants from resources
-        float swDPs = dpiFromPx(Math.min(info.smallestSize.x, info.smallestSize.y), info.metrics);
+        float swDPs = dpiFromPx(Math.min(info.smallestSize.x, info.smallestSize.y),
+                info.densityDpi);
         boolean allowRotation = context.getResources().getBoolean(R.bool.allow_rotation);
         // Tablet UI is built with assumption that simulated landscape is disabled.
         isTablet = allowRotation && swDPs >= TABLET_MIN_DPS;
@@ -227,6 +235,7 @@
         context = getContext(context, info, isVerticalBarLayout()
                 ? Configuration.ORIENTATION_LANDSCAPE
                 : Configuration.ORIENTATION_PORTRAIT);
+        mMetrics = context.getResources().getDisplayMetrics();
         final Resources res = context.getResources();
 
         isTaskbarPresent = isTablet && FeatureFlags.ENABLE_TASKBAR.get();
@@ -234,11 +243,13 @@
             // Taskbar will be added later, but provides bottom insets that we should subtract
             // from availableHeightPx.
             taskbarSize = res.getDimensionPixelSize(R.dimen.taskbar_size);
-            WindowInsets windowInsets = DisplayController.INSTANCE.get(context).getHolder(mInfo.id)
-                    .getDisplayContext().getSystemService(WindowManager.class)
+            WindowInsets windowInsets =
+                    context.createWindowContext(
+                            context.getSystemService(DisplayManager.class).getDisplay(mInfo.id),
+                            TYPE_APPLICATION, null)
+                    .getSystemService(WindowManager.class)
                     .getCurrentWindowMetrics().getWindowInsets();
-            nonOverlappingTaskbarInset =
-                    taskbarSize - windowInsets.getSystemWindowInsetBottom();
+            nonOverlappingTaskbarInset = taskbarSize - windowInsets.getSystemWindowInsetBottom();
             if (nonOverlappingTaskbarInset > 0) {
                 nonFinalAvailableHeightPx -= nonOverlappingTaskbarInset;
             }
@@ -261,7 +272,7 @@
                 res.getDimensionPixelSize(R.dimen.folder_content_padding_left_right);
         folderContentPaddingTop = res.getDimensionPixelSize(R.dimen.folder_content_padding_top);
 
-        setCellLayoutBorderSpacing(pxFromDp(inv.borderSpacing, mInfo.metrics, 1f));
+        setCellLayoutBorderSpacing(pxFromDp(inv.borderSpacing, mMetrics, 1f));
         cellLayoutBorderSpacingOriginalPx = cellLayoutBorderSpacingPx;
         folderCellLayoutBorderSpacingPx = cellLayoutBorderSpacingPx;
 
@@ -308,7 +319,7 @@
         hotseatBarSidePaddingStartPx = isVerticalBarLayout() ? workspacePageIndicatorHeight : 0;
         int hotseatExtraVerticalSize =
                 res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_extra_vertical_size);
-        hotseatBarSizePx = pxFromDp(inv.iconSize, mInfo.metrics, 1f)
+        hotseatBarSizePx = pxFromDp(inv.iconSize, mMetrics, 1f)
                 + (isVerticalBarLayout()
                 ? (hotseatBarSidePaddingStartPx + hotseatBarSidePaddingEndPx)
                 : (hotseatBarTopPaddingPx + hotseatBarBottomPaddingPx
@@ -511,16 +522,16 @@
         // Workspace
         final boolean isVerticalLayout = isVerticalBarLayout();
         float invIconSizeDp = isLandscape ? inv.landscapeIconSize : inv.iconSize;
-        iconSizePx = Math.max(1, pxFromDp(invIconSizeDp, mInfo.metrics, scale));
+        iconSizePx = Math.max(1, pxFromDp(invIconSizeDp, mMetrics, scale));
         float invIconTextSizeSp = isLandscape ? inv.landscapeIconTextSize : inv.iconTextSize;
-        iconTextSizePx = (int) (Utilities.pxFromSp(invIconTextSizeSp, mInfo.metrics) * scale);
+        iconTextSizePx = (int) (Utilities.pxFromSp(invIconTextSizeSp, mMetrics) * scale);
         iconDrawablePaddingPx = (int) (iconDrawablePaddingOriginalPx * scale);
 
         setCellLayoutBorderSpacing((int) (cellLayoutBorderSpacingOriginalPx * scale));
 
         if (isScalableGrid) {
-            cellWidthPx = pxFromDp(inv.minCellWidth, mInfo.metrics, scale);
-            cellHeightPx = pxFromDp(inv.minCellHeight, mInfo.metrics, scale);
+            cellWidthPx = pxFromDp(inv.minCellWidth, mMetrics, scale);
+            cellHeightPx = pxFromDp(inv.minCellHeight, mMetrics, scale);
             int cellContentHeight = iconSizePx + iconDrawablePaddingPx
                     + Utilities.calculateTextHeight(iconTextSizePx);
             cellYPaddingPx = Math.max(0, cellHeightPx - cellContentHeight) / 2;
@@ -542,8 +553,8 @@
 
         // All apps
         if (allAppsHasDifferentNumColumns()) {
-            allAppsIconSizePx = pxFromDp(inv.allAppsIconSize, mInfo.metrics);
-            allAppsIconTextSizePx = Utilities.pxFromSp(inv.allAppsIconTextSize, mInfo.metrics);
+            allAppsIconSizePx = pxFromDp(inv.allAppsIconSize, mMetrics);
+            allAppsIconTextSizePx = Utilities.pxFromSp(inv.allAppsIconTextSize, mMetrics);
             allAppsIconDrawablePaddingPx = iconDrawablePaddingOriginalPx;
             autoResizeAllAppsCells();
         } else {
@@ -613,8 +624,8 @@
 
     private void updateFolderCellSize(float scale, Resources res) {
         float invIconSizeDp = isVerticalBarLayout() ? inv.landscapeIconSize : inv.iconSize;
-        folderChildIconSizePx = Math.max(1, pxFromDp(invIconSizeDp, mInfo.metrics, scale));
-        folderChildTextSizePx = pxFromDp(inv.iconTextSize, mInfo.metrics, scale);
+        folderChildIconSizePx = Math.max(1, pxFromDp(invIconSizeDp, mMetrics, scale));
+        folderChildTextSizePx = pxFromDp(inv.iconTextSize, mMetrics, scale);
         folderLabelTextSizePx = (int) (folderChildTextSizePx * folderLabelTextScale);
 
         int textHeight = Utilities.calculateTextHeight(folderChildTextSizePx);
@@ -801,14 +812,8 @@
      */
     public boolean updateIsSeascape(Context context) {
         if (isVerticalBarLayout()) {
-            // Check an up-to-date info.
-            DisplayController.Info displayInfo = DisplayController.getDefaultDisplay(context)
-                    .createInfoForContext(context);
-            if (displayInfo == null) {
-                return false;
-            }
-
-            boolean isSeascape = displayInfo.rotation == Surface.ROTATION_270;
+            boolean isSeascape = DisplayController.INSTANCE.get(context)
+                    .getInfo().rotation == Surface.ROTATION_270;
             if (mIsSeascape != isSeascape) {
                 mIsSeascape = isSeascape;
                 return true;
@@ -840,12 +845,12 @@
     }
 
     private String pxToDpStr(String name, float value) {
-        return "\t" + name + ": " + value + "px (" + dpiFromPx(value, mInfo.metrics) + "dp)";
+        return "\t" + name + ": " + value + "px (" + dpiFromPx(value, mMetrics.densityDpi) + "dp)";
     }
 
     public void dump(String prefix, PrintWriter writer) {
         writer.println(prefix + "DeviceProfile:");
-        writer.println(prefix + "\t1 dp = " + mInfo.metrics.density + " px");
+        writer.println(prefix + "\t1 dp = " + mMetrics.density + " px");
 
         writer.println(prefix + "\tisTablet:" + isTablet);
         writer.println(prefix + "\tisLargeTablet:" + isLargeTablet);
@@ -938,7 +943,7 @@
     private static Context getContext(Context c, Info info, int orientation) {
         Configuration config = new Configuration(c.getResources().getConfiguration());
         config.orientation = orientation;
-        config.densityDpi = info.metrics.densityDpi;
+        config.densityDpi = info.densityDpi;
         return c.createConfigurationContext(config);
     }