summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Sudheer Shanka <sudheersai@google.com> 2025-02-20 08:37:40 -0800
committer Android (Google) Code Review <android-gerrit@google.com> 2025-02-20 08:37:40 -0800
commiteecb809cf27cdbeeefe1869018021a805be93de5 (patch)
tree5e8d93bc6a59ccf6a89b7448a4f4793312f4d25b
parentd43220476f531f9591fe0f3492144b5b6f8ba624 (diff)
parent34b1c17f4a4c2b18f898b8a8a8491f46040bbe61 (diff)
Merge "Support new merge strategies in BundleMerger." into main
-rw-r--r--core/java/android/os/BundleMerger.java48
-rw-r--r--core/tests/coretests/src/android/os/BundleMergerTest.java41
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);