Merge "Update density util to allow calling the util for external displays." into main
diff --git a/packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java b/packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java
index 58e9355..985599c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java
@@ -57,7 +57,7 @@
      * Summaries for scales smaller than "default" in order of smallest to
      * largest.
      */
-    private static final int[] SUMMARIES_SMALLER = new int[] {
+    private static final int[] SUMMARIES_SMALLER = new int[]{
             R.string.screen_zoom_summary_small
     };
 
@@ -65,7 +65,7 @@
      * Summaries for scales larger than "default" in order of smallest to
      * largest.
      */
-    private static final int[] SUMMARIES_LARGER = new int[] {
+    private static final int[] SUMMARIES_LARGER = new int[]{
             R.string.screen_zoom_summary_large,
             R.string.screen_zoom_summary_very_large,
             R.string.screen_zoom_summary_extremely_large,
@@ -108,7 +108,8 @@
      * Creates an instance that stores the density values for the smallest display that satisfies
      * the predicate. It is enough to store the values for one display because the same density
      * should be set to all the displays that satisfy the predicate.
-     * @param context The context
+     *
+     * @param context   The context
      * @param predicate Determines what displays the density should be set for. The default display
      *                  must satisfy this predicate.
      */
@@ -127,14 +128,10 @@
             mCurrentIndex = -1;
             return;
         }
-        if (!mPredicate.test(defaultDisplayInfo)) {
-            throw new IllegalArgumentException(
-                    "Predicate must not filter out the default display.");
-        }
 
-        int idOfSmallestDisplay = Display.DEFAULT_DISPLAY;
-        int minDimensionPx = Math.min(defaultDisplayInfo.logicalWidth,
-                defaultDisplayInfo.logicalHeight);
+        int idOfSmallestDisplay = Display.INVALID_DISPLAY;
+        int minDimensionPx = Integer.MAX_VALUE;
+        DisplayInfo smallestDisplayInfo = null;
         for (Display display : mDisplayManager.getDisplays(
                 DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED)) {
             DisplayInfo info = new DisplayInfo();
@@ -149,9 +146,19 @@
             if (minDimension < minDimensionPx) {
                 minDimensionPx = minDimension;
                 idOfSmallestDisplay = display.getDisplayId();
+                smallestDisplayInfo = info;
             }
         }
 
+        if (smallestDisplayInfo == null) {
+            Log.w(LOG_TAG, "No display satisfies the predicate");
+            mEntries = null;
+            mValues = null;
+            mDefaultDensity = 0;
+            mCurrentIndex = -1;
+            return;
+        }
+
         final int defaultDensity =
                 DisplayDensityUtils.getDefaultDensityForDisplay(idOfSmallestDisplay);
         if (defaultDensity <= 0) {
@@ -165,7 +172,12 @@
 
         final Resources res = context.getResources();
 
-        final int currentDensity = defaultDisplayInfo.logicalDensityDpi;
+        int currentDensity;
+        if (mPredicate.test(defaultDisplayInfo)) {
+            currentDensity = defaultDisplayInfo.logicalDensityDpi;
+        } else {
+            currentDensity = smallestDisplayInfo.logicalDensityDpi;
+        }
         int currentDensityIndex = -1;
 
         // Compute number of "larger" and "smaller" scales for this display.
@@ -266,16 +278,16 @@
      * Returns the default density for the specified display.
      *
      * @param displayId the identifier of the display
-     * @return the default density of the specified display, or {@code -1} if
-     *         the display does not exist or the density could not be obtained
+     * @return the default density of the specified display, or {@code -1} if the display does not
+     * exist or the density could not be obtained
      */
     private static int getDefaultDensityForDisplay(int displayId) {
-       try {
-           final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
-           return wm.getInitialDisplayDensity(displayId);
-       } catch (RemoteException exc) {
-           return -1;
-       }
+        try {
+            final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
+            return wm.getInitialDisplayDensity(displayId);
+        } catch (RemoteException exc) {
+            return -1;
+        }
     }
 
     /**
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/display/DisplayDensityUtilsTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/display/DisplayDensityUtilsTest.java
index bba278a..73cf28f 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/display/DisplayDensityUtilsTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/display/DisplayDensityUtilsTest.java
@@ -88,8 +88,8 @@
 
     @Test
     public void createDisplayDensityUtil_onlyDefaultDisplay() throws RemoteException {
-        var info = createDisplayInfoForDisplay(Display.DEFAULT_DISPLAY, Display.TYPE_INTERNAL, 2560,
-                1600, 320);
+        var info = createDisplayInfoForDisplay(
+                Display.DEFAULT_DISPLAY, Display.TYPE_INTERNAL, 2560, 1600, 320);
         var display = new Display(mDisplayManagerGlobal, info.displayId, info,
                 (DisplayAdjustments) null);
         doReturn(new Display[]{display}).when(mDisplayManager).getDisplays(any());
@@ -126,6 +126,33 @@
         assertThat(mDisplayDensityUtils.getValues()).isEqualTo(new int[]{330, 390, 426, 462, 500});
     }
 
+    @Test
+    public void createDisplayDensityUtil_forExternalDisplay() throws RemoteException {
+        // Default display
+        var defaultDisplayInfo = createDisplayInfoForDisplay(Display.DEFAULT_DISPLAY,
+                Display.TYPE_INTERNAL, 2000, 2000, 390);
+        var defaultDisplay = new Display(mDisplayManagerGlobal, defaultDisplayInfo.displayId,
+                defaultDisplayInfo,
+                (DisplayAdjustments) null);
+        doReturn(defaultDisplay).when(mDisplayManager).getDisplay(defaultDisplayInfo.displayId);
+
+        // Create external display
+        var externalDisplayInfo = createDisplayInfoForDisplay(/* displayId= */ 2,
+                Display.TYPE_EXTERNAL, 1920, 1080, 85);
+        var externalDisplay = new Display(mDisplayManagerGlobal, externalDisplayInfo.displayId,
+                externalDisplayInfo,
+                (DisplayAdjustments) null);
+
+        doReturn(new Display[]{externalDisplay, defaultDisplay}).when(mDisplayManager).getDisplays(
+                any());
+        doReturn(externalDisplay).when(mDisplayManager).getDisplay(externalDisplayInfo.displayId);
+
+        mDisplayDensityUtils = new DisplayDensityUtils(mContext,
+                (info) -> info.displayId == externalDisplayInfo.displayId);
+
+        assertThat(mDisplayDensityUtils.getValues()).isEqualTo(new int[]{72, 85, 94, 102, 112});
+    }
+
     private DisplayInfo createDisplayInfoForDisplay(int displayId, int displayType,
             int width, int height, int density) throws RemoteException {
         var displayInfo = new DisplayInfo();