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/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 61023be..3c85564 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -20,6 +20,8 @@
 import static com.android.launcher3.Utilities.getPointString;
 import static com.android.launcher3.config.FeatureFlags.ENABLE_FOUR_COLUMNS;
 import static com.android.launcher3.config.FeatureFlags.ENABLE_TWO_PANEL_HOME;
+import static com.android.launcher3.util.DisplayController.CHANGE_DENSITY;
+import static com.android.launcher3.util.DisplayController.CHANGE_SIZE;
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
 import static com.android.launcher3.util.PackageManagerHelper.getPackageFilter;
 
@@ -49,7 +51,6 @@
 
 import com.android.launcher3.graphics.IconShape;
 import com.android.launcher3.testing.TestProtocol;
-import com.android.launcher3.util.ConfigMonitor;
 import com.android.launcher3.util.DisplayController;
 import com.android.launcher3.util.DisplayController.Info;
 import com.android.launcher3.util.IntArray;
@@ -156,7 +157,6 @@
     public Rect defaultWidgetPadding;
 
     private final ArrayList<OnIDPChangeListener> mChangeListeners = new ArrayList<>();
-    private ConfigMonitor mConfigMonitor;
     private OverlayMonitor mOverlayMonitor;
 
     @VisibleForTesting
@@ -203,7 +203,12 @@
                 .putString(KEY_MIGRATION_SRC_WORKSPACE_SIZE, getPointString(numColumns, numRows))
                 .apply();
 
-        mConfigMonitor = new ConfigMonitor(context, this::onConfigChanged);
+        DisplayController.INSTANCE.get(context).addChangeListener(
+                (info, flags) -> {
+                    if ((flags & (CHANGE_SIZE | CHANGE_DENSITY)) != 0) {
+                        onConfigChanged(context);
+                    }
+                });
         mOverlayMonitor = new OverlayMonitor(context);
     }
 
@@ -227,7 +232,7 @@
 
         // Get the display info based on default display and interpolate it to existing display
         DisplayOption defaultDisplayOption = invDistWeightedInterpolate(
-                DisplayController.getDefaultDisplay(context).getInfo(),
+                DisplayController.INSTANCE.get(context).getInfo(),
                 getPredefinedDeviceProfiles(context, gridName));
 
         Info myInfo = new Info(context, display);
@@ -276,7 +281,7 @@
     }
 
     private String initGrid(Context context, String gridName) {
-        Info displayInfo = DisplayController.getDefaultDisplay(context).getInfo();
+        Info displayInfo = DisplayController.INSTANCE.get(context).getInfo();
         ArrayList<DisplayOption> allOptions = getPredefinedDeviceProfiles(context, gridName);
 
         DisplayOption displayOption = invDistWeightedInterpolate(displayInfo, allOptions);
@@ -286,6 +291,7 @@
 
     private void initGrid(
             Context context, Info displayInfo, DisplayOption displayOption) {
+        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
         GridOption closestProfile = displayOption.grid;
         numRows = closestProfile.numRows;
         numColumns = closestProfile.numColumns;
@@ -303,7 +309,7 @@
         iconSize = displayOption.iconSize;
         iconShapePath = getIconShapePath(context);
         landscapeIconSize = displayOption.landscapeIconSize;
-        iconBitmapSize = ResourceUtils.pxFromDp(iconSize, displayInfo.metrics);
+        iconBitmapSize = ResourceUtils.pxFromDp(iconSize, metrics);
         iconTextSize = displayOption.iconTextSize;
         landscapeIconTextSize = displayOption.landscapeIconTextSize;
         fillResIconDpi = getLauncherIconDensity(iconBitmapSize);
@@ -328,7 +334,7 @@
 
         // If the partner customization apk contains any grid overrides, apply them
         // Supported overrides: numRows, numColumns, iconSize
-        applyPartnerDeviceProfileOverrides(context, displayInfo.metrics);
+        applyPartnerDeviceProfileOverrides(context, metrics);
 
         Point realSize = new Point(displayInfo.realSize);
         // The real size never changes. smallSide and largeSide will remain the
@@ -425,10 +431,6 @@
     }
 
     private void apply(Context context, int changeFlags) {
-        // Create a new config monitor
-        mConfigMonitor.unregister();
-        mConfigMonitor = new ConfigMonitor(context, this::onConfigChanged);
-
         for (OnIDPChangeListener listener : mChangeListeners) {
             listener.onIdpChanged(changeFlags, this);
         }
@@ -530,10 +532,10 @@
         Point largestSize = new Point(displayInfo.largestSize);
 
         // This guarantees that width < height
-        float width = Utilities.dpiFromPx(Math.min(smallestSize.x, smallestSize.y),
-                displayInfo.metrics);
-        float height = Utilities.dpiFromPx(Math.min(largestSize.x, largestSize.y),
-                displayInfo.metrics);
+        float width = Utilities.dpiFromPx((float) Math.min(smallestSize.x, smallestSize.y),
+                displayInfo.densityDpi);
+        float height = Utilities.dpiFromPx((float) Math.min(largestSize.x, largestSize.y),
+                displayInfo.densityDpi);
 
         // Sort the profiles based on the closeness to the device size
         Collections.sort(points, (a, b) ->