Support odd (that is, non-even) densities in several drawable tests

Bug: 35385573
Test: cts-tradefed run singleCommand cts-dev --module CtsGraphicsTestCases

Change-Id: I935320fbb3a3d9fc27ac63b82ea98fdc53b47098
Merged-In: Ia54804687657418875fbfcd08fcc74fcacac2ce9
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedStateListDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedStateListDrawableTest.java
index 1bdac0a..02421a6 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedStateListDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedStateListDrawableTest.java
@@ -192,9 +192,11 @@
         DrawableTestUtils.setResourcesDensity(res, densityDpi / 2);
         final StateListDrawable halfDrawable =
                 (StateListDrawable) cs.newDrawable(res);
+        // NOTE: densityDpi may not be an even number, so account for *actual* scaling in asserts
+        final float approxHalf = (float)(densityDpi / 2) / densityDpi;
         for (int i = 0; i < count; i++) {
             halfDrawable.selectDrawable(i);
-            assertEquals(Math.round(origWidth[i] / 2f), halfDrawable.getIntrinsicWidth());
+            assertEquals(Math.round(origWidth[i] * approxHalf), halfDrawable.getIntrinsicWidth());
         }
 
         // Set density to double original.
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/InsetDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/InsetDrawableTest.java
index 68223a0..81f774b 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/InsetDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/InsetDrawableTest.java
@@ -360,21 +360,29 @@
 
 
     public void testPreloadDensity() throws XmlPullParserException, IOException {
-        final Resources res = getContext().getResources();
+        final Resources res = mContext.getResources();
         final int densityDpi = res.getConfiguration().densityDpi;
         try {
-            testPreloadDensityInner(res);
+            DrawableTestUtils.setResourcesDensity(res, densityDpi);
+            verifyPreloadDensityInner(res, densityDpi);
         } finally {
             DrawableTestUtils.setResourcesDensity(res, densityDpi);
         }
     }
 
-    private void testPreloadDensityInner(Resources res) throws XmlPullParserException, IOException {
-        // Set density to a fixed value so that we're not affected by the
-        // device's native density.
-        final int densityDpi = DisplayMetrics.DENSITY_MEDIUM;
-        DrawableTestUtils.setResourcesDensity(res, densityDpi);
+    public void testPreloadDensity_tvdpi() throws XmlPullParserException, IOException {
+        final Resources res = mContext.getResources();
+        final int densityDpi = res.getConfiguration().densityDpi;
+        try {
+            DrawableTestUtils.setResourcesDensity(res, 213);
+            verifyPreloadDensityInner(res, 213);
+        } finally {
+            DrawableTestUtils.setResourcesDensity(res, densityDpi);
+        }
+    }
 
+    private void verifyPreloadDensityInner(Resources res, int densityDpi)
+            throws XmlPullParserException, IOException {
         // Capture initial state at default density.
         final XmlResourceParser parser = DrawableTestUtils.getResourceParser(
                 res, R.drawable.inset_density);
@@ -384,12 +392,14 @@
         final int origInsetHoriz = preloadedDrawable.getIntrinsicWidth()
                 - preloadedDrawable.getDrawable().getIntrinsicWidth();
 
-        // Set density to half of original. Unlike offsets, which are
+        // Set density to approximately half of original. Unlike offsets, which are
         // truncated, dimensions are rounded to the nearest pixel.
         DrawableTestUtils.setResourcesDensity(res, densityDpi / 2);
         final InsetDrawable halfDrawable =
                 (InsetDrawable) preloadedConstantState.newDrawable(res);
-        assertEquals(Math.round(origInsetHoriz / 2f), halfDrawable.getIntrinsicWidth()
+        // NOTE: densityDpi may not be an even number, so account for *actual* scaling in asserts
+        final float approxHalf = (float)(densityDpi / 2) / densityDpi;
+        assertEquals(Math.round(origInsetHoriz * approxHalf), halfDrawable.getIntrinsicWidth()
                 - halfDrawable.getDrawable().getIntrinsicWidth());
 
         // Set density to double original.
@@ -409,8 +419,10 @@
         // Ensure theme density is applied correctly.
         final Theme t = res.newTheme();
         halfDrawable.applyTheme(t);
-        assertEquals(origInsetHoriz, halfDrawable.getIntrinsicWidth()
-                - halfDrawable.getDrawable().getIntrinsicWidth());
+        float approxDouble = 1 / approxHalf;
+        // Reproduce imprecise truncated scale down, and back up. Note that we don't round.
+        assertEquals((int)(approxDouble * ((int)(origInsetHoriz * approxHalf))),
+                halfDrawable.getIntrinsicWidth() - halfDrawable.getDrawable().getIntrinsicWidth());
         doubleDrawable.applyTheme(t);
         assertEquals(origInsetHoriz, doubleDrawable.getIntrinsicWidth()
                 - doubleDrawable.getDrawable().getIntrinsicWidth());
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/LayerDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/LayerDrawableTest.java
index 5a0a125..5539eed 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/LayerDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/LayerDrawableTest.java
@@ -1690,21 +1690,29 @@
 
 
     public void testPreloadDensity() throws XmlPullParserException, IOException {
-        final Resources res = getContext().getResources();
+        final Resources res = mContext.getResources();
         final int densityDpi = res.getConfiguration().densityDpi;
         try {
-            testPreloadDensityInner(res);
+            DrawableTestUtils.setResourcesDensity(res, densityDpi);
+            verifyPreloadDensityInner(res, densityDpi);
         } finally {
             DrawableTestUtils.setResourcesDensity(res, densityDpi);
         }
     }
 
-    private void testPreloadDensityInner(Resources res) throws XmlPullParserException, IOException {
-        // Set density to a fixed value so that we're not affected by the
-        // device's native density.
-        final int densityDpi = DisplayMetrics.DENSITY_MEDIUM;
-        DrawableTestUtils.setResourcesDensity(res, densityDpi);
+    public void testPreloadDensity_tvdpi() throws XmlPullParserException, IOException {
+        final Resources res = mContext.getResources();
+        final int densityDpi = res.getConfiguration().densityDpi;
+        try {
+            DrawableTestUtils.setResourcesDensity(res, 213);
+            verifyPreloadDensityInner(res, 213);
+        } finally {
+            DrawableTestUtils.setResourcesDensity(res, densityDpi);
+        }
+    }
 
+    private void verifyPreloadDensityInner(Resources res, int densityDpi)
+            throws XmlPullParserException, IOException {
         // Capture initial state at default density.
         final XmlResourceParser parser = DrawableTestUtils.getResourceParser(
                 res, R.drawable.layer_drawable_density);
@@ -1733,11 +1741,13 @@
         DrawableTestUtils.setResourcesDensity(res, densityDpi / 2);
         final LayerDrawable halfDrawable =
                 (LayerDrawable) preloadedConstantState.newDrawable(res);
-        final int halfContentWidth = Math.round(initialContentWidth / 2f);
-        final int halfLeftPadding = initialLeftPadding / 2;
-        final int halfRightPadding = initialRightPadding / 2;
-        final int halfContentInsetL = initialContentInsetL / 2;
-        final int halfContentInsetR = initialContentInsetR / 2;
+        // NOTE: densityDpi may not be an even number, so account for *actual* scaling in asserts
+        final float approxHalf = (float)(densityDpi / 2) / densityDpi;
+        final int halfContentWidth = Math.round(initialContentWidth * approxHalf);
+        final int halfLeftPadding = (int) (initialLeftPadding * approxHalf);
+        final int halfRightPadding = (int) (initialRightPadding * approxHalf);
+        final int halfContentInsetL = (int) (initialContentInsetL * approxHalf);
+        final int halfContentInsetR = (int) (initialContentInsetR * approxHalf);
         final int halfIntrinsicWidth = halfContentWidth + halfContentInsetL + halfContentInsetR;
         assertEquals(halfLeftPadding, halfDrawable.getLeftPadding());
         assertEquals(halfRightPadding, halfDrawable.getRightPadding());
@@ -1745,14 +1755,18 @@
         assertEquals(halfContentInsetR, halfDrawable.getLayerInsetLeft(0));
         assertEquals(halfContentWidth, halfDrawable.getLayerWidth(0));
         assertEquals(halfIntrinsicWidth, halfDrawable.getIntrinsicWidth());
-        assertEquals(initialBottomPadding / 2, halfDrawable.getBottomPadding());
-        assertEquals(initialTopPadding / 2, halfDrawable.getTopPadding());
-        assertEquals(initialLayerInsetLeft / 2,halfDrawable.getLayerInsetLeft(0));
-        assertEquals(initialLayerInsetRight / 2, halfDrawable.getLayerInsetRight(0));
-        assertEquals(initialLayerInsetTop / 2, halfDrawable.getLayerInsetTop(0));
-        assertEquals(initialLayerInsetBottom / 2, halfDrawable.getLayerInsetBottom(0));
-        assertEquals(Math.round(initialLayerWidth / 2f), halfDrawable.getLayerWidth(0));
-        assertEquals(Math.round(initialLayerHeight / 2f), halfDrawable.getLayerHeight(0));
+        assertEquals((int) (initialBottomPadding * approxHalf), halfDrawable.getBottomPadding());
+        assertEquals((int) (initialTopPadding * approxHalf), halfDrawable.getTopPadding());
+        assertEquals((int) (initialLayerInsetLeft * approxHalf),
+                halfDrawable.getLayerInsetLeft(0));
+        assertEquals((int) (initialLayerInsetRight * approxHalf),
+                halfDrawable.getLayerInsetRight(0));
+        assertEquals((int) (initialLayerInsetTop * approxHalf),
+                halfDrawable.getLayerInsetTop(0));
+        assertEquals((int) (initialLayerInsetBottom * approxHalf),
+                halfDrawable.getLayerInsetBottom(0));
+        assertEquals(Math.round(initialLayerWidth * approxHalf), halfDrawable.getLayerWidth(0));
+        assertEquals(Math.round(initialLayerHeight * approxHalf), halfDrawable.getLayerHeight(0));
 
         // Set density to double original.
         DrawableTestUtils.setResourcesDensity(res, densityDpi * 2);
@@ -1798,20 +1812,31 @@
         // The half-density drawable will scale-up all of the values that were
         // previously scaled-down, so we need to capture the rounding errors.
         halfDrawable.applyTheme(t);
-        assertEquals(halfLeftPadding * 2, halfDrawable.getLeftPadding());
-        assertEquals(halfRightPadding * 2, halfDrawable.getRightPadding());
-        assertEquals(halfContentInsetL * 2, halfDrawable.getLayerInsetRight(0));
-        assertEquals(halfContentInsetR * 2, halfDrawable.getLayerInsetLeft(0));
-        assertEquals(halfContentWidth * 2, halfDrawable.getLayerWidth(0));
+
+        // Reproduce imprecise truncated scale down, and back up. Note that we don't round.
+        float approxDouble = 1 / approxHalf;
+        assertEquals((int) (halfLeftPadding * approxDouble), halfDrawable.getLeftPadding());
+        assertEquals((int) (halfRightPadding * approxDouble), halfDrawable.getRightPadding());
+        assertEquals((int) (halfContentInsetL * approxDouble), halfDrawable.getLayerInsetRight(0));
+        assertEquals((int) (halfContentInsetR * approxDouble), halfDrawable.getLayerInsetLeft(0));
+        assertEquals((int) (halfContentWidth * approxDouble), halfDrawable.getLayerWidth(0));
         assertEquals(halfIntrinsicWidth * 2, halfDrawable.getIntrinsicWidth());
-        assertEquals(2 * (initialBottomPadding / 2), halfDrawable.getBottomPadding());
-        assertEquals(2 * (initialTopPadding / 2), halfDrawable.getTopPadding());
-        assertEquals(2 * (initialLayerInsetLeft / 2), halfDrawable.getLayerInsetLeft(0));
-        assertEquals(2 * (initialLayerInsetRight / 2), halfDrawable.getLayerInsetRight(0));
-        assertEquals(2 * (initialLayerInsetTop / 2), halfDrawable.getLayerInsetTop(0));
-        assertEquals(2 * (initialLayerInsetBottom / 2), halfDrawable.getLayerInsetBottom(0));
-        assertEquals(2 * Math.round(initialLayerWidth / 2f), halfDrawable.getLayerWidth(0));
-        assertEquals(2 * Math.round(initialLayerHeight / 2f), halfDrawable.getLayerHeight(0));
+        assertEquals((int) ((int) (initialBottomPadding * approxHalf) * approxDouble),
+                halfDrawable.getBottomPadding());
+        assertEquals((int) ((int) (initialTopPadding * approxHalf) * approxDouble),
+                halfDrawable.getTopPadding());
+        assertEquals((int) ((int) (initialLayerInsetLeft * approxHalf) * approxDouble),
+                halfDrawable.getLayerInsetLeft(0));
+        assertEquals((int) ((int) (initialLayerInsetRight * approxHalf) * approxDouble),
+                halfDrawable.getLayerInsetRight(0));
+        assertEquals((int) ((int) (initialLayerInsetTop * approxHalf) * approxDouble),
+                halfDrawable.getLayerInsetTop(0));
+        assertEquals((int) ((int) (initialLayerInsetBottom * approxHalf) * approxDouble),
+                halfDrawable.getLayerInsetBottom(0));
+        assertEquals(Math.round(Math.round(initialLayerWidth * approxHalf) * approxDouble),
+                halfDrawable.getLayerWidth(0));
+        assertEquals(Math.round(Math.round(initialLayerHeight * approxHalf) * approxDouble),
+                halfDrawable.getLayerHeight(0));
 
         // The double-density drawable will scale-down all of the values that
         // were previously scaled-up, so we don't need to worry about rounding.
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/StateListDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/StateListDrawableTest.java
index b9f59cd..8876dc3 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/StateListDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/StateListDrawableTest.java
@@ -210,10 +210,12 @@
         DrawableTestUtils.setResourcesDensity(res, densityDpi / 2);
         final StateListDrawable halfDrawable =
                 (StateListDrawable) preloadedConstantState.newDrawable(res);
+        // NOTE: densityDpi may not be an even number, so account for *actual* scaling in asserts
+        final float approxHalf = (float)(densityDpi / 2) / densityDpi;
         halfDrawable.selectDrawable(0);
-        assertEquals(Math.round(origWidth0 / 2f), halfDrawable.getIntrinsicWidth());
+        assertEquals(Math.round(origWidth0 * approxHalf), halfDrawable.getIntrinsicWidth());
         halfDrawable.selectDrawable(1);
-        assertEquals(Math.round(origWidth1 / 2f), halfDrawable.getIntrinsicWidth());
+        assertEquals(Math.round(origWidth1 * approxHalf), halfDrawable.getIntrinsicWidth());
 
         // Set density to double original.
         DrawableTestUtils.setResourcesDensity(res, densityDpi * 2);
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/VectorDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/VectorDrawableTest.java
index 7d08519..eb02c24 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/VectorDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/VectorDrawableTest.java
@@ -417,17 +417,6 @@
     }
 
     @SmallTest
-    public void testPreloadDensity() throws XmlPullParserException, IOException {
-        final Resources res = getContext().getResources();
-        final int densityDpi = res.getConfiguration().densityDpi;
-        try {
-            testPreloadDensityInner(res);
-        } finally {
-            DrawableTestUtils.setResourcesDensity(res, densityDpi);
-        }
-    }
-
-    @SmallTest
     public void testGetOpacity() throws XmlPullParserException, IOException {
         VectorDrawable vectorDrawable = new VectorDrawable();
 
@@ -441,12 +430,30 @@
                 vectorDrawable.getOpacity());
     }
 
-    private void testPreloadDensityInner(Resources res) throws XmlPullParserException, IOException {
-        // Set density to a fixed value so that we're not affected by the
-        // device's native density.
-        final int densityDpi = DisplayMetrics.DENSITY_MEDIUM;
-        DrawableTestUtils.setResourcesDensity(res, densityDpi);
+    @SmallTest
+    public void testPreloadDensity() throws XmlPullParserException, IOException {
+        final int densityDpi = mResources.getConfiguration().densityDpi;
+        try {
+            DrawableTestUtils.setResourcesDensity(mResources, densityDpi);
+            verifyPreloadDensityInner(mResources, densityDpi);
+        } finally {
+            DrawableTestUtils.setResourcesDensity(mResources, densityDpi);
+        }
+    }
 
+    @SmallTest
+    public void testPreloadDensity_tvdpi() throws XmlPullParserException, IOException {
+        final int densityDpi = mResources.getConfiguration().densityDpi;
+        try {
+            DrawableTestUtils.setResourcesDensity(mResources, 213);
+            verifyPreloadDensityInner(mResources, 213);
+        } finally {
+            DrawableTestUtils.setResourcesDensity(mResources, densityDpi);
+        }
+    }
+
+    private void verifyPreloadDensityInner(Resources res, int densityDpi)
+            throws XmlPullParserException, IOException {
         // Capture initial state at default density.
         final XmlResourceParser parser = DrawableTestUtils.getResourceParser(
                 res, R.drawable.vector_density);
@@ -460,7 +467,9 @@
         DrawableTestUtils.setResourcesDensity(res, densityDpi / 2);
         final VectorDrawable halfDrawable =
                 (VectorDrawable) preloadedConstantState.newDrawable(res);
-        assertEquals(Math.round(origWidth / 2f), halfDrawable.getIntrinsicWidth());
+        // NOTE: densityDpi may not be an even number, so account for *actual* scaling in asserts
+        final float approxHalf = (float)(densityDpi / 2) / densityDpi;
+        assertEquals(Math.round(origWidth * approxHalf), halfDrawable.getIntrinsicWidth());
 
         // Set density to double original.
         DrawableTestUtils.setResourcesDensity(res, densityDpi * 2);