Loading core/java/android/os/BundleMerger.java +48 −0 Original line number Diff line number Diff line Loading @@ -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, Loading @@ -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 {} Loading Loading @@ -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(); } Loading Loading @@ -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)) { Loading @@ -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 Loading core/tests/coretests/src/android/os/BundleMergerTest.java +41 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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(), Loading @@ -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(); Loading Loading
core/java/android/os/BundleMerger.java +48 −0 Original line number Diff line number Diff line Loading @@ -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, Loading @@ -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 {} Loading Loading @@ -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(); } Loading Loading @@ -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)) { Loading @@ -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 Loading
core/tests/coretests/src/android/os/BundleMergerTest.java +41 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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(), Loading @@ -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(); Loading