diff options
| author | 2025-02-20 08:37:40 -0800 | |
|---|---|---|
| committer | 2025-02-20 08:37:40 -0800 | |
| commit | eecb809cf27cdbeeefe1869018021a805be93de5 (patch) | |
| tree | 5e8d93bc6a59ccf6a89b7448a4f4793312f4d25b | |
| parent | d43220476f531f9591fe0f3492144b5b6f8ba624 (diff) | |
| parent | 34b1c17f4a4c2b18f898b8a8a8491f46040bbe61 (diff) | |
Merge "Support new merge strategies in BundleMerger." into main
| -rw-r--r-- | core/java/android/os/BundleMerger.java | 48 | ||||
| -rw-r--r-- | core/tests/coretests/src/android/os/BundleMergerTest.java | 41 |
2 files changed, 89 insertions, 0 deletions
diff --git a/core/java/android/os/BundleMerger.java b/core/java/android/os/BundleMerger.java index dc243a5e9c08..fd5a18c22a37 100644 --- a/core/java/android/os/BundleMerger.java +++ b/core/java/android/os/BundleMerger.java @@ -119,11 +119,23 @@ 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 diff --git a/core/tests/coretests/src/android/os/BundleMergerTest.java b/core/tests/coretests/src/android/os/BundleMergerTest.java index 43ed821e647d..53799935e118 100644 --- a/core/tests/coretests/src/android/os/BundleMergerTest.java +++ b/core/tests/coretests/src/android/os/BundleMergerTest.java @@ -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; @@ -204,6 +206,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(), merge(STRATEGY_ARRAY_LIST_APPEND, arrayListOf(), arrayListOf())); @@ -224,6 +253,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(); merger.setDefaultMergeStrategy(STRATEGY_FIRST); |