Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 63bc46e3 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add support for float type in FRRO" into main

parents 75d39644 ac5be40a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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);
  }
+31 −0
Original line number Diff line number Diff line
@@ -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));
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -28,8 +28,8 @@ android_test {
    certificate: "platform",
    static_libs: [
        "androidx.test.rules",
        "testng",
        "compatibility-device-util-axt",
        "testng",
    ],
    test_suites: ["device-tests"],
    data: [
+3 −1
Original line number Diff line number Diff line
@@ -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" />
+57 −29
Original line number Diff line number Diff line
@@ -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;
            }
        }