Merge "Update framework from jetpack." into sc-dev am: 9f9cc640df
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14669187 Change-Id: Iee3c1624de33a451e503fc9f1074d372b5c826a0
This commit is contained in:
committed by
Automerger Merge Worker
commit
441e99320f
@@ -206,7 +206,7 @@ package android.app.appsearch {
|
|||||||
method @NonNull public android.app.appsearch.GetByDocumentIdRequest build();
|
method @NonNull public android.app.appsearch.GetByDocumentIdRequest build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GetSchemaResponse {
|
public final class GetSchemaResponse {
|
||||||
method @NonNull public java.util.Set<android.app.appsearch.AppSearchSchema> getSchemas();
|
method @NonNull public java.util.Set<android.app.appsearch.AppSearchSchema> getSchemas();
|
||||||
method @IntRange(from=0) public int getVersion();
|
method @IntRange(from=0) public int getVersion();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -389,12 +389,24 @@ public final class AppSearchSchema {
|
|||||||
public @interface TokenizerType {}
|
public @interface TokenizerType {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* It is only valid for tokenizer_type to be 'NONE' if {@link #getIndexingType} is {@link
|
* This value indicates that no tokens should be extracted from this property.
|
||||||
|
*
|
||||||
|
* <p>It is only valid for tokenizer_type to be 'NONE' if {@link #getIndexingType} is {@link
|
||||||
* #INDEXING_TYPE_NONE}.
|
* #INDEXING_TYPE_NONE}.
|
||||||
*/
|
*/
|
||||||
public static final int TOKENIZER_TYPE_NONE = 0;
|
public static final int TOKENIZER_TYPE_NONE = 0;
|
||||||
|
|
||||||
/** Tokenization for plain text. */
|
/**
|
||||||
|
* Tokenization for plain text. This value indicates that tokens should be extracted from
|
||||||
|
* this property based on word breaks. Segments of whitespace and punctuation are not
|
||||||
|
* considered tokens.
|
||||||
|
*
|
||||||
|
* <p>Ex. A property with "foo bar. baz." will produce tokens for "foo", "bar" and "baz".
|
||||||
|
* The segments " " and "." will not be considered tokens.
|
||||||
|
*
|
||||||
|
* <p>It is only valid for tokenizer_type to be 'PLAIN' if {@link #getIndexingType} is
|
||||||
|
* {@link #INDEXING_TYPE_EXACT_TERMS} or {@link #INDEXING_TYPE_PREFIXES}.
|
||||||
|
*/
|
||||||
public static final int TOKENIZER_TYPE_PLAIN = 1;
|
public static final int TOKENIZER_TYPE_PLAIN = 1;
|
||||||
|
|
||||||
StringPropertyConfig(@NonNull Bundle bundle) {
|
StringPropertyConfig(@NonNull Bundle bundle) {
|
||||||
@@ -474,6 +486,17 @@ public final class AppSearchSchema {
|
|||||||
/** Constructs a new {@link StringPropertyConfig} from the contents of this builder. */
|
/** Constructs a new {@link StringPropertyConfig} from the contents of this builder. */
|
||||||
@NonNull
|
@NonNull
|
||||||
public StringPropertyConfig build() {
|
public StringPropertyConfig build() {
|
||||||
|
if (mTokenizerType == TOKENIZER_TYPE_NONE) {
|
||||||
|
Preconditions.checkState(
|
||||||
|
mIndexingType == INDEXING_TYPE_NONE,
|
||||||
|
"Cannot set "
|
||||||
|
+ "TOKENIZER_TYPE_NONE with an indexing type other than "
|
||||||
|
+ "INDEXING_TYPE_NONE.");
|
||||||
|
} else {
|
||||||
|
Preconditions.checkState(
|
||||||
|
mIndexingType != INDEXING_TYPE_NONE,
|
||||||
|
"Cannot set " + "TOKENIZER_TYPE_PLAIN with INDEXING_TYPE_NONE.");
|
||||||
|
}
|
||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
bundle.putString(NAME_FIELD, mPropertyName);
|
bundle.putString(NAME_FIELD, mPropertyName);
|
||||||
bundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_STRING);
|
bundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_STRING);
|
||||||
|
|||||||
@@ -27,8 +27,6 @@ import android.os.Bundle;
|
|||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.android.internal.util.Preconditions;
|
|
||||||
|
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -1018,17 +1016,14 @@ public class GenericDocument {
|
|||||||
// GenericDocument.
|
// GenericDocument.
|
||||||
@SuppressLint("StaticFinalBuilder")
|
@SuppressLint("StaticFinalBuilder")
|
||||||
public static class Builder<BuilderType extends Builder> {
|
public static class Builder<BuilderType extends Builder> {
|
||||||
|
private Bundle mBundle;
|
||||||
private final Bundle mBundle;
|
private Bundle mProperties;
|
||||||
private final Bundle mProperties;
|
|
||||||
private final BuilderType mBuilderTypeInstance;
|
private final BuilderType mBuilderTypeInstance;
|
||||||
private boolean mBuilt = false;
|
private boolean mBuilt = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@link GenericDocument.Builder}.
|
* Creates a new {@link GenericDocument.Builder}.
|
||||||
*
|
*
|
||||||
* <p>Once {@link #build} is called, the instance can no longer be used.
|
|
||||||
*
|
|
||||||
* <p>Document IDs are unique within a namespace.
|
* <p>Document IDs are unique within a namespace.
|
||||||
*
|
*
|
||||||
* <p>The number of namespaces per app should be kept small for efficiency reasons.
|
* <p>The number of namespaces per app should be kept small for efficiency reasons.
|
||||||
@@ -1053,9 +1048,6 @@ public class GenericDocument {
|
|||||||
mBundle.putString(GenericDocument.NAMESPACE_FIELD, namespace);
|
mBundle.putString(GenericDocument.NAMESPACE_FIELD, namespace);
|
||||||
mBundle.putString(GenericDocument.ID_FIELD, id);
|
mBundle.putString(GenericDocument.ID_FIELD, id);
|
||||||
mBundle.putString(GenericDocument.SCHEMA_TYPE_FIELD, schemaType);
|
mBundle.putString(GenericDocument.SCHEMA_TYPE_FIELD, schemaType);
|
||||||
// Set current timestamp for creation timestamp by default.
|
|
||||||
mBundle.putLong(
|
|
||||||
GenericDocument.CREATION_TIMESTAMP_MILLIS_FIELD, System.currentTimeMillis());
|
|
||||||
mBundle.putLong(GenericDocument.TTL_MILLIS_FIELD, DEFAULT_TTL_MILLIS);
|
mBundle.putLong(GenericDocument.TTL_MILLIS_FIELD, DEFAULT_TTL_MILLIS);
|
||||||
mBundle.putInt(GenericDocument.SCORE_FIELD, DEFAULT_SCORE);
|
mBundle.putInt(GenericDocument.SCORE_FIELD, DEFAULT_SCORE);
|
||||||
|
|
||||||
@@ -1063,7 +1055,11 @@ public class GenericDocument {
|
|||||||
mBundle.putBundle(PROPERTIES_FIELD, mProperties);
|
mBundle.putBundle(PROPERTIES_FIELD, mProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Creates a new {@link GenericDocument.Builder} from the given Bundle. */
|
/**
|
||||||
|
* Creates a new {@link GenericDocument.Builder} from the given Bundle.
|
||||||
|
*
|
||||||
|
* <p>The bundle is NOT copied.
|
||||||
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Builder(@NonNull Bundle bundle) {
|
Builder(@NonNull Bundle bundle) {
|
||||||
mBundle = Objects.requireNonNull(bundle);
|
mBundle = Objects.requireNonNull(bundle);
|
||||||
@@ -1079,13 +1075,12 @@ public class GenericDocument {
|
|||||||
*
|
*
|
||||||
* <p>The number of namespaces per app should be kept small for efficiency reasons.
|
* <p>The number of namespaces per app should be kept small for efficiency reasons.
|
||||||
*
|
*
|
||||||
* @throws IllegalStateException if the builder has already been used.
|
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public BuilderType setNamespace(@NonNull String namespace) {
|
public BuilderType setNamespace(@NonNull String namespace) {
|
||||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
|
||||||
Objects.requireNonNull(namespace);
|
Objects.requireNonNull(namespace);
|
||||||
|
resetIfBuilt();
|
||||||
mBundle.putString(GenericDocument.NAMESPACE_FIELD, namespace);
|
mBundle.putString(GenericDocument.NAMESPACE_FIELD, namespace);
|
||||||
return mBuilderTypeInstance;
|
return mBuilderTypeInstance;
|
||||||
}
|
}
|
||||||
@@ -1096,13 +1091,12 @@ public class GenericDocument {
|
|||||||
*
|
*
|
||||||
* <p>Document IDs are unique within a namespace.
|
* <p>Document IDs are unique within a namespace.
|
||||||
*
|
*
|
||||||
* @throws IllegalStateException if the builder has already been used.
|
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public BuilderType setId(@NonNull String id) {
|
public BuilderType setId(@NonNull String id) {
|
||||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
|
||||||
Objects.requireNonNull(id);
|
Objects.requireNonNull(id);
|
||||||
|
resetIfBuilt();
|
||||||
mBundle.putString(GenericDocument.ID_FIELD, id);
|
mBundle.putString(GenericDocument.ID_FIELD, id);
|
||||||
return mBuilderTypeInstance;
|
return mBuilderTypeInstance;
|
||||||
}
|
}
|
||||||
@@ -1113,13 +1107,12 @@ public class GenericDocument {
|
|||||||
* <p>To successfully index a document, the schema type must match the name of an {@link
|
* <p>To successfully index a document, the schema type must match the name of an {@link
|
||||||
* AppSearchSchema} object previously provided to {@link AppSearchSession#setSchema}.
|
* AppSearchSchema} object previously provided to {@link AppSearchSession#setSchema}.
|
||||||
*
|
*
|
||||||
* @throws IllegalStateException if the builder has already been used.
|
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public BuilderType setSchemaType(@NonNull String schemaType) {
|
public BuilderType setSchemaType(@NonNull String schemaType) {
|
||||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
|
||||||
Objects.requireNonNull(schemaType);
|
Objects.requireNonNull(schemaType);
|
||||||
|
resetIfBuilt();
|
||||||
mBundle.putString(GenericDocument.SCHEMA_TYPE_FIELD, schemaType);
|
mBundle.putString(GenericDocument.SCHEMA_TYPE_FIELD, schemaType);
|
||||||
return mBuilderTypeInstance;
|
return mBuilderTypeInstance;
|
||||||
}
|
}
|
||||||
@@ -1136,14 +1129,13 @@ public class GenericDocument {
|
|||||||
* <p>Any non-negative integer can be used a score. By default, scores are set to 0.
|
* <p>Any non-negative integer can be used a score. By default, scores are set to 0.
|
||||||
*
|
*
|
||||||
* @param score any non-negative {@code int} representing the document's score.
|
* @param score any non-negative {@code int} representing the document's score.
|
||||||
* @throws IllegalStateException if the builder has already been used.
|
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public BuilderType setScore(@IntRange(from = 0, to = Integer.MAX_VALUE) int score) {
|
public BuilderType setScore(@IntRange(from = 0, to = Integer.MAX_VALUE) int score) {
|
||||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
|
||||||
if (score < 0) {
|
if (score < 0) {
|
||||||
throw new IllegalArgumentException("Document score cannot be negative.");
|
throw new IllegalArgumentException("Document score cannot be negative.");
|
||||||
}
|
}
|
||||||
|
resetIfBuilt();
|
||||||
mBundle.putInt(GenericDocument.SCORE_FIELD, score);
|
mBundle.putInt(GenericDocument.SCORE_FIELD, score);
|
||||||
return mBuilderTypeInstance;
|
return mBuilderTypeInstance;
|
||||||
}
|
}
|
||||||
@@ -1154,13 +1146,14 @@ public class GenericDocument {
|
|||||||
* <p>This should be set using a value obtained from the {@link System#currentTimeMillis}
|
* <p>This should be set using a value obtained from the {@link System#currentTimeMillis}
|
||||||
* time base.
|
* time base.
|
||||||
*
|
*
|
||||||
|
* <p>If this method is not called, this will be set to the time the object is built.
|
||||||
|
*
|
||||||
* @param creationTimestampMillis a creation timestamp in milliseconds.
|
* @param creationTimestampMillis a creation timestamp in milliseconds.
|
||||||
* @throws IllegalStateException if the builder has already been used.
|
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public BuilderType setCreationTimestampMillis(
|
public BuilderType setCreationTimestampMillis(
|
||||||
@CurrentTimeMillisLong long creationTimestampMillis) {
|
@CurrentTimeMillisLong long creationTimestampMillis) {
|
||||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
resetIfBuilt();
|
||||||
mBundle.putLong(
|
mBundle.putLong(
|
||||||
GenericDocument.CREATION_TIMESTAMP_MILLIS_FIELD, creationTimestampMillis);
|
GenericDocument.CREATION_TIMESTAMP_MILLIS_FIELD, creationTimestampMillis);
|
||||||
return mBuilderTypeInstance;
|
return mBuilderTypeInstance;
|
||||||
@@ -1177,14 +1170,13 @@ public class GenericDocument {
|
|||||||
* auto-deleted until the app is uninstalled or {@link AppSearchSession#remove} is called.
|
* auto-deleted until the app is uninstalled or {@link AppSearchSession#remove} is called.
|
||||||
*
|
*
|
||||||
* @param ttlMillis a non-negative duration in milliseconds.
|
* @param ttlMillis a non-negative duration in milliseconds.
|
||||||
* @throws IllegalStateException if the builder has already been used.
|
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public BuilderType setTtlMillis(long ttlMillis) {
|
public BuilderType setTtlMillis(long ttlMillis) {
|
||||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
|
||||||
if (ttlMillis < 0) {
|
if (ttlMillis < 0) {
|
||||||
throw new IllegalArgumentException("Document ttlMillis cannot be negative.");
|
throw new IllegalArgumentException("Document ttlMillis cannot be negative.");
|
||||||
}
|
}
|
||||||
|
resetIfBuilt();
|
||||||
mBundle.putLong(GenericDocument.TTL_MILLIS_FIELD, ttlMillis);
|
mBundle.putLong(GenericDocument.TTL_MILLIS_FIELD, ttlMillis);
|
||||||
return mBuilderTypeInstance;
|
return mBuilderTypeInstance;
|
||||||
}
|
}
|
||||||
@@ -1197,13 +1189,12 @@ public class GenericDocument {
|
|||||||
* @param values the {@code String} values of the property.
|
* @param values the {@code String} values of the property.
|
||||||
* @throws IllegalArgumentException if no values are provided, if provided values exceed
|
* @throws IllegalArgumentException if no values are provided, if provided values exceed
|
||||||
* maximum repeated property length, or if a passed in {@code String} is {@code null}.
|
* maximum repeated property length, or if a passed in {@code String} is {@code null}.
|
||||||
* @throws IllegalStateException if the builder has already been used.
|
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public BuilderType setPropertyString(@NonNull String name, @NonNull String... values) {
|
public BuilderType setPropertyString(@NonNull String name, @NonNull String... values) {
|
||||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
|
||||||
Objects.requireNonNull(name);
|
Objects.requireNonNull(name);
|
||||||
Objects.requireNonNull(values);
|
Objects.requireNonNull(values);
|
||||||
|
resetIfBuilt();
|
||||||
putInPropertyBundle(name, values);
|
putInPropertyBundle(name, values);
|
||||||
return mBuilderTypeInstance;
|
return mBuilderTypeInstance;
|
||||||
}
|
}
|
||||||
@@ -1216,13 +1207,12 @@ public class GenericDocument {
|
|||||||
* property as given in {@link AppSearchSchema.PropertyConfig#getName}.
|
* property as given in {@link AppSearchSchema.PropertyConfig#getName}.
|
||||||
* @param values the {@code boolean} values of the property.
|
* @param values the {@code boolean} values of the property.
|
||||||
* @throws IllegalArgumentException if values exceed maximum repeated property length.
|
* @throws IllegalArgumentException if values exceed maximum repeated property length.
|
||||||
* @throws IllegalStateException if the builder has already been used.
|
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public BuilderType setPropertyBoolean(@NonNull String name, @NonNull boolean... values) {
|
public BuilderType setPropertyBoolean(@NonNull String name, @NonNull boolean... values) {
|
||||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
|
||||||
Objects.requireNonNull(name);
|
Objects.requireNonNull(name);
|
||||||
Objects.requireNonNull(values);
|
Objects.requireNonNull(values);
|
||||||
|
resetIfBuilt();
|
||||||
putInPropertyBundle(name, values);
|
putInPropertyBundle(name, values);
|
||||||
return mBuilderTypeInstance;
|
return mBuilderTypeInstance;
|
||||||
}
|
}
|
||||||
@@ -1234,13 +1224,12 @@ public class GenericDocument {
|
|||||||
* property as given in {@link AppSearchSchema.PropertyConfig#getName}.
|
* property as given in {@link AppSearchSchema.PropertyConfig#getName}.
|
||||||
* @param values the {@code long} values of the property.
|
* @param values the {@code long} values of the property.
|
||||||
* @throws IllegalArgumentException if values exceed maximum repeated property length.
|
* @throws IllegalArgumentException if values exceed maximum repeated property length.
|
||||||
* @throws IllegalStateException if the builder has already been used.
|
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public BuilderType setPropertyLong(@NonNull String name, @NonNull long... values) {
|
public BuilderType setPropertyLong(@NonNull String name, @NonNull long... values) {
|
||||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
|
||||||
Objects.requireNonNull(name);
|
Objects.requireNonNull(name);
|
||||||
Objects.requireNonNull(values);
|
Objects.requireNonNull(values);
|
||||||
|
resetIfBuilt();
|
||||||
putInPropertyBundle(name, values);
|
putInPropertyBundle(name, values);
|
||||||
return mBuilderTypeInstance;
|
return mBuilderTypeInstance;
|
||||||
}
|
}
|
||||||
@@ -1252,13 +1241,12 @@ public class GenericDocument {
|
|||||||
* property as given in {@link AppSearchSchema.PropertyConfig#getName}.
|
* property as given in {@link AppSearchSchema.PropertyConfig#getName}.
|
||||||
* @param values the {@code double} values of the property.
|
* @param values the {@code double} values of the property.
|
||||||
* @throws IllegalArgumentException if values exceed maximum repeated property length.
|
* @throws IllegalArgumentException if values exceed maximum repeated property length.
|
||||||
* @throws IllegalStateException if the builder has already been used.
|
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public BuilderType setPropertyDouble(@NonNull String name, @NonNull double... values) {
|
public BuilderType setPropertyDouble(@NonNull String name, @NonNull double... values) {
|
||||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
|
||||||
Objects.requireNonNull(name);
|
Objects.requireNonNull(name);
|
||||||
Objects.requireNonNull(values);
|
Objects.requireNonNull(values);
|
||||||
|
resetIfBuilt();
|
||||||
putInPropertyBundle(name, values);
|
putInPropertyBundle(name, values);
|
||||||
return mBuilderTypeInstance;
|
return mBuilderTypeInstance;
|
||||||
}
|
}
|
||||||
@@ -1271,13 +1259,12 @@ public class GenericDocument {
|
|||||||
* @param values the {@code byte[]} of the property.
|
* @param values the {@code byte[]} of the property.
|
||||||
* @throws IllegalArgumentException if no values are provided, if provided values exceed
|
* @throws IllegalArgumentException if no values are provided, if provided values exceed
|
||||||
* maximum repeated property length, or if a passed in {@code byte[]} is {@code null}.
|
* maximum repeated property length, or if a passed in {@code byte[]} is {@code null}.
|
||||||
* @throws IllegalStateException if the builder has already been used.
|
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public BuilderType setPropertyBytes(@NonNull String name, @NonNull byte[]... values) {
|
public BuilderType setPropertyBytes(@NonNull String name, @NonNull byte[]... values) {
|
||||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
|
||||||
Objects.requireNonNull(name);
|
Objects.requireNonNull(name);
|
||||||
Objects.requireNonNull(values);
|
Objects.requireNonNull(values);
|
||||||
|
resetIfBuilt();
|
||||||
putInPropertyBundle(name, values);
|
putInPropertyBundle(name, values);
|
||||||
return mBuilderTypeInstance;
|
return mBuilderTypeInstance;
|
||||||
}
|
}
|
||||||
@@ -1292,14 +1279,13 @@ public class GenericDocument {
|
|||||||
* @throws IllegalArgumentException if no values are provided, if provided values exceed if
|
* @throws IllegalArgumentException if no values are provided, if provided values exceed if
|
||||||
* provided values exceed maximum repeated property length, or if a passed in {@link
|
* provided values exceed maximum repeated property length, or if a passed in {@link
|
||||||
* GenericDocument} is {@code null}.
|
* GenericDocument} is {@code null}.
|
||||||
* @throws IllegalStateException if the builder has already been used.
|
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public BuilderType setPropertyDocument(
|
public BuilderType setPropertyDocument(
|
||||||
@NonNull String name, @NonNull GenericDocument... values) {
|
@NonNull String name, @NonNull GenericDocument... values) {
|
||||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
|
||||||
Objects.requireNonNull(name);
|
Objects.requireNonNull(name);
|
||||||
Objects.requireNonNull(values);
|
Objects.requireNonNull(values);
|
||||||
|
resetIfBuilt();
|
||||||
putInPropertyBundle(name, values);
|
putInPropertyBundle(name, values);
|
||||||
return mBuilderTypeInstance;
|
return mBuilderTypeInstance;
|
||||||
}
|
}
|
||||||
@@ -1314,8 +1300,8 @@ public class GenericDocument {
|
|||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public BuilderType clearProperty(@NonNull String name) {
|
public BuilderType clearProperty(@NonNull String name) {
|
||||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
|
||||||
Objects.requireNonNull(name);
|
Objects.requireNonNull(name);
|
||||||
|
resetIfBuilt();
|
||||||
mProperties.remove(name);
|
mProperties.remove(name);
|
||||||
return mBuilderTypeInstance;
|
return mBuilderTypeInstance;
|
||||||
}
|
}
|
||||||
@@ -1399,16 +1385,25 @@ public class GenericDocument {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Builds the {@link GenericDocument} object. */
|
||||||
* Builds the {@link GenericDocument} object.
|
|
||||||
*
|
|
||||||
* @throws IllegalStateException if the builder has already been used.
|
|
||||||
*/
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public GenericDocument build() {
|
public GenericDocument build() {
|
||||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
|
||||||
mBuilt = true;
|
mBuilt = true;
|
||||||
|
// Set current timestamp for creation timestamp by default.
|
||||||
|
if (mBundle.getLong(GenericDocument.CREATION_TIMESTAMP_MILLIS_FIELD, -1) == -1) {
|
||||||
|
mBundle.putLong(
|
||||||
|
GenericDocument.CREATION_TIMESTAMP_MILLIS_FIELD,
|
||||||
|
System.currentTimeMillis());
|
||||||
|
}
|
||||||
return new GenericDocument(mBundle);
|
return new GenericDocument(mBundle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void resetIfBuilt() {
|
||||||
|
if (mBuilt) {
|
||||||
|
mBundle = BundleUtil.deepCopy(mBundle);
|
||||||
|
mProperties = mBundle.getBundle(PROPERTIES_FIELD);
|
||||||
|
mBuilt = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import java.util.Objects;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/** The response class of {@link AppSearchSession#getSchema} */
|
/** The response class of {@link AppSearchSession#getSchema} */
|
||||||
public class GetSchemaResponse {
|
public final class GetSchemaResponse {
|
||||||
private static final String VERSION_FIELD = "version";
|
private static final String VERSION_FIELD = "version";
|
||||||
private static final String SCHEMAS_FIELD = "schemas";
|
private static final String SCHEMAS_FIELD = "schemas";
|
||||||
|
|
||||||
|
|||||||
@@ -322,6 +322,8 @@ public final class SetSchemaRequest {
|
|||||||
/**
|
/**
|
||||||
* Sets a Map of {@link Migrator}s.
|
* Sets a Map of {@link Migrator}s.
|
||||||
*
|
*
|
||||||
|
* <p>The key of the map is the schema type that the {@link Migrator} value applies to.
|
||||||
|
*
|
||||||
* <p>The {@link Migrator} migrates all {@link GenericDocument}s under given schema type
|
* <p>The {@link Migrator} migrates all {@link GenericDocument}s under given schema type
|
||||||
* from the current version number stored in AppSearch to the final version set via {@link
|
* from the current version number stored in AppSearch to the final version set via {@link
|
||||||
* #setVersion}.
|
* #setVersion}.
|
||||||
@@ -335,7 +337,8 @@ public final class SetSchemaRequest {
|
|||||||
* SetSchemaRequest}.
|
* SetSchemaRequest}.
|
||||||
*
|
*
|
||||||
* @param migrators A {@link Map} of migrators that translate a document from it's current
|
* @param migrators A {@link Map} of migrators that translate a document from it's current
|
||||||
* version to the final version set via {@link #setVersion}.
|
* version to the final version set via {@link #setVersion}. The key of the map is the
|
||||||
|
* schema type that the {@link Migrator} value applies to.
|
||||||
* @see SetSchemaRequest.Builder#setVersion
|
* @see SetSchemaRequest.Builder#setVersion
|
||||||
* @see SetSchemaRequest.Builder#addSchemas
|
* @see SetSchemaRequest.Builder#addSchemas
|
||||||
* @see AppSearchSession#setSchema
|
* @see AppSearchSession#setSchema
|
||||||
|
|||||||
@@ -930,7 +930,12 @@ public class AppSearchManagerService extends SystemService {
|
|||||||
for (int i = 0; i < ids.size(); i++) {
|
for (int i = 0; i < ids.size(); i++) {
|
||||||
String id = ids.get(i);
|
String id = ids.get(i);
|
||||||
try {
|
try {
|
||||||
impl.remove(packageName, databaseName, namespace, id);
|
impl.remove(
|
||||||
|
packageName,
|
||||||
|
databaseName,
|
||||||
|
namespace,
|
||||||
|
id,
|
||||||
|
/*removeStatsBuilder=*/ null);
|
||||||
++operationSuccessCount;
|
++operationSuccessCount;
|
||||||
resultBuilder.setSuccess(id, /*result= */ null);
|
resultBuilder.setSuccess(id, /*result= */ null);
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
@@ -1007,7 +1012,8 @@ public class AppSearchManagerService extends SystemService {
|
|||||||
packageName,
|
packageName,
|
||||||
databaseName,
|
databaseName,
|
||||||
queryExpression,
|
queryExpression,
|
||||||
new SearchSpec(searchSpecBundle));
|
new SearchSpec(searchSpecBundle),
|
||||||
|
/*removeStatsBuilder=*/ null);
|
||||||
// Now that the batch has been written. Persist the newly written data.
|
// Now that the batch has been written. Persist the newly written data.
|
||||||
impl.persistToDisk(PersistType.Code.LITE);
|
impl.persistToDisk(PersistType.Code.LITE);
|
||||||
++operationSuccessCount;
|
++operationSuccessCount;
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ import com.android.server.appsearch.external.localstorage.converter.SetSchemaRes
|
|||||||
import com.android.server.appsearch.external.localstorage.converter.TypePropertyPathToProtoConverter;
|
import com.android.server.appsearch.external.localstorage.converter.TypePropertyPathToProtoConverter;
|
||||||
import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
|
import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
|
||||||
import com.android.server.appsearch.external.localstorage.stats.PutDocumentStats;
|
import com.android.server.appsearch.external.localstorage.stats.PutDocumentStats;
|
||||||
|
import com.android.server.appsearch.external.localstorage.stats.RemoveStats;
|
||||||
import com.android.server.appsearch.external.localstorage.stats.SearchStats;
|
import com.android.server.appsearch.external.localstorage.stats.SearchStats;
|
||||||
|
|
||||||
import com.google.android.icing.IcingSearchEngine;
|
import com.google.android.icing.IcingSearchEngine;
|
||||||
@@ -1118,14 +1119,17 @@ public final class AppSearchImpl implements Closeable {
|
|||||||
* @param databaseName The databaseName the document is in.
|
* @param databaseName The databaseName the document is in.
|
||||||
* @param namespace Namespace of the document to remove.
|
* @param namespace Namespace of the document to remove.
|
||||||
* @param id ID of the document to remove.
|
* @param id ID of the document to remove.
|
||||||
|
* @param removeStatsBuilder builder for {@link RemoveStats} to hold stats for remove
|
||||||
* @throws AppSearchException on IcingSearchEngine error.
|
* @throws AppSearchException on IcingSearchEngine error.
|
||||||
*/
|
*/
|
||||||
public void remove(
|
public void remove(
|
||||||
@NonNull String packageName,
|
@NonNull String packageName,
|
||||||
@NonNull String databaseName,
|
@NonNull String databaseName,
|
||||||
@NonNull String namespace,
|
@NonNull String namespace,
|
||||||
@NonNull String id)
|
@NonNull String id,
|
||||||
|
@Nullable RemoveStats.Builder removeStatsBuilder)
|
||||||
throws AppSearchException {
|
throws AppSearchException {
|
||||||
|
long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
|
||||||
mReadWriteLock.writeLock().lock();
|
mReadWriteLock.writeLock().lock();
|
||||||
try {
|
try {
|
||||||
throwIfClosedLocked();
|
throwIfClosedLocked();
|
||||||
@@ -1138,9 +1142,20 @@ public final class AppSearchImpl implements Closeable {
|
|||||||
mIcingSearchEngineLocked.delete(prefixedNamespace, id);
|
mIcingSearchEngineLocked.delete(prefixedNamespace, id);
|
||||||
mLogUtil.piiTrace(
|
mLogUtil.piiTrace(
|
||||||
"removeById, response", deleteResultProto.getStatus(), deleteResultProto);
|
"removeById, response", deleteResultProto.getStatus(), deleteResultProto);
|
||||||
|
|
||||||
|
if (removeStatsBuilder != null) {
|
||||||
|
removeStatsBuilder.setStatusCode(
|
||||||
|
statusProtoToResultCode(deleteResultProto.getStatus()));
|
||||||
|
AppSearchLoggerHelper.copyNativeStats(
|
||||||
|
deleteResultProto.getDeleteStats(), removeStatsBuilder);
|
||||||
|
}
|
||||||
checkSuccess(deleteResultProto.getStatus());
|
checkSuccess(deleteResultProto.getStatus());
|
||||||
} finally {
|
} finally {
|
||||||
mReadWriteLock.writeLock().unlock();
|
mReadWriteLock.writeLock().unlock();
|
||||||
|
if (removeStatsBuilder != null) {
|
||||||
|
removeStatsBuilder.setTotalLatencyMillis(
|
||||||
|
(int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1153,14 +1168,17 @@ public final class AppSearchImpl implements Closeable {
|
|||||||
* @param databaseName The databaseName the document is in.
|
* @param databaseName The databaseName the document is in.
|
||||||
* @param queryExpression Query String to search.
|
* @param queryExpression Query String to search.
|
||||||
* @param searchSpec Defines what and how to remove
|
* @param searchSpec Defines what and how to remove
|
||||||
|
* @param removeStatsBuilder builder for {@link RemoveStats} to hold stats for remove
|
||||||
* @throws AppSearchException on IcingSearchEngine error.
|
* @throws AppSearchException on IcingSearchEngine error.
|
||||||
*/
|
*/
|
||||||
public void removeByQuery(
|
public void removeByQuery(
|
||||||
@NonNull String packageName,
|
@NonNull String packageName,
|
||||||
@NonNull String databaseName,
|
@NonNull String databaseName,
|
||||||
@NonNull String queryExpression,
|
@NonNull String queryExpression,
|
||||||
@NonNull SearchSpec searchSpec)
|
@NonNull SearchSpec searchSpec,
|
||||||
|
@Nullable RemoveStats.Builder removeStatsBuilder)
|
||||||
throws AppSearchException {
|
throws AppSearchException {
|
||||||
|
long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
|
||||||
mReadWriteLock.writeLock().lock();
|
mReadWriteLock.writeLock().lock();
|
||||||
try {
|
try {
|
||||||
throwIfClosedLocked();
|
throwIfClosedLocked();
|
||||||
@@ -1195,12 +1213,24 @@ public final class AppSearchImpl implements Closeable {
|
|||||||
mLogUtil.piiTrace(
|
mLogUtil.piiTrace(
|
||||||
"removeByQuery, response", deleteResultProto.getStatus(), deleteResultProto);
|
"removeByQuery, response", deleteResultProto.getStatus(), deleteResultProto);
|
||||||
|
|
||||||
|
if (removeStatsBuilder != null) {
|
||||||
|
removeStatsBuilder.setStatusCode(
|
||||||
|
statusProtoToResultCode(deleteResultProto.getStatus()));
|
||||||
|
// TODO(b/187206766) also log query stats here once IcingLib returns it
|
||||||
|
AppSearchLoggerHelper.copyNativeStats(
|
||||||
|
deleteResultProto.getDeleteStats(), removeStatsBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
// It seems that the caller wants to get success if the data matching the query is
|
// It seems that the caller wants to get success if the data matching the query is
|
||||||
// not in the DB because it was not there or was successfully deleted.
|
// not in the DB because it was not there or was successfully deleted.
|
||||||
checkCodeOneOf(
|
checkCodeOneOf(
|
||||||
deleteResultProto.getStatus(), StatusProto.Code.OK, StatusProto.Code.NOT_FOUND);
|
deleteResultProto.getStatus(), StatusProto.Code.OK, StatusProto.Code.NOT_FOUND);
|
||||||
} finally {
|
} finally {
|
||||||
mReadWriteLock.writeLock().unlock();
|
mReadWriteLock.writeLock().unlock();
|
||||||
|
if (removeStatsBuilder != null) {
|
||||||
|
removeStatsBuilder.setTotalLatencyMillis(
|
||||||
|
(int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import android.app.appsearch.exceptions.AppSearchException;
|
|||||||
import com.android.server.appsearch.external.localstorage.stats.CallStats;
|
import com.android.server.appsearch.external.localstorage.stats.CallStats;
|
||||||
import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
|
import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
|
||||||
import com.android.server.appsearch.external.localstorage.stats.PutDocumentStats;
|
import com.android.server.appsearch.external.localstorage.stats.PutDocumentStats;
|
||||||
|
import com.android.server.appsearch.external.localstorage.stats.RemoveStats;
|
||||||
import com.android.server.appsearch.external.localstorage.stats.SearchStats;
|
import com.android.server.appsearch.external.localstorage.stats.SearchStats;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -47,5 +48,8 @@ public interface AppSearchLogger {
|
|||||||
/** Logs {@link SearchStats} */
|
/** Logs {@link SearchStats} */
|
||||||
void logStats(@NonNull SearchStats stats) throws AppSearchException;
|
void logStats(@NonNull SearchStats stats) throws AppSearchException;
|
||||||
|
|
||||||
|
/** Logs {@link RemoveStats} */
|
||||||
|
void logStats(@NonNull RemoveStats stats) throws AppSearchException;
|
||||||
|
|
||||||
// TODO(b/173532925) Add remaining logStats once we add all the stats.
|
// TODO(b/173532925) Add remaining logStats once we add all the stats.
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,8 +20,10 @@ import android.annotation.NonNull;
|
|||||||
|
|
||||||
import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
|
import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
|
||||||
import com.android.server.appsearch.external.localstorage.stats.PutDocumentStats;
|
import com.android.server.appsearch.external.localstorage.stats.PutDocumentStats;
|
||||||
|
import com.android.server.appsearch.external.localstorage.stats.RemoveStats;
|
||||||
import com.android.server.appsearch.external.localstorage.stats.SearchStats;
|
import com.android.server.appsearch.external.localstorage.stats.SearchStats;
|
||||||
|
|
||||||
|
import com.google.android.icing.proto.DeleteStatsProto;
|
||||||
import com.google.android.icing.proto.InitializeStatsProto;
|
import com.google.android.icing.proto.InitializeStatsProto;
|
||||||
import com.google.android.icing.proto.PutDocumentStatsProto;
|
import com.google.android.icing.proto.PutDocumentStatsProto;
|
||||||
import com.google.android.icing.proto.QueryStatsProto;
|
import com.google.android.icing.proto.QueryStatsProto;
|
||||||
@@ -119,4 +121,21 @@ public final class AppSearchLoggerHelper {
|
|||||||
.setDocumentRetrievingLatencyMillis(
|
.setDocumentRetrievingLatencyMillis(
|
||||||
fromNativeStats.getDocumentRetrievalLatencyMs());
|
fromNativeStats.getDocumentRetrievalLatencyMs());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy native Query stats to buiilder.
|
||||||
|
*
|
||||||
|
* @param fromNativeStats Stats copied from.
|
||||||
|
* @param toStatsBuilder Stats copied to.
|
||||||
|
*/
|
||||||
|
static void copyNativeStats(
|
||||||
|
@NonNull DeleteStatsProto fromNativeStats,
|
||||||
|
@NonNull RemoveStats.Builder toStatsBuilder) {
|
||||||
|
Objects.requireNonNull(fromNativeStats);
|
||||||
|
Objects.requireNonNull(toStatsBuilder);
|
||||||
|
toStatsBuilder
|
||||||
|
.setNativeLatencyMillis(fromNativeStats.getLatencyMs())
|
||||||
|
.setDeleteType(fromNativeStats.getDeleteType().getNumber())
|
||||||
|
.setDeletedDocumentCount(fromNativeStats.getNumDocumentsDeleted());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,6 +52,9 @@ public final class SearchStats {
|
|||||||
// Searches the global documents. Including platform surfaceable and 3p-access.
|
// Searches the global documents. Including platform surfaceable and 3p-access.
|
||||||
public static final int VISIBILITY_SCOPE_GLOBAL = 2;
|
public static final int VISIBILITY_SCOPE_GLOBAL = 2;
|
||||||
|
|
||||||
|
// TODO(b/173532925): Add a field searchType to indicate where the search is used(normal
|
||||||
|
// query vs in removeByQuery vs during migration)
|
||||||
|
|
||||||
@NonNull private final String mPackageName;
|
@NonNull private final String mPackageName;
|
||||||
@Nullable private final String mDatabase;
|
@Nullable private final String mDatabase;
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import com.android.server.appsearch.external.localstorage.AppSearchLogger;
|
|||||||
import com.android.server.appsearch.external.localstorage.stats.CallStats;
|
import com.android.server.appsearch.external.localstorage.stats.CallStats;
|
||||||
import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
|
import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
|
||||||
import com.android.server.appsearch.external.localstorage.stats.PutDocumentStats;
|
import com.android.server.appsearch.external.localstorage.stats.PutDocumentStats;
|
||||||
|
import com.android.server.appsearch.external.localstorage.stats.RemoveStats;
|
||||||
import com.android.server.appsearch.external.localstorage.stats.SearchStats;
|
import com.android.server.appsearch.external.localstorage.stats.SearchStats;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
@@ -213,6 +214,11 @@ public final class PlatformLogger implements AppSearchLogger {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void logStats(@androidx.annotation.NonNull RemoveStats stats) throws AppSearchException {
|
||||||
|
// TODO(b/173532925): Log stats
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes cached UID for package.
|
* Removes cached UID for package.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
c6630eba424d98dd54ece674e769d9b0b883e410
|
be6d5138cbd64d3fd401a83d30bf9ad22a6c2d17
|
||||||
|
|||||||
@@ -455,7 +455,8 @@ public class AppSearchImplTest {
|
|||||||
// delete 999 documents, we will reach the threshold to trigger optimize() in next
|
// delete 999 documents, we will reach the threshold to trigger optimize() in next
|
||||||
// deletion.
|
// deletion.
|
||||||
for (int i = 0; i < AppSearchImpl.OPTIMIZE_THRESHOLD_DOC_COUNT - 1; i++) {
|
for (int i = 0; i < AppSearchImpl.OPTIMIZE_THRESHOLD_DOC_COUNT - 1; i++) {
|
||||||
mAppSearchImpl.remove("package", "database", "namespace", "id" + i);
|
mAppSearchImpl.remove(
|
||||||
|
"package", "database", "namespace", "id" + i, /*removeStatsBuilder=*/ null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updates the check for optimize counter, checkForOptimize() will be triggered since
|
// Updates the check for optimize counter, checkForOptimize() will be triggered since
|
||||||
@@ -475,7 +476,8 @@ public class AppSearchImplTest {
|
|||||||
< AppSearchImpl.OPTIMIZE_THRESHOLD_DOC_COUNT
|
< AppSearchImpl.OPTIMIZE_THRESHOLD_DOC_COUNT
|
||||||
+ AppSearchImpl.CHECK_OPTIMIZE_INTERVAL;
|
+ AppSearchImpl.CHECK_OPTIMIZE_INTERVAL;
|
||||||
i++) {
|
i++) {
|
||||||
mAppSearchImpl.remove("package", "database", "namespace", "id" + i);
|
mAppSearchImpl.remove(
|
||||||
|
"package", "database", "namespace", "id" + i, /*removeStatsBuilder=*/ null);
|
||||||
}
|
}
|
||||||
// updates the check for optimize counter, will reach both CHECK_OPTIMIZE_INTERVAL and
|
// updates the check for optimize counter, will reach both CHECK_OPTIMIZE_INTERVAL and
|
||||||
// OPTIMIZE_THRESHOLD_DOC_COUNT this time and trigger a optimize().
|
// OPTIMIZE_THRESHOLD_DOC_COUNT this time and trigger a optimize().
|
||||||
@@ -885,17 +887,20 @@ public class AppSearchImplTest {
|
|||||||
.addFilterSchemas("FakeType")
|
.addFilterSchemas("FakeType")
|
||||||
.setTermMatch(TermMatchType.Code.PREFIX_VALUE)
|
.setTermMatch(TermMatchType.Code.PREFIX_VALUE)
|
||||||
.build();
|
.build();
|
||||||
mAppSearchImpl.removeByQuery("package", "EmptyDatabase", "", searchSpec);
|
mAppSearchImpl.removeByQuery(
|
||||||
|
"package", "EmptyDatabase", "", searchSpec, /*statsBuilder=*/ null);
|
||||||
|
|
||||||
searchSpec =
|
searchSpec =
|
||||||
new SearchSpec.Builder()
|
new SearchSpec.Builder()
|
||||||
.addFilterNamespaces("FakeNamespace")
|
.addFilterNamespaces("FakeNamespace")
|
||||||
.setTermMatch(TermMatchType.Code.PREFIX_VALUE)
|
.setTermMatch(TermMatchType.Code.PREFIX_VALUE)
|
||||||
.build();
|
.build();
|
||||||
mAppSearchImpl.removeByQuery("package", "EmptyDatabase", "", searchSpec);
|
mAppSearchImpl.removeByQuery(
|
||||||
|
"package", "EmptyDatabase", "", searchSpec, /*statsBuilder=*/ null);
|
||||||
|
|
||||||
searchSpec = new SearchSpec.Builder().setTermMatch(TermMatchType.Code.PREFIX_VALUE).build();
|
searchSpec = new SearchSpec.Builder().setTermMatch(TermMatchType.Code.PREFIX_VALUE).build();
|
||||||
mAppSearchImpl.removeByQuery("package", "EmptyDatabase", "", searchSpec);
|
mAppSearchImpl.removeByQuery(
|
||||||
|
"package", "EmptyDatabase", "", searchSpec, /*statsBuilder=*/ null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -1661,8 +1666,7 @@ public class AppSearchImplTest {
|
|||||||
context,
|
context,
|
||||||
VisibilityStore.NO_OP_USER_ID,
|
VisibilityStore.NO_OP_USER_ID,
|
||||||
/*globalQuerierPackage=*/ "",
|
/*globalQuerierPackage=*/ "",
|
||||||
/*logger
|
/*logger=*/ null);
|
||||||
=*/ null);
|
|
||||||
|
|
||||||
// Initial check that we could do something at first.
|
// Initial check that we could do something at first.
|
||||||
List<AppSearchSchema> schemas =
|
List<AppSearchSchema> schemas =
|
||||||
@@ -1768,7 +1772,8 @@ public class AppSearchImplTest {
|
|||||||
expectThrows(
|
expectThrows(
|
||||||
IllegalStateException.class,
|
IllegalStateException.class,
|
||||||
() -> {
|
() -> {
|
||||||
appSearchImpl.remove("package", "database", "namespace", "id");
|
appSearchImpl.remove(
|
||||||
|
"package", "database", "namespace", "id", /*statsBuilder=*/ null);
|
||||||
});
|
});
|
||||||
|
|
||||||
expectThrows(
|
expectThrows(
|
||||||
@@ -1780,7 +1785,8 @@ public class AppSearchImplTest {
|
|||||||
"query",
|
"query",
|
||||||
new SearchSpec.Builder()
|
new SearchSpec.Builder()
|
||||||
.setTermMatch(TermMatchType.Code.PREFIX_VALUE)
|
.setTermMatch(TermMatchType.Code.PREFIX_VALUE)
|
||||||
.build());
|
.build(),
|
||||||
|
/*statsBuilder=*/ null);
|
||||||
});
|
});
|
||||||
|
|
||||||
expectThrows(
|
expectThrows(
|
||||||
@@ -1894,7 +1900,7 @@ public class AppSearchImplTest {
|
|||||||
assertThat(getResult).isEqualTo(document2);
|
assertThat(getResult).isEqualTo(document2);
|
||||||
|
|
||||||
// Delete the first document
|
// Delete the first document
|
||||||
appSearchImpl.remove("package", "database", "namespace1", "id1");
|
appSearchImpl.remove("package", "database", "namespace1", "id1", /*statsBuilder=*/ null);
|
||||||
appSearchImpl.persistToDisk(PersistType.Code.LITE);
|
appSearchImpl.persistToDisk(PersistType.Code.LITE);
|
||||||
expectThrows(
|
expectThrows(
|
||||||
AppSearchException.class,
|
AppSearchException.class,
|
||||||
@@ -1983,7 +1989,8 @@ public class AppSearchImplTest {
|
|||||||
new SearchSpec.Builder()
|
new SearchSpec.Builder()
|
||||||
.addFilterNamespaces("namespace1")
|
.addFilterNamespaces("namespace1")
|
||||||
.setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
|
.setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
|
||||||
.build());
|
.build(),
|
||||||
|
/*statsBuilder=*/ null);
|
||||||
appSearchImpl.persistToDisk(PersistType.Code.LITE);
|
appSearchImpl.persistToDisk(PersistType.Code.LITE);
|
||||||
expectThrows(
|
expectThrows(
|
||||||
AppSearchException.class,
|
AppSearchException.class,
|
||||||
|
|||||||
@@ -32,7 +32,9 @@ import androidx.test.core.app.ApplicationProvider;
|
|||||||
import com.android.server.appsearch.external.localstorage.stats.CallStats;
|
import com.android.server.appsearch.external.localstorage.stats.CallStats;
|
||||||
import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
|
import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
|
||||||
import com.android.server.appsearch.external.localstorage.stats.PutDocumentStats;
|
import com.android.server.appsearch.external.localstorage.stats.PutDocumentStats;
|
||||||
|
import com.android.server.appsearch.external.localstorage.stats.RemoveStats;
|
||||||
import com.android.server.appsearch.external.localstorage.stats.SearchStats;
|
import com.android.server.appsearch.external.localstorage.stats.SearchStats;
|
||||||
|
import com.android.server.appsearch.proto.DeleteStatsProto;
|
||||||
import com.android.server.appsearch.proto.InitializeStatsProto;
|
import com.android.server.appsearch.proto.InitializeStatsProto;
|
||||||
import com.android.server.appsearch.proto.PutDocumentStatsProto;
|
import com.android.server.appsearch.proto.PutDocumentStatsProto;
|
||||||
import com.android.server.appsearch.proto.QueryStatsProto;
|
import com.android.server.appsearch.proto.QueryStatsProto;
|
||||||
@@ -73,6 +75,7 @@ public class AppSearchLoggerTest {
|
|||||||
@Nullable PutDocumentStats mPutDocumentStats;
|
@Nullable PutDocumentStats mPutDocumentStats;
|
||||||
@Nullable InitializeStats mInitializeStats;
|
@Nullable InitializeStats mInitializeStats;
|
||||||
@Nullable SearchStats mSearchStats;
|
@Nullable SearchStats mSearchStats;
|
||||||
|
@Nullable RemoveStats mRemoveStats;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void logStats(@NonNull CallStats stats) {
|
public void logStats(@NonNull CallStats stats) {
|
||||||
@@ -93,6 +96,11 @@ public class AppSearchLoggerTest {
|
|||||||
public void logStats(@NonNull SearchStats stats) {
|
public void logStats(@NonNull SearchStats stats) {
|
||||||
mSearchStats = stats;
|
mSearchStats = stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void logStats(@NonNull RemoveStats stats) {
|
||||||
|
mRemoveStats = stats;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -252,6 +260,27 @@ public class AppSearchLoggerTest {
|
|||||||
.isEqualTo(nativeDocumentRetrievingLatencyMillis);
|
.isEqualTo(nativeDocumentRetrievingLatencyMillis);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAppSearchLoggerHelper_testCopyNativeStats_remove() {
|
||||||
|
final int nativeLatencyMillis = 1;
|
||||||
|
final int nativeDeleteType = 2;
|
||||||
|
final int nativeNumDocumentDeleted = 3;
|
||||||
|
DeleteStatsProto nativeDeleteStatsProto =
|
||||||
|
DeleteStatsProto.newBuilder()
|
||||||
|
.setLatencyMs(nativeLatencyMillis)
|
||||||
|
.setDeleteType(DeleteStatsProto.DeleteType.Code.forNumber(nativeDeleteType))
|
||||||
|
.setNumDocumentsDeleted(nativeNumDocumentDeleted)
|
||||||
|
.build();
|
||||||
|
RemoveStats.Builder rBuilder = new RemoveStats.Builder("packageName", "database");
|
||||||
|
|
||||||
|
AppSearchLoggerHelper.copyNativeStats(nativeDeleteStatsProto, rBuilder);
|
||||||
|
|
||||||
|
RemoveStats rStats = rBuilder.build();
|
||||||
|
assertThat(rStats.getNativeLatencyMillis()).isEqualTo(nativeLatencyMillis);
|
||||||
|
assertThat(rStats.getDeleteType()).isEqualTo(nativeDeleteType);
|
||||||
|
assertThat(rStats.getDeletedDocumentCount()).isEqualTo(nativeNumDocumentDeleted);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Testing actual logging
|
// Testing actual logging
|
||||||
//
|
//
|
||||||
@@ -355,4 +384,74 @@ public class AppSearchLoggerTest {
|
|||||||
assertThat(sStats.isFirstPage()).isTrue();
|
assertThat(sStats.isFirstPage()).isTrue();
|
||||||
assertThat(sStats.getScoredDocumentCount()).isEqualTo(1);
|
assertThat(sStats.getScoredDocumentCount()).isEqualTo(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLoggingStats_remove() throws Exception {
|
||||||
|
// Insert schema
|
||||||
|
final String testPackageName = "testPackage";
|
||||||
|
final String testDatabase = "testDatabase";
|
||||||
|
final String testNamespace = "testNameSpace";
|
||||||
|
final String testId = "id";
|
||||||
|
List<AppSearchSchema> schemas =
|
||||||
|
Collections.singletonList(new AppSearchSchema.Builder("type").build());
|
||||||
|
mAppSearchImpl.setSchema(
|
||||||
|
testPackageName,
|
||||||
|
testDatabase,
|
||||||
|
schemas,
|
||||||
|
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
|
||||||
|
/*schemasPackageAccessible=*/ Collections.emptyMap(),
|
||||||
|
/*forceOverride=*/ false,
|
||||||
|
/*version=*/ 0);
|
||||||
|
GenericDocument document =
|
||||||
|
new GenericDocument.Builder<>(testNamespace, testId, "type").build();
|
||||||
|
mAppSearchImpl.putDocument(testPackageName, testDatabase, document, /*logger=*/ null);
|
||||||
|
|
||||||
|
RemoveStats.Builder rStatsBuilder = new RemoveStats.Builder(testPackageName, testDatabase);
|
||||||
|
mAppSearchImpl.remove(testPackageName, testDatabase, testNamespace, testId, rStatsBuilder);
|
||||||
|
RemoveStats rStats = rStatsBuilder.build();
|
||||||
|
|
||||||
|
assertThat(rStats.getPackageName()).isEqualTo(testPackageName);
|
||||||
|
assertThat(rStats.getDatabase()).isEqualTo(testDatabase);
|
||||||
|
// delete by namespace + id
|
||||||
|
assertThat(rStats.getDeleteType()).isEqualTo(DeleteStatsProto.DeleteType.Code.SINGLE_VALUE);
|
||||||
|
assertThat(rStats.getDeletedDocumentCount()).isEqualTo(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLoggingStats_removeByQuery() throws Exception {
|
||||||
|
// Insert schema
|
||||||
|
final String testPackageName = "testPackage";
|
||||||
|
final String testDatabase = "testDatabase";
|
||||||
|
final String testNamespace = "testNameSpace";
|
||||||
|
List<AppSearchSchema> schemas =
|
||||||
|
Collections.singletonList(new AppSearchSchema.Builder("type").build());
|
||||||
|
mAppSearchImpl.setSchema(
|
||||||
|
testPackageName,
|
||||||
|
testDatabase,
|
||||||
|
schemas,
|
||||||
|
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
|
||||||
|
/*schemasPackageAccessible=*/ Collections.emptyMap(),
|
||||||
|
/*forceOverride=*/ false,
|
||||||
|
/*version=*/ 0);
|
||||||
|
GenericDocument document1 =
|
||||||
|
new GenericDocument.Builder<>(testNamespace, "id1", "type").build();
|
||||||
|
GenericDocument document2 =
|
||||||
|
new GenericDocument.Builder<>(testNamespace, "id2", "type").build();
|
||||||
|
mAppSearchImpl.putDocument(testPackageName, testDatabase, document1, mLogger);
|
||||||
|
mAppSearchImpl.putDocument(testPackageName, testDatabase, document2, mLogger);
|
||||||
|
// No query filters specified. package2 should only get its own documents back.
|
||||||
|
SearchSpec searchSpec =
|
||||||
|
new SearchSpec.Builder().setTermMatch(TermMatchType.Code.PREFIX_VALUE).build();
|
||||||
|
|
||||||
|
RemoveStats.Builder rStatsBuilder = new RemoveStats.Builder(testPackageName, testDatabase);
|
||||||
|
mAppSearchImpl.removeByQuery(
|
||||||
|
testPackageName, testDatabase, /*queryExpression=*/ "", searchSpec, rStatsBuilder);
|
||||||
|
RemoveStats rStats = rStatsBuilder.build();
|
||||||
|
|
||||||
|
assertThat(rStats.getPackageName()).isEqualTo(testPackageName);
|
||||||
|
assertThat(rStats.getDatabase()).isEqualTo(testDatabase);
|
||||||
|
// delete by query
|
||||||
|
assertThat(rStats.getDeleteType()).isEqualTo(DeleteStatsProto.DeleteType.Code.QUERY_VALUE);
|
||||||
|
assertThat(rStats.getDeletedDocumentCount()).isEqualTo(2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user