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

Commit eecb809c authored by Sudheer Shanka's avatar Sudheer Shanka Committed by Android (Google) Code Review
Browse files

Merge "Support new merge strategies in BundleMerger." into main

parents d4322047 34b1c17f
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();