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

Commit 34b1c17f authored by Sudheer Shanka's avatar Sudheer Shanka
Browse files

Support new merge strategies in BundleMerger.

Add a merge strategy to append two strings and to merge
two arrays by taking the union of their elements.

Bug: 395836346
Test: atest core/tests/coretests/src/android/os/BundleMergerTest.java
Flag: NONE trivial change
Change-Id: Idcf7362937d6774a232d1739e198ec5a62143a30
parent e1bd9bff
Loading
Loading
Loading
Loading
+48 −0
Original line number Diff line number Diff line
@@ -118,12 +118,24 @@ public class BundleMerger implements Parcelable {
     */
    public static final int STRATEGY_ARRAY_APPEND = 50;

    /**
     * Merge strategy that combines two conflicting array values by creating a new array
     * containing all unique elements from both arrays.
     */
    public static final int STRATEGY_ARRAY_UNION = 55;

    /**
     * Merge strategy that combines two conflicting {@link ArrayList} values by
     * appending the last {@link ArrayList} after the first {@link ArrayList}.
     */
    public static final int STRATEGY_ARRAY_LIST_APPEND = 60;

    /**
     * Merge strategy that combines two conflicting {@link String} values by
     * appending the last {@link String} after the first {@link String}.
     */
    public static final int STRATEGY_STRING_APPEND = 70;

    @IntDef(flag = false, prefix = { "STRATEGY_" }, value = {
            STRATEGY_REJECT,
            STRATEGY_FIRST,
@@ -136,7 +148,9 @@ public class BundleMerger implements Parcelable {
            STRATEGY_BOOLEAN_AND,
            STRATEGY_BOOLEAN_OR,
            STRATEGY_ARRAY_APPEND,
            STRATEGY_ARRAY_UNION,
            STRATEGY_ARRAY_LIST_APPEND,
            STRATEGY_STRING_APPEND,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface Strategy {}
@@ -298,8 +312,12 @@ public class BundleMerger implements Parcelable {
                return booleanOr(first, last);
            case STRATEGY_ARRAY_APPEND:
                return arrayAppend(first, last);
            case STRATEGY_ARRAY_UNION:
                return arrayUnion(first, last);
            case STRATEGY_ARRAY_LIST_APPEND:
                return arrayListAppend(first, last);
            case STRATEGY_STRING_APPEND:
                return stringAppend(first, last);
            default:
                throw new UnsupportedOperationException();
        }
@@ -361,6 +379,29 @@ public class BundleMerger implements Parcelable {
        return res;
    }

    private static @NonNull Object arrayUnion(@NonNull Object first, @NonNull Object last) {
        if (!first.getClass().isArray()) {
            throw new IllegalArgumentException("Unable to union " + first.getClass());
        }
        final int firstLength = Array.getLength(first);
        final int lastLength = Array.getLength(last);
        final ArrayList<Object> list = new ArrayList<>(firstLength + lastLength);
        final ArraySet<Object> set = new ArraySet<>();
        for (int i = 0; i < firstLength; i++) {
            set.add(Array.get(first, i));
        }
        for (int i = 0; i < lastLength; i++) {
            set.add(Array.get(last, i));
        }
        final Class<?> clazz = first.getClass().getComponentType();
        final int setSize = set.size();
        final Object res = Array.newInstance(clazz, setSize);
        for (int i = 0; i < setSize; i++) {
            Array.set(res, i, set.valueAt(i));
        }
        return res;
    }

    @SuppressWarnings("unchecked")
    private static @NonNull Object arrayListAppend(@NonNull Object first, @NonNull Object last) {
        if (!(first instanceof ArrayList)) {
@@ -374,6 +415,13 @@ public class BundleMerger implements Parcelable {
        return res;
    }

    private static @NonNull Object stringAppend(@NonNull Object first, @NonNull Object last) {
        if (!(first instanceof String)) {
            throw new IllegalArgumentException("Unable to append " + first.getClass());
        }
        return ((String) first) + ((String) last);
    }

    public static final @android.annotation.NonNull Parcelable.Creator<BundleMerger> CREATOR =
            new Parcelable.Creator<BundleMerger>() {
                @Override
+41 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.os;

import static android.os.BundleMerger.STRATEGY_ARRAY_APPEND;
import static android.os.BundleMerger.STRATEGY_ARRAY_LIST_APPEND;
import static android.os.BundleMerger.STRATEGY_ARRAY_UNION;
import static android.os.BundleMerger.STRATEGY_BOOLEAN_AND;
import static android.os.BundleMerger.STRATEGY_BOOLEAN_OR;
import static android.os.BundleMerger.STRATEGY_COMPARABLE_MAX;
@@ -28,6 +29,7 @@ import static android.os.BundleMerger.STRATEGY_NUMBER_ADD;
import static android.os.BundleMerger.STRATEGY_NUMBER_INCREMENT_FIRST;
import static android.os.BundleMerger.STRATEGY_NUMBER_INCREMENT_FIRST_AND_ADD;
import static android.os.BundleMerger.STRATEGY_REJECT;
import static android.os.BundleMerger.STRATEGY_STRING_APPEND;
import static android.os.BundleMerger.merge;

import static org.junit.Assert.assertArrayEquals;
@@ -203,6 +205,33 @@ public class BundleMergerTest {
        });
    }

    @Test
    public void testStrategyArrayUnion() throws Exception {
        assertArrayEquals(new int[] {},
                (int[]) merge(STRATEGY_ARRAY_UNION, new int[] {}, new int[] {}));
        assertArrayEquals(new int[] {10},
                (int[]) merge(STRATEGY_ARRAY_UNION, new int[] {10}, new int[] {}));
        assertArrayEquals(new int[] {20},
                (int[]) merge(STRATEGY_ARRAY_UNION, new int[] {}, new int[] {20}));
        assertArrayEquals(new int[] {10, 20},
                (int[]) merge(STRATEGY_ARRAY_UNION, new int[] {10}, new int[] {20}));
        assertArrayEquals(new int[] {10, 20, 30, 40},
                (int[]) merge(STRATEGY_ARRAY_UNION, new int[] {10, 30}, new int[] {20, 40}));
        assertArrayEquals(new int[] {10, 20, 30},
                (int[]) merge(STRATEGY_ARRAY_UNION, new int[] {10, 30}, new int[] {10, 20}));
        assertArrayEquals(new int[] {10, 20},
                (int[]) merge(STRATEGY_ARRAY_UNION, new int[] {10, 20}, new int[] {20}));
        assertArrayEquals(new String[] {"a", "b"},
                (String[]) merge(STRATEGY_ARRAY_UNION, new String[] {"a"}, new String[] {"b"}));
        assertArrayEquals(new String[] {"a", "b", "c"},
                (String[]) merge(STRATEGY_ARRAY_UNION, new String[] {"a", "b"},
                        new String[] {"b", "c"}));

        assertThrows(Exception.class, () -> {
            merge(STRATEGY_ARRAY_UNION, 10, 20);
        });
    }

    @Test
    public void testStrategyArrayListAppend() throws Exception {
        assertEquals(arrayListOf(),
@@ -223,6 +252,18 @@ public class BundleMergerTest {
        });
    }

    @Test
    public void testStrategyStringAppend() throws Exception {
        assertEquals("ab", merge(STRATEGY_STRING_APPEND, "a", "b"));
        assertEquals("abc", merge(STRATEGY_STRING_APPEND, "a", "bc"));
        assertEquals("abc", merge(STRATEGY_STRING_APPEND, "ab", "c"));
        assertEquals("a,b,c,", merge(STRATEGY_STRING_APPEND, "a,", "b,c,"));

        assertThrows(Exception.class, () -> {
            merge(STRATEGY_STRING_APPEND, 10, 20);
        });
    }

    @Test
    public void testSetDefaultMergeStrategy() throws Exception {
        final BundleMerger merger = new BundleMerger();