diff options
5 files changed, 93 insertions, 31 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index 27aa3518f958..07224db7dcd3 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -12367,6 +12367,7 @@ package android.content.om { method @NonNull public void setResourceValue(@NonNull String, @NonNull android.os.ParcelFileDescriptor, @Nullable String); method @FlaggedApi("android.content.res.asset_file_descriptor_frro") @NonNull public void setResourceValue(@NonNull String, @NonNull android.content.res.AssetFileDescriptor, @Nullable String); method @FlaggedApi("android.content.res.dimension_frro") public void setResourceValue(@NonNull String, float, int, @Nullable String); + method @FlaggedApi("android.content.res.dimension_frro") public void setResourceValue(@NonNull String, float, @Nullable String); method public void setTargetOverlayable(@Nullable String); } diff --git a/core/java/android/content/om/FabricatedOverlay.java b/core/java/android/content/om/FabricatedOverlay.java index 64e9c339f2d6..2f93adbb1e8c 100644 --- a/core/java/android/content/om/FabricatedOverlay.java +++ b/core/java/android/content/om/FabricatedOverlay.java @@ -490,6 +490,17 @@ public class FabricatedOverlay { return entry; } + @NonNull + private static FabricatedOverlayInternalEntry generateFabricatedOverlayInternalEntry( + @NonNull String resourceName, float value, @Nullable String configuration) { + final FabricatedOverlayInternalEntry entry = new FabricatedOverlayInternalEntry(); + entry.resourceName = resourceName; + entry.dataType = TypedValue.TYPE_FLOAT; + entry.data = Float.floatToIntBits(value); + entry.configuration = configuration; + return entry; + } + /** * Sets the resource value in the fabricated overlay for the integer-like types with the * configuration. @@ -621,4 +632,24 @@ public class FabricatedOverlay { mOverlay.entries.add(generateFabricatedOverlayInternalEntry(resourceName, dimensionValue, dimensionUnit, configuration)); } + + /** + * Sets the resource value in the fabricated overlay for the float type with the + * configuration. + * + * @param resourceName name of the target resource to overlay (in the form + * [package]:type/entry) + * @param value the float representing the new value + * @param configuration The string representation of the config this overlay is enabled for + * @throws IllegalArgumentException If the resource name is invalid + */ + @FlaggedApi(android.content.res.Flags.FLAG_DIMENSION_FRRO) + public void setResourceValue( + @NonNull String resourceName, + float value, + @Nullable String configuration) { + ensureValidResourceName(resourceName); + mOverlay.entries.add(generateFabricatedOverlayInternalEntry(resourceName, value, + configuration)); + } } diff --git a/core/tests/overlaytests/device/Android.bp b/core/tests/overlaytests/device/Android.bp index 2b22344a4ef2..db1bf9c295b6 100644 --- a/core/tests/overlaytests/device/Android.bp +++ b/core/tests/overlaytests/device/Android.bp @@ -28,8 +28,8 @@ android_test { certificate: "platform", static_libs: [ "androidx.test.rules", - "testng", "compatibility-device-util-axt", + "testng", ], test_suites: ["device-tests"], data: [ diff --git a/core/tests/overlaytests/device/res/values/config.xml b/core/tests/overlaytests/device/res/values/config.xml index a30d66f82128..e031b95f5d22 100644 --- a/core/tests/overlaytests/device/res/values/config.xml +++ b/core/tests/overlaytests/device/res/values/config.xml @@ -2,7 +2,7 @@ <resources> <string name="str">none</string> <string name="str2">none</string> - <integer name="overlaid">0</integer> + <integer name="overlaidInt">0</integer> <integer name="matrix_100000">100</integer> <integer name="matrix_100001">100</integer> <integer name="matrix_100010">100</integer> @@ -58,6 +58,8 @@ <item>19</item> </integer-array> + <item name="overlaidFloat" format="float" type="dimen">0</item> + <attr name="customAttribute" /> <id name="view_1" /> <id name="view_2" /> diff --git a/core/tests/overlaytests/device/src/com/android/overlaytest/FabricatedOverlaysTest.java b/core/tests/overlaytests/device/src/com/android/overlaytest/FabricatedOverlaysTest.java index 2da9a2ebbdb6..b48e3b7423ff 100644 --- a/core/tests/overlaytests/device/src/com/android/overlaytest/FabricatedOverlaysTest.java +++ b/core/tests/overlaytests/device/src/com/android/overlaytest/FabricatedOverlaysTest.java @@ -22,6 +22,7 @@ import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertNull; import static org.testng.Assert.assertThrows; +import android.annotation.NonNull; import android.content.Context; import android.content.om.FabricatedOverlay; import android.content.om.OverlayIdentifier; @@ -44,14 +45,17 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import java.util.Collections; +import java.util.Objects; import java.util.concurrent.TimeoutException; +import java.util.function.Function; @RunWith(JUnit4.class) @MediumTest public class FabricatedOverlaysTest { private static final String TAG = "FabricatedOverlaysTest"; - private final String TEST_RESOURCE = "integer/overlaid"; - private final String TEST_OVERLAY_NAME = "Test"; + private static final String TEST_INT_RESOURCE = "integer/overlaidInt"; + private static final String TEST_FLOAT_RESOURCE = "dimen/overlaidFloat"; + private static final String TEST_OVERLAY_NAME = "Test"; private Context mContext; private Resources mResources; @@ -84,10 +88,10 @@ public class FabricatedOverlaysTest { public void testFabricatedOverlay() throws Exception { final FabricatedOverlay overlay = new FabricatedOverlay.Builder( mContext.getPackageName(), TEST_OVERLAY_NAME, mContext.getPackageName()) - .setResourceValue(TEST_RESOURCE, TypedValue.TYPE_INT_DEC, 1) + .setResourceValue(TEST_INT_RESOURCE, TypedValue.TYPE_INT_DEC, 1) .build(); - waitForResourceValue(0); + waitForIntResourceValue(0); mOverlayManager.commit(new OverlayManagerTransaction.Builder() .registerFabricatedOverlay(overlay) .build()); @@ -104,63 +108,63 @@ public class FabricatedOverlaysTest { assertNotNull(info); assertTrue(info.isEnabled()); - waitForResourceValue(1); + waitForIntResourceValue(1); mOverlayManager.commit(new OverlayManagerTransaction.Builder() .unregisterFabricatedOverlay(overlay.getIdentifier()) .build()); - waitForResourceValue(0); + waitForIntResourceValue(0); } @Test public void testRegisterEnableAtomic() throws Exception { final FabricatedOverlay overlay = new FabricatedOverlay.Builder( mContext.getPackageName(), TEST_OVERLAY_NAME, mContext.getPackageName()) - .setResourceValue(TEST_RESOURCE, TypedValue.TYPE_INT_DEC, 1) + .setResourceValue(TEST_INT_RESOURCE, TypedValue.TYPE_INT_DEC, 1) .build(); - waitForResourceValue(0); + waitForIntResourceValue(0); mOverlayManager.commit(new OverlayManagerTransaction.Builder() .registerFabricatedOverlay(overlay) .setEnabled(overlay.getIdentifier(), true, mUserId) .build()); - waitForResourceValue(1); + waitForIntResourceValue(1); } @Test public void testRegisterTwice() throws Exception { FabricatedOverlay overlay = new FabricatedOverlay.Builder( mContext.getPackageName(), TEST_OVERLAY_NAME, mContext.getPackageName()) - .setResourceValue(TEST_RESOURCE, TypedValue.TYPE_INT_DEC, 1) + .setResourceValue(TEST_INT_RESOURCE, TypedValue.TYPE_INT_DEC, 1) .build(); - waitForResourceValue(0); + waitForIntResourceValue(0); mOverlayManager.commit(new OverlayManagerTransaction.Builder() .registerFabricatedOverlay(overlay) .setEnabled(overlay.getIdentifier(), true, mUserId) .build()); - waitForResourceValue(1); + waitForIntResourceValue(1); overlay = new FabricatedOverlay.Builder( mContext.getPackageName(), TEST_OVERLAY_NAME, mContext.getPackageName()) - .setResourceValue(TEST_RESOURCE, TypedValue.TYPE_INT_DEC, 2) + .setResourceValue(TEST_INT_RESOURCE, TypedValue.TYPE_INT_DEC, 2) .build(); mOverlayManager.commit(new OverlayManagerTransaction.Builder() .registerFabricatedOverlay(overlay) .build()); - waitForResourceValue(2); + waitForIntResourceValue(2); } @Test public void testInvalidOwningPackageName() throws Exception { final FabricatedOverlay overlay = new FabricatedOverlay.Builder( "android", TEST_OVERLAY_NAME, mContext.getPackageName()) - .setResourceValue(TEST_RESOURCE, TypedValue.TYPE_INT_DEC, 1) + .setResourceValue(TEST_INT_RESOURCE, TypedValue.TYPE_INT_DEC, 1) .build(); - waitForResourceValue(0); + waitForIntResourceValue(0); assertThrows(SecurityException.class, () -> mOverlayManager.commit(new OverlayManagerTransaction.Builder() .registerFabricatedOverlay(overlay) @@ -174,10 +178,10 @@ public class FabricatedOverlaysTest { public void testInvalidOverlayName() throws Exception { final FabricatedOverlay overlay = new FabricatedOverlay.Builder( mContext.getPackageName(), "invalid@name", mContext.getPackageName()) - .setResourceValue(TEST_RESOURCE, TypedValue.TYPE_INT_DEC, 1) + .setResourceValue(TEST_INT_RESOURCE, TypedValue.TYPE_INT_DEC, 1) .build(); - waitForResourceValue(0); + waitForIntResourceValue(0); assertThrows(SecurityException.class, () -> mOverlayManager.commit(new OverlayManagerTransaction.Builder() .registerFabricatedOverlay(overlay) @@ -195,7 +199,7 @@ public class FabricatedOverlaysTest { { FabricatedOverlay overlay = new FabricatedOverlay.Builder(mContext.getPackageName(), longestName, mContext.getPackageName()) - .setResourceValue(TEST_RESOURCE, TypedValue.TYPE_INT_DEC, 1) + .setResourceValue(TEST_INT_RESOURCE, TypedValue.TYPE_INT_DEC, 1) .build(); mOverlayManager.commit(new OverlayManagerTransaction.Builder() @@ -206,7 +210,7 @@ public class FabricatedOverlaysTest { { FabricatedOverlay overlay = new FabricatedOverlay.Builder(mContext.getPackageName(), longestName + "a", mContext.getPackageName()) - .setResourceValue(TEST_RESOURCE, TypedValue.TYPE_INT_DEC, 1) + .setResourceValue(TEST_INT_RESOURCE, TypedValue.TYPE_INT_DEC, 1) .build(); assertThrows(SecurityException.class, () -> @@ -267,11 +271,11 @@ public class FabricatedOverlaysTest { public void testInvalidResourceValues() throws Exception { final FabricatedOverlay overlay = new FabricatedOverlay.Builder( "android", TEST_OVERLAY_NAME, mContext.getPackageName()) - .setResourceValue(TEST_RESOURCE, TypedValue.TYPE_INT_DEC, 1) + .setResourceValue(TEST_INT_RESOURCE, TypedValue.TYPE_INT_DEC, 1) .setResourceValue("color/something", TypedValue.TYPE_INT_DEC, 1) .build(); - waitForResourceValue(0); + waitForIntResourceValue(0); assertThrows(SecurityException.class, () -> mOverlayManager.commit(new OverlayManagerTransaction.Builder() .registerFabricatedOverlay(overlay) @@ -285,10 +289,10 @@ public class FabricatedOverlaysTest { public void testTransactionFailRollback() throws Exception { final FabricatedOverlay overlay = new FabricatedOverlay.Builder( mContext.getPackageName(), TEST_OVERLAY_NAME, mContext.getPackageName()) - .setResourceValue(TEST_RESOURCE, TypedValue.TYPE_INT_DEC, 1) + .setResourceValue(TEST_INT_RESOURCE, TypedValue.TYPE_INT_DEC, 1) .build(); - waitForResourceValue(0); + waitForIntResourceValue(0); assertThrows(SecurityException.class, () -> mOverlayManager.commit(new OverlayManagerTransaction.Builder() .registerFabricatedOverlay(overlay) @@ -299,16 +303,40 @@ public class FabricatedOverlaysTest { assertNull(mOverlayManager.getOverlayInfo(overlay.getIdentifier(), mUserHandle)); } - void waitForResourceValue(final int expectedValue) throws TimeoutException { + @Test + public void setResourceValue_forFloatType_succeeds() throws Exception { + final float overlaidValue = 5.7f; + final FabricatedOverlay overlay = new FabricatedOverlay.Builder( + mContext.getPackageName(), TEST_OVERLAY_NAME, mContext.getPackageName()).build(); + overlay.setResourceValue(TEST_FLOAT_RESOURCE, overlaidValue, null /* configuration */); + + waitForFloatResourceValue(0); + mOverlayManager.commit(new OverlayManagerTransaction.Builder() + .registerFabricatedOverlay(overlay) + .setEnabled(overlay.getIdentifier(), true, mUserId) + .build()); + + waitForFloatResourceValue(overlaidValue); + } + + private void waitForIntResourceValue(final int expectedValue) throws TimeoutException { + waitForResourceValue(expectedValue, TEST_INT_RESOURCE, id -> mResources.getInteger(id)); + } + + private void waitForFloatResourceValue(final float expectedValue) throws TimeoutException { + waitForResourceValue(expectedValue, TEST_FLOAT_RESOURCE, id -> mResources.getFloat(id)); + } + + private <T> void waitForResourceValue(final T expectedValue, final String resourceName, + @NonNull Function<Integer, T> resourceValueEmitter) throws TimeoutException { final long timeOutDuration = 10000; final long endTime = System.currentTimeMillis() + timeOutDuration; - final String resourceName = TEST_RESOURCE; final int resourceId = mResources.getIdentifier(resourceName, "", mContext.getPackageName()); - int resourceValue = 0; + T resourceValue = null; while (System.currentTimeMillis() < endTime) { - resourceValue = mResources.getInteger(resourceId); - if (resourceValue == expectedValue) { + resourceValue = resourceValueEmitter.apply(resourceId); + if (Objects.equals(expectedValue, resourceValue)) { return; } } |