Merge "Update framework from Jetpack." into sc-dev
diff --git a/framework/api/current.txt b/framework/api/current.txt
index a3b8013..905000a 100644
--- a/framework/api/current.txt
+++ b/framework/api/current.txt
@@ -208,8 +208,8 @@
ctor public GetByUriRequest.Builder();
method @NonNull public android.app.appsearch.GetByUriRequest.Builder addProjection(@NonNull String, @NonNull java.lang.String...);
method @NonNull public android.app.appsearch.GetByUriRequest.Builder addProjection(@NonNull String, @NonNull java.util.Collection<java.lang.String>);
- method @NonNull public android.app.appsearch.GetByUriRequest.Builder addUri(@NonNull java.lang.String...);
- method @NonNull public android.app.appsearch.GetByUriRequest.Builder addUri(@NonNull java.util.Collection<java.lang.String>);
+ method @NonNull public android.app.appsearch.GetByUriRequest.Builder addUris(@NonNull java.lang.String...);
+ method @NonNull public android.app.appsearch.GetByUriRequest.Builder addUris(@NonNull java.util.Collection<java.lang.String>);
method @NonNull public android.app.appsearch.GetByUriRequest build();
method @NonNull public android.app.appsearch.GetByUriRequest.Builder setNamespace(@NonNull String);
}
@@ -243,8 +243,8 @@
public static final class RemoveByUriRequest.Builder {
ctor public RemoveByUriRequest.Builder();
- method @NonNull public android.app.appsearch.RemoveByUriRequest.Builder addUri(@NonNull java.lang.String...);
- method @NonNull public android.app.appsearch.RemoveByUriRequest.Builder addUri(@NonNull java.util.Collection<java.lang.String>);
+ method @NonNull public android.app.appsearch.RemoveByUriRequest.Builder addUris(@NonNull java.lang.String...);
+ method @NonNull public android.app.appsearch.RemoveByUriRequest.Builder addUris(@NonNull java.util.Collection<java.lang.String>);
method @NonNull public android.app.appsearch.RemoveByUriRequest build();
method @NonNull public android.app.appsearch.RemoveByUriRequest.Builder setNamespace(@NonNull String);
}
diff --git a/framework/java/external/android/app/appsearch/GetByUriRequest.java b/framework/java/external/android/app/appsearch/GetByUriRequest.java
index 0fcf061..656608d 100644
--- a/framework/java/external/android/app/appsearch/GetByUriRequest.java
+++ b/framework/java/external/android/app/appsearch/GetByUriRequest.java
@@ -122,14 +122,14 @@
/** Adds one or more URIs to the request. */
@NonNull
- public Builder addUri(@NonNull String... uris) {
+ public Builder addUris(@NonNull String... uris) {
Preconditions.checkNotNull(uris);
- return addUri(Arrays.asList(uris));
+ return addUris(Arrays.asList(uris));
}
/** Adds one or more URIs to the request. */
@NonNull
- public Builder addUri(@NonNull Collection<String> uris) {
+ public Builder addUris(@NonNull Collection<String> uris) {
Preconditions.checkState(!mBuilt, "Builder has already been used");
Preconditions.checkNotNull(uris);
mUris.addAll(uris);
diff --git a/framework/java/external/android/app/appsearch/RemoveByUriRequest.java b/framework/java/external/android/app/appsearch/RemoveByUriRequest.java
index 2104198..198eee8 100644
--- a/framework/java/external/android/app/appsearch/RemoveByUriRequest.java
+++ b/framework/java/external/android/app/appsearch/RemoveByUriRequest.java
@@ -73,14 +73,14 @@
/** Adds one or more URIs to the request. */
@NonNull
- public Builder addUri(@NonNull String... uris) {
+ public Builder addUris(@NonNull String... uris) {
Preconditions.checkNotNull(uris);
- return addUri(Arrays.asList(uris));
+ return addUris(Arrays.asList(uris));
}
/** Adds one or more URIs to the request. */
@NonNull
- public Builder addUri(@NonNull Collection<String> uris) {
+ public Builder addUris(@NonNull Collection<String> uris) {
Preconditions.checkState(!mBuilt, "Builder has already been used");
Preconditions.checkNotNull(uris);
mUris.addAll(uris);
diff --git a/framework/java/external/android/app/appsearch/SetSchemaResponse.java b/framework/java/external/android/app/appsearch/SetSchemaResponse.java
index 0328d54..4869aa3 100644
--- a/framework/java/external/android/app/appsearch/SetSchemaResponse.java
+++ b/framework/java/external/android/app/appsearch/SetSchemaResponse.java
@@ -163,7 +163,7 @@
/** Adds deletedTypes to the list of deleted schema types. */
@NonNull
- public Builder addDeletedType(@NonNull Collection<String> deletedTypes) {
+ public Builder addDeletedTypes(@NonNull Collection<String> deletedTypes) {
Preconditions.checkState(!mBuilt, "Builder has already been used");
mDeletedTypes.addAll(Preconditions.checkNotNull(deletedTypes));
return this;
@@ -171,7 +171,7 @@
/** Adds incompatibleTypes to the list of incompatible schema types. */
@NonNull
- public Builder addIncompatibleType(@NonNull Collection<String> incompatibleTypes) {
+ public Builder addIncompatibleTypes(@NonNull Collection<String> incompatibleTypes) {
Preconditions.checkState(!mBuilt, "Builder has already been used");
mIncompatibleTypes.addAll(Preconditions.checkNotNull(incompatibleTypes));
return this;
@@ -179,7 +179,7 @@
/** Adds migratedTypes to the list of migrated schema types. */
@NonNull
- public Builder addMigratedType(@NonNull Collection<String> migratedTypes) {
+ public Builder addMigratedTypes(@NonNull Collection<String> migratedTypes) {
Preconditions.checkState(!mBuilt, "Builder has already been used");
mMigratedTypes.addAll(Preconditions.checkNotNull(migratedTypes));
return this;
diff --git a/framework/java/external/android/app/appsearch/util/BundleUtil.java b/framework/java/external/android/app/appsearch/util/BundleUtil.java
index 1b4d284..14dd472 100644
--- a/framework/java/external/android/app/appsearch/util/BundleUtil.java
+++ b/framework/java/external/android/app/appsearch/util/BundleUtil.java
@@ -147,35 +147,41 @@
if (bundle == null) {
return 0;
}
- int[] hashCodes = new int[bundle.size()];
- int i = 0;
+ int[] hashCodes = new int[bundle.size() + 1];
+ int hashCodeIdx = 0;
// Bundle inherit its hashCode() from Object.java, which only relative to their memory
// address. Bundle doesn't have an order, so we should iterate all keys and combine
// their value's hashcode into an array. And use the hashcode of the array to be
// the hashcode of the bundle.
- for (String key : bundle.keySet()) {
- Object value = bundle.get(key);
+ // Because bundle.keySet() doesn't guarantee any particular order, we need to sort the keys
+ // in case the iteration order varies from run to run.
+ String[] keys = bundle.keySet().toArray(new String[0]);
+ Arrays.sort(keys);
+ // Hash the keys so we can detect key-only differences
+ hashCodes[hashCodeIdx++] = Arrays.hashCode(keys);
+ for (int keyIdx = 0; keyIdx < keys.length; keyIdx++) {
+ Object value = bundle.get(keys[keyIdx]);
if (value instanceof Bundle) {
- hashCodes[i++] = deepHashCode((Bundle) value);
+ hashCodes[hashCodeIdx++] = deepHashCode((Bundle) value);
} else if (value instanceof int[]) {
- hashCodes[i++] = Arrays.hashCode((int[]) value);
+ hashCodes[hashCodeIdx++] = Arrays.hashCode((int[]) value);
} else if (value instanceof byte[]) {
- hashCodes[i++] = Arrays.hashCode((byte[]) value);
+ hashCodes[hashCodeIdx++] = Arrays.hashCode((byte[]) value);
} else if (value instanceof char[]) {
- hashCodes[i++] = Arrays.hashCode((char[]) value);
+ hashCodes[hashCodeIdx++] = Arrays.hashCode((char[]) value);
} else if (value instanceof long[]) {
- hashCodes[i++] = Arrays.hashCode((long[]) value);
+ hashCodes[hashCodeIdx++] = Arrays.hashCode((long[]) value);
} else if (value instanceof float[]) {
- hashCodes[i++] = Arrays.hashCode((float[]) value);
+ hashCodes[hashCodeIdx++] = Arrays.hashCode((float[]) value);
} else if (value instanceof short[]) {
- hashCodes[i++] = Arrays.hashCode((short[]) value);
+ hashCodes[hashCodeIdx++] = Arrays.hashCode((short[]) value);
} else if (value instanceof double[]) {
- hashCodes[i++] = Arrays.hashCode((double[]) value);
+ hashCodes[hashCodeIdx++] = Arrays.hashCode((double[]) value);
} else if (value instanceof boolean[]) {
- hashCodes[i++] = Arrays.hashCode((boolean[]) value);
+ hashCodes[hashCodeIdx++] = Arrays.hashCode((boolean[]) value);
} else if (value instanceof String[]) {
// Optimization to avoid Object[] handler creating an inner array for common cases
- hashCodes[i++] = Arrays.hashCode((String[]) value);
+ hashCodes[hashCodeIdx++] = Arrays.hashCode((String[]) value);
} else if (value instanceof Object[]) {
Object[] array = (Object[]) value;
int[] innerHashCodes = new int[array.length];
@@ -186,7 +192,7 @@
innerHashCodes[j] = array[j].hashCode();
}
}
- hashCodes[i++] = Arrays.hashCode(innerHashCodes);
+ hashCodes[hashCodeIdx++] = Arrays.hashCode(innerHashCodes);
} else if (value instanceof ArrayList) {
ArrayList<?> list = (ArrayList<?>) value;
int[] innerHashCodes = new int[list.size()];
@@ -198,7 +204,7 @@
innerHashCodes[j] = item.hashCode();
}
}
- hashCodes[i++] = Arrays.hashCode(innerHashCodes);
+ hashCodes[hashCodeIdx++] = Arrays.hashCode(innerHashCodes);
} else if (value instanceof SparseArray) {
SparseArray<?> array = (SparseArray<?>) value;
int[] innerHashCodes = new int[array.size() * 2];
@@ -211,9 +217,9 @@
innerHashCodes[j * 2 + 1] = item.hashCode();
}
}
- hashCodes[i++] = Arrays.hashCode(innerHashCodes);
+ hashCodes[hashCodeIdx++] = Arrays.hashCode(innerHashCodes);
} else {
- hashCodes[i++] = value.hashCode();
+ hashCodes[hashCodeIdx++] = value.hashCode();
}
}
return Arrays.hashCode(hashCodes);
diff --git a/synced_jetpack_changeid.txt b/synced_jetpack_changeid.txt
index 12699b7..6ba5572 100644
--- a/synced_jetpack_changeid.txt
+++ b/synced_jetpack_changeid.txt
@@ -1 +1 @@
-Ibe06fb9c574c8718191f833bb042fa10c300e4e2
+I2bf8bd9db1b71b7da4ab50dd7480e4529678413a
diff --git a/testing/coretests/src/android/app/appsearch/external/util/BundleUtilTest.java b/testing/coretests/src/android/app/appsearch/external/util/BundleUtilTest.java
index cfcfcc8..ece37f8 100644
--- a/testing/coretests/src/android/app/appsearch/external/util/BundleUtilTest.java
+++ b/testing/coretests/src/android/app/appsearch/external/util/BundleUtilTest.java
@@ -201,6 +201,18 @@
assertThat(BundleUtil.deepHashCode(b1)).isNotEqualTo(BundleUtil.deepHashCode(b2));
}
+ @Test
+ public void testDeepHashCode_differentKeys() {
+ Bundle[] inputs = new Bundle[2];
+ for (int i = 0; i < 2; i++) {
+ Bundle b = new Bundle();
+ b.putString("key" + i, "value");
+ inputs[i] = b;
+ }
+ assertThat(BundleUtil.deepHashCode(inputs[0]))
+ .isNotEqualTo(BundleUtil.deepHashCode(inputs[1]));
+ }
+
private static Bundle createThoroughBundle() {
Bundle toy1 = new Bundle();
toy1.putString("a", "a");
diff --git a/testing/java/com/android/server/appsearch/testing/external/AppSearchTestUtils.java b/testing/java/com/android/server/appsearch/testing/external/AppSearchTestUtils.java
index 20fb909..44d5180 100644
--- a/testing/java/com/android/server/appsearch/testing/external/AppSearchTestUtils.java
+++ b/testing/java/com/android/server/appsearch/testing/external/AppSearchTestUtils.java
@@ -59,7 +59,7 @@
session.getByUri(
new GetByUriRequest.Builder()
.setNamespace(namespace)
- .addUri(uris)
+ .addUris(uris)
.build()));
assertThat(result.getSuccesses()).hasSize(uris.length);
assertThat(result.getFailures()).isEmpty();