summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apex/appsearch/framework/api/current.txt76
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/AppSearchBatchResult.java7
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java19
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java93
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/GlobalSearchSession.java11
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl28
-rw-r--r--apex/appsearch/framework/java/external/android/app/appsearch/AppSearchEmail.java6
-rw-r--r--apex/appsearch/framework/java/external/android/app/appsearch/AppSearchSchema.java137
-rw-r--r--apex/appsearch/framework/java/external/android/app/appsearch/GenericDocument.java814
-rw-r--r--apex/appsearch/framework/java/external/android/app/appsearch/GetByDocumentIdRequest.java (renamed from apex/appsearch/framework/java/external/android/app/appsearch/GetByUriRequest.java)63
-rw-r--r--apex/appsearch/framework/java/external/android/app/appsearch/GetSchemaResponse.java2
-rw-r--r--apex/appsearch/framework/java/external/android/app/appsearch/Migrator.java4
-rw-r--r--apex/appsearch/framework/java/external/android/app/appsearch/RemoveByDocumentIdRequest.java (renamed from apex/appsearch/framework/java/external/android/app/appsearch/RemoveByUriRequest.java)46
-rw-r--r--apex/appsearch/framework/java/external/android/app/appsearch/ReportSystemUsageRequest.java62
-rw-r--r--apex/appsearch/framework/java/external/android/app/appsearch/ReportUsageRequest.java58
-rw-r--r--apex/appsearch/framework/java/external/android/app/appsearch/SearchResult.java30
-rw-r--r--apex/appsearch/framework/java/external/android/app/appsearch/SearchSpec.java12
-rw-r--r--apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaRequest.java2
-rw-r--r--apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaResponse.java110
-rw-r--r--apex/appsearch/framework/java/external/android/app/appsearch/exceptions/IllegalSearchSpecException.java36
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java56
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/VisibilityStore.java27
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java25
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverter.java2
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverter.java8
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchResultToProtoConverter.java3
-rw-r--r--apex/appsearch/synced_jetpack_changeid.txt2
-rw-r--r--apex/appsearch/testing/java/com/android/server/appsearch/testing/AppSearchSessionShimImpl.java13
-rw-r--r--apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchSessionShim.java54
-rw-r--r--apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchTestUtils.java32
-rw-r--r--apex/appsearch/testing/java/com/android/server/appsearch/testing/external/GlobalSearchSessionShim.java7
-rw-r--r--core/java/android/content/pm/AppSearchPerson.java2
-rw-r--r--core/java/android/content/pm/AppSearchShortcutInfo.java6
-rw-r--r--core/tests/coretests/src/android/app/appsearch/external/app/AppSearchEmailTest.java4
-rw-r--r--core/tests/coretests/src/android/app/appsearch/external/app/GenericDocumentTest.java4
-rw-r--r--core/tests/coretests/src/android/app/appsearch/external/app/PutDocumentsRequestTest.java4
-rw-r--r--services/core/java/com/android/server/pm/ShortcutPackage.java16
-rw-r--r--services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java154
-rw-r--r--services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchLoggerTest.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverterTest.java16
-rw-r--r--services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SnippetTest.java258
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java46
42 files changed, 1343 insertions, 1015 deletions
diff --git a/apex/appsearch/framework/api/current.txt b/apex/appsearch/framework/api/current.txt
index 5acfe6ab6430..7441b0f1e22b 100644
--- a/apex/appsearch/framework/api/current.txt
+++ b/apex/appsearch/framework/api/current.txt
@@ -79,15 +79,14 @@ package android.app.appsearch {
public static final class AppSearchSchema.DocumentPropertyConfig extends android.app.appsearch.AppSearchSchema.PropertyConfig {
method @NonNull public String getSchemaType();
- method public boolean isIndexNestedProperties();
+ method public boolean shouldIndexNestedProperties();
}
public static final class AppSearchSchema.DocumentPropertyConfig.Builder {
- ctor public AppSearchSchema.DocumentPropertyConfig.Builder(@NonNull String);
+ ctor public AppSearchSchema.DocumentPropertyConfig.Builder(@NonNull String, @NonNull String);
method @NonNull public android.app.appsearch.AppSearchSchema.DocumentPropertyConfig build();
method @NonNull public android.app.appsearch.AppSearchSchema.DocumentPropertyConfig.Builder setCardinality(int);
- method @NonNull public android.app.appsearch.AppSearchSchema.DocumentPropertyConfig.Builder setIndexNestedProperties(boolean);
- method @NonNull public android.app.appsearch.AppSearchSchema.DocumentPropertyConfig.Builder setSchemaType(@NonNull String);
+ method @NonNull public android.app.appsearch.AppSearchSchema.DocumentPropertyConfig.Builder setShouldIndexNestedProperties(boolean);
}
public static final class AppSearchSchema.DoublePropertyConfig extends android.app.appsearch.AppSearchSchema.PropertyConfig {
@@ -136,12 +135,12 @@ package android.app.appsearch {
public final class AppSearchSession implements java.io.Closeable {
method public void close();
- method public void getByUri(@NonNull android.app.appsearch.GetByUriRequest, @NonNull java.util.concurrent.Executor, @NonNull android.app.appsearch.BatchResultCallback<java.lang.String,android.app.appsearch.GenericDocument>);
+ method public void getByDocumentId(@NonNull android.app.appsearch.GetByDocumentIdRequest, @NonNull java.util.concurrent.Executor, @NonNull android.app.appsearch.BatchResultCallback<java.lang.String,android.app.appsearch.GenericDocument>);
method public void getNamespaces(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<java.util.Set<java.lang.String>>>);
method public void getSchema(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<android.app.appsearch.GetSchemaResponse>>);
method public void getStorageInfo(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<android.app.appsearch.StorageInfo>>);
method public void put(@NonNull android.app.appsearch.PutDocumentsRequest, @NonNull java.util.concurrent.Executor, @NonNull android.app.appsearch.BatchResultCallback<java.lang.String,java.lang.Void>);
- method public void remove(@NonNull android.app.appsearch.RemoveByUriRequest, @NonNull java.util.concurrent.Executor, @NonNull android.app.appsearch.BatchResultCallback<java.lang.String,java.lang.Void>);
+ method public void remove(@NonNull android.app.appsearch.RemoveByDocumentIdRequest, @NonNull java.util.concurrent.Executor, @NonNull android.app.appsearch.BatchResultCallback<java.lang.String,java.lang.Void>);
method public void remove(@NonNull String, @NonNull android.app.appsearch.SearchSpec, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<java.lang.Void>>);
method public void reportUsage(@NonNull android.app.appsearch.ReportUsageRequest, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<java.lang.Void>>);
method @NonNull public android.app.appsearch.SearchResults search(@NonNull String, @NonNull android.app.appsearch.SearchSpec);
@@ -156,6 +155,7 @@ package android.app.appsearch {
public class GenericDocument {
ctor protected GenericDocument(@NonNull android.app.appsearch.GenericDocument);
method public long getCreationTimestampMillis();
+ method @NonNull public String getId();
method public static int getMaxIndexedProperties();
method @NonNull public String getNamespace();
method @Nullable public Object getProperty(@NonNull String);
@@ -175,7 +175,6 @@ package android.app.appsearch {
method @NonNull public String getSchemaType();
method public int getScore();
method public long getTtlMillis();
- method @NonNull public String getUri();
}
public static class GenericDocument.Builder<BuilderType extends android.app.appsearch.GenericDocument.Builder> {
@@ -192,19 +191,19 @@ package android.app.appsearch {
method @NonNull public BuilderType setTtlMillis(long);
}
- public final class GetByUriRequest {
+ public final class GetByDocumentIdRequest {
+ method @NonNull public java.util.Set<java.lang.String> getIds();
method @NonNull public String getNamespace();
method @NonNull public java.util.Map<java.lang.String,java.util.List<java.lang.String>> getProjections();
- method @NonNull public java.util.Set<java.lang.String> getUris();
field public static final String PROJECTION_SCHEMA_TYPE_WILDCARD = "*";
}
- public static final class GetByUriRequest.Builder {
- ctor public GetByUriRequest.Builder(@NonNull 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 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();
+ public static final class GetByDocumentIdRequest.Builder {
+ ctor public GetByDocumentIdRequest.Builder(@NonNull String);
+ method @NonNull public android.app.appsearch.GetByDocumentIdRequest.Builder addIds(@NonNull java.lang.String...);
+ method @NonNull public android.app.appsearch.GetByDocumentIdRequest.Builder addIds(@NonNull java.util.Collection<java.lang.String>);
+ method @NonNull public android.app.appsearch.GetByDocumentIdRequest.Builder addProjection(@NonNull String, @NonNull java.util.Collection<java.lang.String>);
+ method @NonNull public android.app.appsearch.GetByDocumentIdRequest build();
}
public class GetSchemaResponse {
@@ -249,44 +248,42 @@ package android.app.appsearch {
method @NonNull public android.app.appsearch.PutDocumentsRequest build();
}
- public final class RemoveByUriRequest {
+ public final class RemoveByDocumentIdRequest {
+ method @NonNull public java.util.Set<java.lang.String> getIds();
method @NonNull public String getNamespace();
- method @NonNull public java.util.Set<java.lang.String> getUris();
}
- public static final class RemoveByUriRequest.Builder {
- ctor public RemoveByUriRequest.Builder(@NonNull 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();
+ public static final class RemoveByDocumentIdRequest.Builder {
+ ctor public RemoveByDocumentIdRequest.Builder(@NonNull String);
+ method @NonNull public android.app.appsearch.RemoveByDocumentIdRequest.Builder addIds(@NonNull java.lang.String...);
+ method @NonNull public android.app.appsearch.RemoveByDocumentIdRequest.Builder addIds(@NonNull java.util.Collection<java.lang.String>);
+ method @NonNull public android.app.appsearch.RemoveByDocumentIdRequest build();
}
public final class ReportSystemUsageRequest {
method @NonNull public String getDatabaseName();
+ method @NonNull public String getDocumentId();
method @NonNull public String getNamespace();
method @NonNull public String getPackageName();
- method @NonNull public String getUri();
- method public long getUsageTimeMillis();
+ method public long getUsageTimestampMillis();
}
public static final class ReportSystemUsageRequest.Builder {
- ctor public ReportSystemUsageRequest.Builder(@NonNull String, @NonNull String, @NonNull String);
+ ctor public ReportSystemUsageRequest.Builder(@NonNull String, @NonNull String, @NonNull String, @NonNull String);
method @NonNull public android.app.appsearch.ReportSystemUsageRequest build();
- method @NonNull public android.app.appsearch.ReportSystemUsageRequest.Builder setUri(@NonNull String);
- method @NonNull public android.app.appsearch.ReportSystemUsageRequest.Builder setUsageTimeMillis(long);
+ method @NonNull public android.app.appsearch.ReportSystemUsageRequest.Builder setUsageTimestampMillis(long);
}
public final class ReportUsageRequest {
+ method @NonNull public String getDocumentId();
method @NonNull public String getNamespace();
- method @NonNull public String getUri();
- method public long getUsageTimeMillis();
+ method public long getUsageTimestampMillis();
}
public static final class ReportUsageRequest.Builder {
- ctor public ReportUsageRequest.Builder(@NonNull String);
+ ctor public ReportUsageRequest.Builder(@NonNull String, @NonNull String);
method @NonNull public android.app.appsearch.ReportUsageRequest build();
- method @NonNull public android.app.appsearch.ReportUsageRequest.Builder setUri(@NonNull String);
- method @NonNull public android.app.appsearch.ReportUsageRequest.Builder setUsageTimeMillis(long);
+ method @NonNull public android.app.appsearch.ReportUsageRequest.Builder setUsageTimestampMillis(long);
}
public final class SearchResult {
@@ -315,10 +312,9 @@ package android.app.appsearch {
}
public static final class SearchResult.MatchInfo.Builder {
- ctor public SearchResult.MatchInfo.Builder();
+ ctor public SearchResult.MatchInfo.Builder(@NonNull String);
method @NonNull public android.app.appsearch.SearchResult.MatchInfo build();
method @NonNull public android.app.appsearch.SearchResult.MatchInfo.Builder setExactMatchRange(@NonNull android.app.appsearch.SearchResult.MatchRange);
- method @NonNull public android.app.appsearch.SearchResult.MatchInfo.Builder setPropertyPath(@NonNull String);
method @NonNull public android.app.appsearch.SearchResult.MatchInfo.Builder setSnippetRange(@NonNull android.app.appsearch.SearchResult.MatchRange);
}
@@ -427,19 +423,11 @@ package android.app.appsearch {
}
public static class SetSchemaResponse.MigrationFailure {
+ ctor public SetSchemaResponse.MigrationFailure(@NonNull String, @NonNull String, @NonNull String, @NonNull android.app.appsearch.AppSearchResult<?>);
method @NonNull public android.app.appsearch.AppSearchResult<java.lang.Void> getAppSearchResult();
+ method @NonNull public String getDocumentId();
method @NonNull public String getNamespace();
method @NonNull public String getSchemaType();
- method @NonNull public String getUri();
- }
-
- public static final class SetSchemaResponse.MigrationFailure.Builder {
- ctor public SetSchemaResponse.MigrationFailure.Builder();
- method @NonNull public android.app.appsearch.SetSchemaResponse.MigrationFailure build();
- method @NonNull public android.app.appsearch.SetSchemaResponse.MigrationFailure.Builder setAppSearchResult(@NonNull android.app.appsearch.AppSearchResult<java.lang.Void>);
- method @NonNull public android.app.appsearch.SetSchemaResponse.MigrationFailure.Builder setNamespace(@NonNull String);
- method @NonNull public android.app.appsearch.SetSchemaResponse.MigrationFailure.Builder setSchemaType(@NonNull String);
- method @NonNull public android.app.appsearch.SetSchemaResponse.MigrationFailure.Builder setUri(@NonNull String);
}
public class StorageInfo {
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchBatchResult.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchBatchResult.java
index 6c624264b9be..9ae0d622dfae 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchBatchResult.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchBatchResult.java
@@ -40,7 +40,7 @@ import java.util.Objects;
* both successes and failures.
*
* @see AppSearchSession#put
- * @see AppSearchSession#getByUri
+ * @see AppSearchSession#getByDocumentId
* @see AppSearchSession#remove
*/
public final class AppSearchBatchResult<KeyType, ValueType> implements Parcelable {
@@ -87,8 +87,9 @@ public final class AppSearchBatchResult<KeyType, ValueType> implements Parcelabl
* Returns a {@link Map} of keys mapped to instances of the value type for all successful
* individual results.
*
- * <p>Example: {@link AppSearchSession#getByUri} returns an {@link AppSearchBatchResult}. Each
- * key (a URI of {@code String} type) will map to a {@link GenericDocument} object.
+ * <p>Example: {@link AppSearchSession#getByDocumentId} returns an {@link AppSearchBatchResult}.
+ * Each key (the document ID, of {@code String} type) will map to a {@link GenericDocument}
+ * object.
*
* <p>The values of the {@link Map} will not be {@code null}.
*/
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java
index 8af91b480889..c4dd1a0bc4e5 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java
@@ -78,10 +78,10 @@ import java.util.function.Consumer;
* });</pre>
*
* <p>The basic unit of data in AppSearch is represented as a {@link GenericDocument} object,
- * containing a URI, namespace, time-to-live, score, and properties. A namespace organizes a logical
+ * containing an ID, namespace, time-to-live, score, and properties. A namespace organizes a logical
* group of documents. For example, a namespace can be created to group documents on a per-account
- * basis. A URI identifies a single document within a namespace. The combination of URI and
- * namespace uniquely identifies a {@link GenericDocument} in the database.
+ * basis. An ID identifies a single document within a namespace. The combination of namespace and ID
+ * uniquely identifies a {@link GenericDocument} in the database.
*
* <p>Once the schema has been set, {@link GenericDocument} objects can be put into the database and
* indexed by calling {@link AppSearchSession#put}.
@@ -91,8 +91,7 @@ import java.util.function.Consumer;
* <pre>
* // Although for this example we use GenericDocument directly, we recommend extending
* // GenericDocument to create specific types (i.e. Email) with specific setters/getters.
- * GenericDocument email = new GenericDocument.Builder<>(URI, EMAIL_SCHEMA_TYPE)
- * .setNamespace(NAMESPACE)
+ * GenericDocument email = new GenericDocument.Builder<>(NAMESPACE, ID, EMAIL_SCHEMA_TYPE)
* .setPropertyString(“subject”, EMAIL_SUBJECT)
* .setScore(EMAIL_SCORE)
* .build();
@@ -108,13 +107,13 @@ import java.util.function.Consumer;
* <p>Searching within the database is done by calling {@link AppSearchSession#search} and providing
* the query string to search for, as well as a {@link SearchSpec}.
*
- * <p>Alternatively, {@link AppSearchSession#getByUri} can be called to retrieve documents by URI
- * and namespace.
+ * <p>Alternatively, {@link AppSearchSession#getByDocumentId} can be called to retrieve documents by
+ * namespace and ID.
*
* <p>Document removal is done either by time-to-live expiration, or explicitly calling a remove
- * operation. Remove operations can be done by URI and namespace via {@link
- * AppSearchSession#remove(RemoveByUriRequest, Executor, BatchResultCallback)}, or by query via
- * {@link AppSearchSession#remove(String, SearchSpec, Executor, Consumer)}.
+ * operation. Remove operations can be done by namespace and ID via {@link
+ * AppSearchSession#remove(RemoveByDocumentIdRequest, Executor, BatchResultCallback)}, or by query
+ * via {@link AppSearchSession#remove(String, SearchSpec, Executor, Consumer)}.
*/
@SystemService(Context.APP_SEARCH_SERVICE)
public class AppSearchManager {
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java
index c85c4c3a8a7f..1e0d205230ca 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java
@@ -41,10 +41,14 @@ import java.util.concurrent.Executor;
import java.util.function.Consumer;
/**
- * Represents a connection to an AppSearch storage system where {@link GenericDocument}s can be
- * placed and queried.
+ * Provides a connection to a single AppSearch database.
+ *
+ * <p>An {@link AppSearchSession} instance provides access to database operations such as
+ * setting a schema, adding documents, and searching.
*
* <p>This class is thread safe.
+ *
+ * @see GlobalSearchSession
*/
public final class AppSearchSession implements Closeable {
private static final String TAG = "AppSearchSession";
@@ -250,12 +254,12 @@ public final class AppSearchSession implements Closeable {
* @param request containing documents to be indexed.
* @param executor Executor on which to invoke the callback.
* @param callback Callback to receive pending result of performing this operation. The keys
- * of the returned {@link AppSearchBatchResult} are the URIs of the input
+ * of the returned {@link AppSearchBatchResult} are the IDs of the input
* documents. The values are {@code null} if they were successfully indexed,
- * or a failed {@link AppSearchResult} otherwise.
- * Or {@link BatchResultCallback#onSystemError} will be invoked with a
- * {@link Throwable} if an unexpected internal error occurred in AppSearch
- * service.
+ * or a failed {@link AppSearchResult} otherwise. If an unexpected internal
+ * error occurs in the AppSearch service,
+ * {@link BatchResultCallback#onSystemError} will be invoked with a
+ * {@link Throwable}.
*/
public void put(
@NonNull PutDocumentsRequest request,
@@ -291,23 +295,22 @@ public final class AppSearchSession implements Closeable {
}
/**
- * Gets {@link GenericDocument} objects by URIs and namespace from the {@link AppSearchSession}
- * database.
+ * Gets {@link GenericDocument} objects by document IDs in a namespace from the {@link
+ * AppSearchSession} database.
*
- * @param request a request containing URIs and namespace to get documents for.
+ * @param request a request containing a namespace and IDs to get documents for.
* @param executor Executor on which to invoke the callback.
* @param callback Callback to receive the pending result of performing this operation. The keys
- * of the returned {@link AppSearchBatchResult} are the input URIs. The values
+ * of the returned {@link AppSearchBatchResult} are the input IDs. The values
* are the returned {@link GenericDocument}s on success, or a failed
- * {@link AppSearchResult} otherwise. URIs that are not found will return a
+ * {@link AppSearchResult} otherwise. IDs that are not found will return a
* failed {@link AppSearchResult} with a result code of
- * {@link AppSearchResult#RESULT_NOT_FOUND}.
- * Or {@link BatchResultCallback#onSystemError} will be invoked with a
- * {@link Throwable} if an unexpected internal error occurred in AppSearch
- * service.
+ * {@link AppSearchResult#RESULT_NOT_FOUND}. If an unexpected internal error
+ * occurs in the AppSearch service, {@link BatchResultCallback#onSystemError}
+ * will be invoked with a {@link Throwable}.
*/
- public void getByUri(
- @NonNull GetByUriRequest request,
+ public void getByDocumentId(
+ @NonNull GetByDocumentIdRequest request,
@NonNull @CallbackExecutor Executor executor,
@NonNull BatchResultCallback<String, GenericDocument> callback) {
Objects.requireNonNull(request);
@@ -319,7 +322,7 @@ public final class AppSearchSession implements Closeable {
mPackageName,
mDatabaseName,
request.getNamespace(),
- new ArrayList<>(request.getUris()),
+ new ArrayList<>(request.getIds()),
request.getProjectionsInternal(),
mUserId,
new IAppSearchBatchResultCallback.Stub() {
@@ -373,8 +376,8 @@ public final class AppSearchSession implements Closeable {
}
/**
- * Retrieves documents from the open {@link AppSearchSession} that match a given query string
- * and type of search provided.
+ * Retrieves documents from the open {@link AppSearchSession} that match a given query
+ * string and type of search provided.
*
* <p>Query strings can be empty, contain one term with no operators, or contain multiple terms
* and operators.
@@ -441,7 +444,7 @@ public final class AppSearchSession implements Closeable {
}
/**
- * Reports usage of a particular document by URI and namespace.
+ * Reports usage of a particular document by namespace and ID.
*
* <p>A usage report represents an event in which a user interacted with or viewed a document.
*
@@ -470,8 +473,8 @@ public final class AppSearchSession implements Closeable {
mPackageName,
mDatabaseName,
request.getNamespace(),
- request.getUri(),
- request.getUsageTimeMillis(),
+ request.getDocumentId(),
+ request.getUsageTimestampMillis(),
/*systemUsage=*/ false,
mUserId,
new IAppSearchResultCallback.Stub() {
@@ -486,29 +489,29 @@ public final class AppSearchSession implements Closeable {
}
/**
- * Removes {@link GenericDocument} objects by URIs and namespace from the {@link
+ * Removes {@link GenericDocument} objects by document IDs in a namespace from the {@link
* AppSearchSession} database.
*
- * <p>Removed documents will no longer be surfaced by {@link #search} or {@link #getByUri}
- * calls.
+ * <p>Removed documents will no longer be surfaced by {@link #search} or {@link
+ * #getByDocumentId} calls.
*
- * <p><b>NOTE:</b>By default, documents are removed via a soft delete operation. Once the
- * document crosses the count threshold or byte usage threshold, the documents will be removed
- * from disk.
+ * <p>Once the database crosses the document count or byte usage threshold, removed documents
+ * will be deleted from disk.
*
- * @param request {@link RemoveByUriRequest} with URIs and namespace to remove from the index.
+ * @param request {@link RemoveByDocumentIdRequest} with IDs in a namespace to remove from the
+ * index.
* @param executor Executor on which to invoke the callback.
* @param callback Callback to receive the pending result of performing this operation. The keys
- * of the returned {@link AppSearchBatchResult} are the input URIs. The values
- * are {@code null} on success, or a failed {@link AppSearchResult} otherwise.
- * URIs that are not found will return a failed {@link AppSearchResult} with a
- * result code of {@link AppSearchResult#RESULT_NOT_FOUND}.
- * Or {@link BatchResultCallback#onSystemError} will be invoked with a
- * {@link Throwable} if an unexpected internal error occurred in AppSearch
- * service.
+ * of the returned {@link AppSearchBatchResult} are the input document IDs. The
+ * values are {@code null} on success, or a failed {@link AppSearchResult}
+ * otherwise. IDs that are not found will return a failed
+ * {@link AppSearchResult} with a result code of
+ * {@link AppSearchResult#RESULT_NOT_FOUND}. If an unexpected internal error
+ * occurs in the AppSearch service, {@link BatchResultCallback#onSystemError}
+ * will be invoked with a {@link Throwable}.
*/
public void remove(
- @NonNull RemoveByUriRequest request,
+ @NonNull RemoveByDocumentIdRequest request,
@NonNull @CallbackExecutor Executor executor,
@NonNull BatchResultCallback<String, Void> callback) {
Objects.requireNonNull(request);
@@ -516,8 +519,8 @@ public final class AppSearchSession implements Closeable {
Objects.requireNonNull(callback);
Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
try {
- mService.removeByUri(mPackageName, mDatabaseName, request.getNamespace(),
- new ArrayList<>(request.getUris()), mUserId,
+ mService.removeByDocumentId(mPackageName, mDatabaseName, request.getNamespace(),
+ new ArrayList<>(request.getIds()), mUserId,
new IAppSearchBatchResultCallback.Stub() {
@Override
public void onResult(AppSearchBatchResult result) {
@@ -581,8 +584,8 @@ public final class AppSearchSession implements Closeable {
/**
* Gets the storage info for this {@link AppSearchSession} database.
*
- * <p>This may take time proportional to the number of documents and may be inefficient to
- * call repeatedly.
+ * <p>This may take time proportional to the number of documents and may be inefficient to call
+ * repeatedly.
*
* @param executor Executor on which to invoke the callback.
* @param callback Callback to receive the storage info.
@@ -618,8 +621,8 @@ public final class AppSearchSession implements Closeable {
}
/**
- * Closes the {@link AppSearchSession} to persist all schema and document updates, additions,
- * and deletes to disk.
+ * Closes the {@link AppSearchSession} to persist all schema and document updates,
+ * additions, and deletes to disk.
*/
@Override
public void close() {
diff --git a/apex/appsearch/framework/java/android/app/appsearch/GlobalSearchSession.java b/apex/appsearch/framework/java/android/app/appsearch/GlobalSearchSession.java
index b30ed50b8240..d49f47271055 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/GlobalSearchSession.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/GlobalSearchSession.java
@@ -31,9 +31,12 @@ import java.util.concurrent.Executor;
import java.util.function.Consumer;
/**
- * This class provides global access to the centralized AppSearch index maintained by the system.
+ * Provides a connection to all AppSearch databases the querying application has been granted access
+ * to.
*
- * <p>Apps can retrieve indexed documents through the {@link #search} API.
+ * <p>This class is thread safe.
+ *
+ * @see AppSearchSession
*/
public class GlobalSearchSession implements Closeable {
private static final String TAG = "AppSearchGlobalSearchSe";
@@ -151,8 +154,8 @@ public class GlobalSearchSession implements Closeable {
request.getPackageName(),
request.getDatabaseName(),
request.getNamespace(),
- request.getUri(),
- request.getUsageTimeMillis(),
+ request.getDocumentId(),
+ request.getUsageTimestampMillis(),
/*systemUsage=*/ true,
mUserId,
new IAppSearchResultCallback.Stub() {
diff --git a/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl b/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl
index 0b8f0523ab56..17f724b3a6f5 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl
+++ b/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl
@@ -100,7 +100,7 @@ interface IAppSearchManager {
* will be called with the cause throwable. Otherwise,
* {@link IAppSearchBatchResultCallback#onResult} will be called with an
* {@link AppSearchBatchResult}&lt;{@link String}, {@link Void}&gt;
- * where the keys are document URIs, and the values are {@code null}.
+ * where the keys are document IDs, and the values are {@code null}.
*/
void putDocuments(
in String packageName,
@@ -116,7 +116,7 @@ interface IAppSearchManager {
* @param packageName The name of the package that owns this document.
* @param databaseName The databaseName this document resides in.
* @param namespace The namespace this document resides in.
- * @param uris The URIs of the documents to retrieve
+ * @param ids The IDs of the documents to retrieve
* @param typePropertyPaths A map of schema type to a list of property paths to return in the
* result.
* @param userId Id of the calling user
@@ -125,13 +125,13 @@ interface IAppSearchManager {
* will be called with the cause throwable. Otherwise,
* {@link IAppSearchBatchResultCallback#onResult} will be called with an
* {@link AppSearchBatchResult}&lt;{@link String}, {@link Bundle}&gt;
- * where the keys are document URIs, and the values are Document bundles.
+ * where the keys are document IDs, and the values are Document bundles.
*/
void getDocuments(
in String packageName,
in String databaseName,
in String namespace,
- in List<String> uris,
+ in List<String> ids,
in Map<String, List<String>> typePropertyPaths,
in int userId,
in IAppSearchBatchResultCallback callback);
@@ -235,7 +235,7 @@ interface IAppSearchManager {
in IAppSearchResultCallback callback);
/**
- * Reports usage of a particular document by URI and namespace.
+ * Reports usage of a particular document by namespace and id.
*
* <p>A usage report represents an event in which a user interacted with or viewed a document.
*
@@ -249,8 +249,8 @@ interface IAppSearchManager {
* @param packageName The name of the package that owns this document.
* @param databaseName The name of the database to report usage against.
* @param namespace Namespace the document being used belongs to.
- * @param uri URI of the document being used.
- * @param usageTimeMillis The timestamp at which the document was used.
+ * @param id ID of the document being used.
+ * @param usageTimestampMillis The timestamp at which the document was used.
* @param systemUsage Whether the usage was reported by a system app against another app's doc.
* @param userId Id of the calling user
* @param callback {@link IAppSearchResultCallback#onResult} will be called with an
@@ -260,33 +260,33 @@ interface IAppSearchManager {
in String packageName,
in String databaseName,
in String namespace,
- in String uri,
- in long usageTimeMillis,
+ in String id,
+ in long usageTimestampMillis,
in boolean systemUsage,
in int userId,
in IAppSearchResultCallback callback);
/**
- * Removes documents by URI.
+ * Removes documents by ID.
*
* @param packageName The name of the package the document is in.
* @param databaseName The databaseName the document is in.
* @param namespace Namespace of the document to remove.
- * @param uris The URIs of the documents to delete
+ * @param ids The IDs of the documents to delete
* @param userId Id of the calling user
* @param callback
* If the call fails to start, {@link IAppSearchBatchResultCallback#onSystemError}
* will be called with the cause throwable. Otherwise,
* {@link IAppSearchBatchResultCallback#onResult} will be called with an
* {@link AppSearchBatchResult}&lt;{@link String}, {@link Void}&gt;
- * where the keys are document URIs. If a document doesn't exist, it will be reported as a
+ * where the keys are document IDs. If a document doesn't exist, it will be reported as a
* failure where the {@code throwable} is {@code null}.
*/
- void removeByUri(
+ void removeByDocumentId(
in String packageName,
in String databaseName,
in String namespace,
- in List<String> uris,
+ in List<String> ids,
in int userId,
in IAppSearchBatchResultCallback callback);
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchEmail.java b/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchEmail.java
index 77740f88de7a..d99c73f8f64b 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchEmail.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchEmail.java
@@ -156,10 +156,10 @@ public class AppSearchEmail extends GenericDocument {
* Creates a new {@link AppSearchEmail.Builder}
*
* @param namespace The namespace of the Email.
- * @param uri The Uri of the Email.
+ * @param id The ID of the Email.
*/
- public Builder(@NonNull String namespace, @NonNull String uri) {
- super(namespace, uri, SCHEMA_TYPE);
+ public Builder(@NonNull String namespace, @NonNull String id) {
+ super(namespace, id, SCHEMA_TYPE);
}
/** Sets the from address of {@link AppSearchEmail} */
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchSchema.java b/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchSchema.java
index 2368bdb7466d..2a941fb54833 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchSchema.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchSchema.java
@@ -273,7 +273,7 @@ public final class AppSearchSchema {
* Returns the cardinality of the property (whether it is optional, required or repeated).
*/
public @Cardinality int getCardinality() {
- return mBundle.getInt(CARDINALITY_FIELD, -1);
+ return mBundle.getInt(CARDINALITY_FIELD, CARDINALITY_OPTIONAL);
}
@Override
@@ -407,11 +407,7 @@ public final class AppSearchSchema {
return mBundle.getInt(TOKENIZER_TYPE_FIELD);
}
- /**
- * Builder for {@link StringPropertyConfig}.
- *
- * <p>{@link #setCardinality} must be called or {@link #build} will fail.
- */
+ /** Builder for {@link StringPropertyConfig}. */
public static final class Builder {
private final Bundle mBundle = new Bundle();
private boolean mBuilt = false;
@@ -420,12 +416,16 @@ public final class AppSearchSchema {
public Builder(@NonNull String propertyName) {
mBundle.putString(NAME_FIELD, propertyName);
mBundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_STRING);
+ mBundle.putInt(CARDINALITY_FIELD, CARDINALITY_OPTIONAL);
+ mBundle.putInt(INDEXING_TYPE_FIELD, INDEXING_TYPE_NONE);
+ mBundle.putInt(TOKENIZER_TYPE_FIELD, TOKENIZER_TYPE_NONE);
}
/**
* The cardinality of the property (whether it is optional, required or repeated).
*
- * <p>This property must be set.
+ * <p>If this method is not called, the default cardinality is {@link
+ * PropertyConfig#CARDINALITY_OPTIONAL}.
*/
@SuppressWarnings("MissingGetterMatchingBuilder") // getter defined in superclass
@NonNull
@@ -439,6 +439,9 @@ public final class AppSearchSchema {
/**
* Configures how a property should be indexed so that it can be retrieved by queries.
+ *
+ * <p>If this method is not called, the default indexing type is {@link
+ * StringPropertyConfig#INDEXING_TYPE_NONE}, so that it cannot be matched by queries.
*/
@NonNull
public StringPropertyConfig.Builder setIndexingType(@IndexingType int indexingType) {
@@ -449,7 +452,17 @@ public final class AppSearchSchema {
return this;
}
- /** Configures how this property should be tokenized (split into words). */
+ /**
+ * Configures how this property should be tokenized (split into words).
+ *
+ * <p>If this method is not called, the default indexing type is {@link
+ * StringPropertyConfig#TOKENIZER_TYPE_NONE}, so that it is not tokenized.
+ *
+ * <p>This method must be called with a value other than {@link
+ * StringPropertyConfig#TOKENIZER_TYPE_NONE} if the property is indexed (i.e. if {@link
+ * #setIndexingType} has been called with a value other than {@link
+ * StringPropertyConfig#INDEXING_TYPE_NONE}).
+ */
@NonNull
public StringPropertyConfig.Builder setTokenizerType(@TokenizerType int tokenizerType) {
Preconditions.checkState(!mBuilt, "Builder has already been used");
@@ -464,16 +477,11 @@ public final class AppSearchSchema {
*
* <p>After calling this method, the builder must no longer be used.
*
- * @throws IllegalSchemaException if the property is not correctly populated
+ * @throws IllegalStateException if the builder has already been used
*/
@NonNull
public StringPropertyConfig build() {
Preconditions.checkState(!mBuilt, "Builder has already been used");
- // TODO(b/147692920): Send the schema to Icing Lib for official validation, instead
- // of partially reimplementing some of the validation Icing does here.
- if (!mBundle.containsKey(CARDINALITY_FIELD)) {
- throw new IllegalSchemaException("Missing field: cardinality");
- }
mBuilt = true;
return new StringPropertyConfig(mBundle);
}
@@ -486,11 +494,7 @@ public final class AppSearchSchema {
super(bundle);
}
- /**
- * Builder for {@link Int64PropertyConfig}.
- *
- * <p>{@link #setCardinality} must be called or {@link #build} will fail.
- */
+ /** Builder for {@link Int64PropertyConfig}. */
public static final class Builder {
private final Bundle mBundle = new Bundle();
private boolean mBuilt = false;
@@ -499,12 +503,14 @@ public final class AppSearchSchema {
public Builder(@NonNull String propertyName) {
mBundle.putString(NAME_FIELD, propertyName);
mBundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_INT64);
+ mBundle.putInt(CARDINALITY_FIELD, CARDINALITY_OPTIONAL);
}
/**
* The cardinality of the property (whether it is optional, required or repeated).
*
- * <p>This property must be set.
+ * <p>If this method is not called, the default cardinality is {@link
+ * PropertyConfig#CARDINALITY_OPTIONAL}.
*/
@SuppressWarnings("MissingGetterMatchingBuilder") // getter defined in superclass
@NonNull
@@ -521,14 +527,11 @@ public final class AppSearchSchema {
*
* <p>After calling this method, the builder must no longer be used.
*
- * @throws IllegalSchemaException if the property is not correctly populated
+ * @throws IllegalStateException if the builder has already been used
*/
@NonNull
public Int64PropertyConfig build() {
Preconditions.checkState(!mBuilt, "Builder has already been used");
- if (!mBundle.containsKey(CARDINALITY_FIELD)) {
- throw new IllegalSchemaException("Missing field: cardinality");
- }
mBuilt = true;
return new Int64PropertyConfig(mBundle);
}
@@ -541,11 +544,7 @@ public final class AppSearchSchema {
super(bundle);
}
- /**
- * Builder for {@link DoublePropertyConfig}.
- *
- * <p>{@link #setCardinality} must be called or {@link #build} will fail.
- */
+ /** Builder for {@link DoublePropertyConfig}. */
public static final class Builder {
private final Bundle mBundle = new Bundle();
private boolean mBuilt = false;
@@ -554,12 +553,14 @@ public final class AppSearchSchema {
public Builder(@NonNull String propertyName) {
mBundle.putString(NAME_FIELD, propertyName);
mBundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_DOUBLE);
+ mBundle.putInt(CARDINALITY_FIELD, CARDINALITY_OPTIONAL);
}
/**
* The cardinality of the property (whether it is optional, required or repeated).
*
- * <p>This property must be set.
+ * <p>If this method is not called, the default cardinality is {@link
+ * PropertyConfig#CARDINALITY_OPTIONAL}.
*/
@SuppressWarnings("MissingGetterMatchingBuilder") // getter defined in superclass
@NonNull
@@ -576,14 +577,11 @@ public final class AppSearchSchema {
*
* <p>After calling this method, the builder must no longer be used.
*
- * @throws IllegalSchemaException if the property is not correctly populated
+ * @throws IllegalStateException if the builder has already been used
*/
@NonNull
public DoublePropertyConfig build() {
Preconditions.checkState(!mBuilt, "Builder has already been used");
- if (!mBundle.containsKey(CARDINALITY_FIELD)) {
- throw new IllegalSchemaException("Missing field: cardinality");
- }
mBuilt = true;
return new DoublePropertyConfig(mBundle);
}
@@ -596,11 +594,7 @@ public final class AppSearchSchema {
super(bundle);
}
- /**
- * Builder for {@link BooleanPropertyConfig}.
- *
- * <p>{@link #setCardinality} must be called or {@link #build} will fail.
- */
+ /** Builder for {@link BooleanPropertyConfig}. */
public static final class Builder {
private final Bundle mBundle = new Bundle();
private boolean mBuilt = false;
@@ -609,12 +603,14 @@ public final class AppSearchSchema {
public Builder(@NonNull String propertyName) {
mBundle.putString(NAME_FIELD, propertyName);
mBundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_BOOLEAN);
+ mBundle.putInt(CARDINALITY_FIELD, CARDINALITY_OPTIONAL);
}
/**
* The cardinality of the property (whether it is optional, required or repeated).
*
- * <p>This property must be set.
+ * <p>If this method is not called, the default cardinality is {@link
+ * PropertyConfig#CARDINALITY_OPTIONAL}.
*/
@SuppressWarnings("MissingGetterMatchingBuilder") // getter defined in superclass
@NonNull
@@ -631,14 +627,11 @@ public final class AppSearchSchema {
*
* <p>After calling this method, the builder must no longer be used.
*
- * @throws IllegalSchemaException if the property is not correctly populated
+ * @throws IllegalStateException if the builder has already been used
*/
@NonNull
public BooleanPropertyConfig build() {
Preconditions.checkState(!mBuilt, "Builder has already been used");
- if (!mBundle.containsKey(CARDINALITY_FIELD)) {
- throw new IllegalSchemaException("Missing field: cardinality");
- }
mBuilt = true;
return new BooleanPropertyConfig(mBundle);
}
@@ -651,11 +644,7 @@ public final class AppSearchSchema {
super(bundle);
}
- /**
- * Builder for {@link BytesPropertyConfig}.
- *
- * <p>{@link #setCardinality} must be called or {@link #build} will fail.
- */
+ /** Builder for {@link BytesPropertyConfig}. */
public static final class Builder {
private final Bundle mBundle = new Bundle();
private boolean mBuilt = false;
@@ -664,12 +653,14 @@ public final class AppSearchSchema {
public Builder(@NonNull String propertyName) {
mBundle.putString(NAME_FIELD, propertyName);
mBundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_BYTES);
+ mBundle.putInt(CARDINALITY_FIELD, CARDINALITY_OPTIONAL);
}
/**
* The cardinality of the property (whether it is optional, required or repeated).
*
- * <p>This property must be set.
+ * <p>If this method is not called, the default cardinality is {@link
+ * PropertyConfig#CARDINALITY_OPTIONAL}.
*/
@SuppressWarnings("MissingGetterMatchingBuilder") // getter defined in superclass
@NonNull
@@ -686,14 +677,11 @@ public final class AppSearchSchema {
*
* <p>After calling this method, the builder must no longer be used.
*
- * @throws IllegalSchemaException if the property is not correctly populated
+ * @throws IllegalStateException if the builder has already been used
*/
@NonNull
public BytesPropertyConfig build() {
Preconditions.checkState(!mBuilt, "Builder has already been used");
- if (!mBundle.containsKey(CARDINALITY_FIELD)) {
- throw new IllegalSchemaException("Missing field: cardinality");
- }
mBuilt = true;
return new BytesPropertyConfig(mBundle);
}
@@ -722,7 +710,7 @@ public final class AppSearchSchema {
* <p>If false, the nested document's properties are not indexed regardless of its own
* schema.
*/
- public boolean isIndexNestedProperties() {
+ public boolean shouldIndexNestedProperties() {
return mBundle.getBoolean(INDEX_NESTED_PROPERTIES_FIELD);
}
@@ -741,29 +729,28 @@ public final class AppSearchSchema {
private final Bundle mBundle = new Bundle();
private boolean mBuilt = false;
- /** Creates a new {@link DocumentPropertyConfig.Builder}. */
- public Builder(@NonNull String propertyName) {
- mBundle.putString(NAME_FIELD, propertyName);
- mBundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_DOCUMENT);
- }
-
/**
- * The logical schema-type of the contents of this property.
+ * Creates a new {@link DocumentPropertyConfig.Builder}.
*
- * <p>This property must be set.
+ * @param propertyName The logical name of the property in the schema, which will be
+ * used as the key for this property in {@link
+ * GenericDocument.Builder#setPropertyDocument}.
+ * @param schemaType The type of documents which will be stored in this property.
+ * Documents of different types cannot be mixed into a single property.
*/
- @NonNull
- public DocumentPropertyConfig.Builder setSchemaType(@NonNull String schemaType) {
- Preconditions.checkState(!mBuilt, "Builder has already been used");
- Objects.requireNonNull(schemaType);
+ public Builder(@NonNull String propertyName, @NonNull String schemaType) {
+ mBundle.putString(NAME_FIELD, propertyName);
+ mBundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_DOCUMENT);
+ mBundle.putInt(CARDINALITY_FIELD, CARDINALITY_OPTIONAL);
+ mBundle.putBoolean(INDEX_NESTED_PROPERTIES_FIELD, false);
mBundle.putString(SCHEMA_TYPE_FIELD, schemaType);
- return this;
}
/**
* The cardinality of the property (whether it is optional, required or repeated).
*
- * <p>This property must be set.
+ * <p>If this method is not called, the default cardinality is {@link
+ * PropertyConfig#CARDINALITY_OPTIONAL}.
*/
@SuppressWarnings("MissingGetterMatchingBuilder") // getter defined in superclass
@NonNull
@@ -783,7 +770,7 @@ public final class AppSearchSchema {
* schema.
*/
@NonNull
- public DocumentPropertyConfig.Builder setIndexNestedProperties(
+ public DocumentPropertyConfig.Builder setShouldIndexNestedProperties(
boolean indexNestedProperties) {
Preconditions.checkState(!mBuilt, "Builder has already been used");
mBundle.putBoolean(INDEX_NESTED_PROPERTIES_FIELD, indexNestedProperties);
@@ -795,18 +782,12 @@ public final class AppSearchSchema {
*
* <p>After calling this method, the builder must no longer be used.
*
- * @throws IllegalSchemaException If the property is not correctly populated (e.g.
- * missing {@code dataType}).
+ * @throws IllegalStateException if the builder has already been used (e.g. missing
+ * {@code dataType}).
*/
@NonNull
public DocumentPropertyConfig build() {
Preconditions.checkState(!mBuilt, "Builder has already been used");
- if (mBundle.getString(SCHEMA_TYPE_FIELD, "").isEmpty()) {
- throw new IllegalSchemaException("Missing field: schemaType");
- }
- if (!mBundle.containsKey(CARDINALITY_FIELD)) {
- throw new IllegalSchemaException("Missing field: cardinality");
- }
mBuilt = true;
return new DocumentPropertyConfig(mBundle);
}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/GenericDocument.java b/apex/appsearch/framework/java/external/android/app/appsearch/GenericDocument.java
index e3b3a859981d..85018ad6e9db 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/GenericDocument.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/GenericDocument.java
@@ -16,6 +16,7 @@
package android.app.appsearch;
+import android.annotation.CurrentTimeMillisLong;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -31,6 +32,7 @@ import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.List;
import java.util.Objects;
import java.util.Set;
@@ -38,10 +40,12 @@ import java.util.Set;
* Represents a document unit.
*
* <p>Documents contain structured data conforming to their {@link AppSearchSchema} type. Each
- * document is uniquely identified by a URI and namespace.
+ * document is uniquely identified by a namespace and a String ID within that namespace.
+ *
+ * <p>Documents are constructed by using the {@link GenericDocument.Builder}.
*
* @see AppSearchSession#put
- * @see AppSearchSession#getByUri
+ * @see AppSearchSession#getByDocumentId
* @see AppSearchSession#search
*/
public class GenericDocument {
@@ -65,7 +69,7 @@ public class GenericDocument {
private static final String PROPERTIES_FIELD = "properties";
private static final String BYTE_ARRAY_FIELD = "byteArray";
private static final String SCHEMA_TYPE_FIELD = "schemaType";
- private static final String URI_FIELD = "uri";
+ private static final String ID_FIELD = "id";
private static final String SCORE_FIELD = "score";
private static final String TTL_MILLIS_FIELD = "ttlMillis";
private static final String CREATION_TIMESTAMP_MILLIS_FIELD = "creationTimestampMillis";
@@ -82,30 +86,33 @@ public class GenericDocument {
return MAX_INDEXED_PROPERTIES;
}
- /** Contains {@link GenericDocument} basic information (uri, schemaType etc). */
+ /**
+ * Contains all {@link GenericDocument} information in a packaged format.
+ *
+ * <p>Keys are the {@code *_FIELD} constants in this class.
+ */
@NonNull final Bundle mBundle;
- /** Contains all properties in {@link GenericDocument} to support getting properties via keys */
+ /** Contains all properties in {@link GenericDocument} to support getting properties via name */
@NonNull private final Bundle mProperties;
- @NonNull private final String mUri;
+ @NonNull private final String mId;
@NonNull private final String mSchemaType;
private final long mCreationTimestampMillis;
@Nullable private Integer mHashCode;
/**
- * Rebuilds a {@link GenericDocument} by the a bundle.
+ * Rebuilds a {@link GenericDocument} from a bundle.
*
- * @param bundle Contains {@link GenericDocument} basic information (uri, schemaType etc) and a
- * properties bundle contains all properties in {@link GenericDocument} to support getting
- * properties via keys.
+ * @param bundle Packaged {@link GenericDocument} data, such as the result of {@link
+ * #getBundle}.
* @hide
*/
public GenericDocument(@NonNull Bundle bundle) {
Objects.requireNonNull(bundle);
mBundle = bundle;
mProperties = Objects.requireNonNull(bundle.getParcelable(PROPERTIES_FIELD));
- mUri = Objects.requireNonNull(mBundle.getString(URI_FIELD));
+ mId = Objects.requireNonNull(mBundle.getString(ID_FIELD));
mSchemaType = Objects.requireNonNull(mBundle.getString(SCHEMA_TYPE_FIELD));
mCreationTimestampMillis =
mBundle.getLong(CREATION_TIMESTAMP_MILLIS_FIELD, System.currentTimeMillis());
@@ -130,10 +137,10 @@ public class GenericDocument {
return mBundle;
}
- /** Returns the URI of the {@link GenericDocument}. */
+ /** Returns the unique identifier of the {@link GenericDocument}. */
@NonNull
- public String getUri() {
- return mUri;
+ public String getId() {
+ return mId;
}
/** Returns the namespace of the {@link GenericDocument}. */
@@ -153,6 +160,7 @@ public class GenericDocument {
*
* <p>The value is in the {@link System#currentTimeMillis} time base.
*/
+ @CurrentTimeMillisLong
public long getCreationTimestampMillis() {
return mCreationTimestampMillis;
}
@@ -193,136 +201,517 @@ public class GenericDocument {
}
/**
- * Retrieves the property value with the given key as {@link Object}.
+ * Retrieves the property value with the given path as {@link Object}.
+ *
+ * <p>A path can be a simple property name, such as those returned by {@link #getPropertyNames}.
+ * It may also be a dot-delimited path through the nested document hierarchy, with nested {@link
+ * GenericDocument} properties accessed via {@code '.'} and repeated properties optionally
+ * indexed into via {@code [n]}.
+ *
+ * <p>For example, given the following {@link GenericDocument}:
+ *
+ * <pre>
+ * (Message) {
+ * from: "sender@example.com"
+ * to: [{
+ * name: "Albert Einstein"
+ * email: "einstein@example.com"
+ * }, {
+ * name: "Marie Curie"
+ * email: "curie@example.com"
+ * }]
+ * tags: ["important", "inbox"]
+ * subject: "Hello"
+ * }
+ * </pre>
+ *
+ * <p>Here are some example paths and their results:
+ *
+ * <ul>
+ * <li>{@code "from"} returns {@code "sender@example.com"} as a {@link String} array with one
+ * element
+ * <li>{@code "to"} returns the two nested documents containing contact information as a
+ * {@link GenericDocument} array with two elements
+ * <li>{@code "to[1]"} returns the second nested document containing Marie Curie's contact
+ * information as a {@link GenericDocument} array with one element
+ * <li>{@code "to[1].email"} returns {@code "curie@example.com"}
+ * <li>{@code "to[100].email"} returns {@code null} as this particular document does not have
+ * that many elements in its {@code "to"} array.
+ * <li>{@code "to.email"} aggregates emails across all nested documents that have them,
+ * returning {@code ["einstein@example.com", "curie@example.com"]} as a {@link String}
+ * array with two elements.
+ * </ul>
+ *
+ * <p>If you know the expected type of the property you are retrieving, it is recommended to use
+ * one of the typed versions of this method instead, such as {@link #getPropertyString} or
+ * {@link #getPropertyStringArray}.
+ *
+ * @param path The path to look for.
+ * @return The entry with the given path as an object or {@code null} if there is no such path.
+ * The returned object will be one of the following types: {@code String[]}, {@code long[]},
+ * {@code double[]}, {@code boolean[]}, {@code byte[][]}, {@code GenericDocument[]}.
+ */
+ @Nullable
+ public Object getProperty(@NonNull String path) {
+ Objects.requireNonNull(path);
+ Object rawValue = getRawPropertyFromRawDocument(path, mBundle);
+
+ // Unpack the raw value into the types the user expects, if required.
+ if (rawValue instanceof Bundle) {
+ // getRawPropertyFromRawDocument may return a document as a bare Bundle as a performance
+ // optimization for lookups.
+ GenericDocument document = new GenericDocument((Bundle) rawValue);
+ return new GenericDocument[] {document};
+ }
+
+ if (rawValue instanceof List) {
+ // byte[][] fields are packed into List<Bundle> where each Bundle contains just a single
+ // entry: BYTE_ARRAY_FIELD -> byte[].
+ @SuppressWarnings("unchecked")
+ List<Bundle> bundles = (List<Bundle>) rawValue;
+ if (bundles.size() == 0) {
+ return null;
+ }
+ byte[][] bytes = new byte[bundles.size()][];
+ for (int i = 0; i < bundles.size(); i++) {
+ Bundle bundle = bundles.get(i);
+ if (bundle == null) {
+ Log.e(TAG, "The inner bundle is null at " + i + ", for path: " + path);
+ continue;
+ }
+ byte[] innerBytes = bundle.getByteArray(BYTE_ARRAY_FIELD);
+ if (innerBytes == null) {
+ Log.e(TAG, "The bundle at " + i + " contains a null byte[].");
+ continue;
+ }
+ bytes[i] = innerBytes;
+ }
+ return bytes;
+ }
+
+ if (rawValue instanceof Parcelable[]) {
+ // The underlying Bundle of nested GenericDocuments is packed into a Parcelable array.
+ // We must unpack it into GenericDocument instances.
+ Parcelable[] bundles = (Parcelable[]) rawValue;
+ if (bundles.length == 0) {
+ return null;
+ }
+ GenericDocument[] documents = new GenericDocument[bundles.length];
+ for (int i = 0; i < bundles.length; i++) {
+ if (bundles[i] == null) {
+ Log.e(TAG, "The inner bundle is null at " + i + ", for path: " + path);
+ continue;
+ }
+ if (!(bundles[i] instanceof Bundle)) {
+ Log.e(
+ TAG,
+ "The inner element at "
+ + i
+ + " is a "
+ + bundles[i].getClass()
+ + ", not a Bundle for path: "
+ + path);
+ continue;
+ }
+ documents[i] = new GenericDocument((Bundle) bundles[i]);
+ }
+ return documents;
+ }
+
+ // Otherwise the raw property is the same as the final property and needs no transformation.
+ return rawValue;
+ }
+
+ /**
+ * Looks up a property path within the given document bundle.
+ *
+ * <p>The return value may be any of GenericDocument's internal repeated storage types
+ * (String[], long[], double[], boolean[], ArrayList&lt;Bundle&gt;, Parcelable[]).
+ */
+ @Nullable
+ private static Object getRawPropertyFromRawDocument(
+ @NonNull String path, @NonNull Bundle documentBundle) {
+ Objects.requireNonNull(path);
+ Objects.requireNonNull(documentBundle);
+ Bundle properties = Objects.requireNonNull(documentBundle.getBundle(PROPERTIES_FIELD));
+
+ // Determine whether the path is just a raw property name with no control characters
+ int controlIdx = -1;
+ boolean controlIsIndex = false;
+ for (int i = 0; i < path.length(); i++) {
+ char c = path.charAt(i);
+ if (c == '[' || c == '.') {
+ controlIdx = i;
+ controlIsIndex = c == '[';
+ break;
+ }
+ }
+
+ // Look up the value of the first path element
+ Object firstElementValue;
+ if (controlIdx == -1) {
+ firstElementValue = properties.get(path);
+ } else {
+ String name = path.substring(0, controlIdx);
+ firstElementValue = properties.get(name);
+ }
+
+ // If the path has no further elements, we're done.
+ if (firstElementValue == null || controlIdx == -1) {
+ return firstElementValue;
+ }
+
+ // At this point, for a path like "recipients[0]", firstElementValue contains the value of
+ // "recipients". If the first element of the path is an indexed value, we now update
+ // firstElementValue to contain "recipients[0]" instead.
+ String remainingPath;
+ if (!controlIsIndex) {
+ // Remaining path is everything after the .
+ remainingPath = path.substring(controlIdx + 1);
+ } else {
+ int endBracketIdx = path.indexOf(']', controlIdx);
+ if (endBracketIdx == -1) {
+ throw new IllegalArgumentException("Malformed path (no ending ']'): " + path);
+ }
+ if (endBracketIdx + 1 < path.length() && path.charAt(endBracketIdx + 1) != '.') {
+ throw new IllegalArgumentException(
+ "Malformed path (']' not followed by '.'): " + path);
+ }
+ String indexStr = path.substring(controlIdx + 1, endBracketIdx);
+ int index = Integer.parseInt(indexStr);
+ if (index < 0) {
+ throw new IllegalArgumentException("Path index less than 0: " + path);
+ }
+
+ // Remaining path is everything after the [n]
+ if (endBracketIdx + 1 < path.length()) {
+ // More path remains, and we've already checked that charAt(endBracketIdx+1) == .
+ remainingPath = path.substring(endBracketIdx + 2);
+ } else {
+ // No more path remains.
+ remainingPath = null;
+ }
+
+ // Extract the right array element
+ Object extractedValue = null;
+ if (firstElementValue instanceof String[]) {
+ String[] stringValues = (String[]) firstElementValue;
+ if (index < stringValues.length) {
+ extractedValue = Arrays.copyOfRange(stringValues, index, index + 1);
+ }
+ } else if (firstElementValue instanceof long[]) {
+ long[] longValues = (long[]) firstElementValue;
+ if (index < longValues.length) {
+ extractedValue = Arrays.copyOfRange(longValues, index, index + 1);
+ }
+ } else if (firstElementValue instanceof double[]) {
+ double[] doubleValues = (double[]) firstElementValue;
+ if (index < doubleValues.length) {
+ extractedValue = Arrays.copyOfRange(doubleValues, index, index + 1);
+ }
+ } else if (firstElementValue instanceof boolean[]) {
+ boolean[] booleanValues = (boolean[]) firstElementValue;
+ if (index < booleanValues.length) {
+ extractedValue = Arrays.copyOfRange(booleanValues, index, index + 1);
+ }
+ } else if (firstElementValue instanceof List) {
+ @SuppressWarnings("unchecked")
+ List<Bundle> bundles = (List<Bundle>) firstElementValue;
+ if (index < bundles.size()) {
+ extractedValue = bundles.subList(index, index + 1);
+ }
+ } else if (firstElementValue instanceof Parcelable[]) {
+ // Special optimization: to avoid creating new singleton arrays for traversing paths
+ // we return the bare document Bundle in this particular case.
+ Parcelable[] bundles = (Parcelable[]) firstElementValue;
+ if (index < bundles.length) {
+ extractedValue = (Bundle) bundles[index];
+ }
+ } else {
+ throw new IllegalStateException("Unsupported value type: " + firstElementValue);
+ }
+ firstElementValue = extractedValue;
+ }
+
+ // If we are at the end of the path or there are no deeper elements in this document, we
+ // have nothing to recurse into.
+ if (firstElementValue == null || remainingPath == null) {
+ return firstElementValue;
+ }
+
+ // More of the path remains; recursively evaluate it
+ if (firstElementValue instanceof Bundle) {
+ return getRawPropertyFromRawDocument(remainingPath, (Bundle) firstElementValue);
+ } else if (firstElementValue instanceof Parcelable[]) {
+ Parcelable[] parcelables = (Parcelable[]) firstElementValue;
+ if (parcelables.length == 1) {
+ return getRawPropertyFromRawDocument(remainingPath, (Bundle) parcelables[0]);
+ }
+
+ // Slowest path: we're collecting values across repeated nested docs. (Example: given a
+ // path like recipient.name, where recipient is a repeated field, we return a string
+ // array where each recipient's name is an array element).
+ //
+ // Performance note: Suppose that we have a property path "a.b.c" where the "a"
+ // property has N document values and each containing a "b" property with M document
+ // values and each of those containing a "c" property with an int array.
+ //
+ // We'll allocate a new ArrayList for each of the "b" properties, add the M int arrays
+ // from the "c" properties to it and then we'll allocate an int array in
+ // flattenAccumulator before returning that (1 + M allocation per "b" property).
+ //
+ // When we're on the "a" properties, we'll allocate an ArrayList and add the N
+ // flattened int arrays returned from the "b" properties to the list. Then we'll
+ // allocate an int array in flattenAccumulator (1 + N ("b" allocs) allocations per "a").
+ // So this implementation could incur 1 + N + NM allocs.
+ //
+ // However, we expect the vast majority of getProperty calls to be either for direct
+ // property names (not paths) or else property paths returned from snippetting, which
+ // always refer to exactly one property value and don't aggregate across repeated
+ // values. The implementation is optimized for these two cases, requiring no additional
+ // allocations. So we've decided that the above performance characteristics are OK for
+ // the less used path.
+ List<Object> accumulator = new ArrayList<>(parcelables.length);
+ for (int i = 0; i < parcelables.length; i++) {
+ Object value =
+ getRawPropertyFromRawDocument(remainingPath, (Bundle) parcelables[i]);
+ if (value != null) {
+ accumulator.add(value);
+ }
+ }
+ return flattenAccumulator(accumulator);
+ } else {
+ Log.e(TAG, "Failed to apply path to document; no nested value found: " + path);
+ return null;
+ }
+ }
+
+ /**
+ * Combines accumulated repeated properties from multiple documents into a single array.
*
- * @param key The key to look for.
- * @return The entry with the given key as an object or {@code null} if there is no such key.
+ * @param accumulator List containing objects of the following types: {@code String[]}, {@code
+ * long[]}, {@code double[]}, {@code boolean[]}, {@code List<Bundle>}, or {@code
+ * Parcelable[]}.
+ * @return The result of concatenating each individual list element into a larger array/list of
+ * the same type.
*/
@Nullable
- public Object getProperty(@NonNull String key) {
- Objects.requireNonNull(key);
- Object property = mProperties.get(key);
- if (property instanceof ArrayList) {
- return getPropertyBytesArray(key);
- } else if (property instanceof Parcelable[]) {
- return getPropertyDocumentArray(key);
+ private static Object flattenAccumulator(@NonNull List<Object> accumulator) {
+ if (accumulator.isEmpty()) {
+ return null;
}
- return property;
+ Object first = accumulator.get(0);
+ if (first instanceof String[]) {
+ int length = 0;
+ for (int i = 0; i < accumulator.size(); i++) {
+ length += ((String[]) accumulator.get(i)).length;
+ }
+ String[] result = new String[length];
+ int total = 0;
+ for (int i = 0; i < accumulator.size(); i++) {
+ String[] castValue = (String[]) accumulator.get(i);
+ System.arraycopy(castValue, 0, result, total, castValue.length);
+ total += castValue.length;
+ }
+ return result;
+ }
+ if (first instanceof long[]) {
+ int length = 0;
+ for (int i = 0; i < accumulator.size(); i++) {
+ length += ((long[]) accumulator.get(i)).length;
+ }
+ long[] result = new long[length];
+ int total = 0;
+ for (int i = 0; i < accumulator.size(); i++) {
+ long[] castValue = (long[]) accumulator.get(i);
+ System.arraycopy(castValue, 0, result, total, castValue.length);
+ total += castValue.length;
+ }
+ return result;
+ }
+ if (first instanceof double[]) {
+ int length = 0;
+ for (int i = 0; i < accumulator.size(); i++) {
+ length += ((double[]) accumulator.get(i)).length;
+ }
+ double[] result = new double[length];
+ int total = 0;
+ for (int i = 0; i < accumulator.size(); i++) {
+ double[] castValue = (double[]) accumulator.get(i);
+ System.arraycopy(castValue, 0, result, total, castValue.length);
+ total += castValue.length;
+ }
+ return result;
+ }
+ if (first instanceof boolean[]) {
+ int length = 0;
+ for (int i = 0; i < accumulator.size(); i++) {
+ length += ((boolean[]) accumulator.get(i)).length;
+ }
+ boolean[] result = new boolean[length];
+ int total = 0;
+ for (int i = 0; i < accumulator.size(); i++) {
+ boolean[] castValue = (boolean[]) accumulator.get(i);
+ System.arraycopy(castValue, 0, result, total, castValue.length);
+ total += castValue.length;
+ }
+ return result;
+ }
+ if (first instanceof List) {
+ int length = 0;
+ for (int i = 0; i < accumulator.size(); i++) {
+ length += ((List<?>) accumulator.get(i)).size();
+ }
+ List<Bundle> result = new ArrayList<>(length);
+ for (int i = 0; i < accumulator.size(); i++) {
+ @SuppressWarnings("unchecked")
+ List<Bundle> castValue = (List<Bundle>) accumulator.get(i);
+ result.addAll(castValue);
+ }
+ return result;
+ }
+ if (first instanceof Parcelable[]) {
+ int length = 0;
+ for (int i = 0; i < accumulator.size(); i++) {
+ length += ((Parcelable[]) accumulator.get(i)).length;
+ }
+ Parcelable[] result = new Parcelable[length];
+ int total = 0;
+ for (int i = 0; i < accumulator.size(); i++) {
+ Parcelable[] castValue = (Parcelable[]) accumulator.get(i);
+ System.arraycopy(castValue, 0, result, total, castValue.length);
+ total += castValue.length;
+ }
+ return result;
+ }
+ throw new IllegalStateException("Unexpected property type: " + first);
}
/**
- * Retrieves a {@link String} value by key.
+ * Retrieves a {@link String} property by path.
*
- * @param key The key to look for.
- * @return The first {@link String} associated with the given key or {@code null} if there is no
- * such key or the value is of a different type.
+ * <p>See {@link #getProperty} for a detailed description of the path syntax.
+ *
+ * @param path The path to look for.
+ * @return The first {@link String} associated with the given path or {@code null} if there is
+ * no such value or the value is of a different type.
*/
@Nullable
- public String getPropertyString(@NonNull String key) {
- Objects.requireNonNull(key);
- String[] propertyArray = getPropertyStringArray(key);
+ public String getPropertyString(@NonNull String path) {
+ Objects.requireNonNull(path);
+ String[] propertyArray = getPropertyStringArray(path);
if (propertyArray == null || propertyArray.length == 0) {
return null;
}
- warnIfSinglePropertyTooLong("String", key, propertyArray.length);
+ warnIfSinglePropertyTooLong("String", path, propertyArray.length);
return propertyArray[0];
}
/**
- * Retrieves a {@code long} value by key.
+ * Retrieves a {@code long} property by path.
+ *
+ * <p>See {@link #getProperty} for a detailed description of the path syntax.
*
- * @param key The key to look for.
- * @return The first {@code long} associated with the given key or default value {@code 0} if
- * there is no such key or the value is of a different type.
+ * @param path The path to look for.
+ * @return The first {@code long} associated with the given path or default value {@code 0} if
+ * there is no such value or the value is of a different type.
*/
- public long getPropertyLong(@NonNull String key) {
- Objects.requireNonNull(key);
- long[] propertyArray = getPropertyLongArray(key);
+ public long getPropertyLong(@NonNull String path) {
+ Objects.requireNonNull(path);
+ long[] propertyArray = getPropertyLongArray(path);
if (propertyArray == null || propertyArray.length == 0) {
return 0;
}
- warnIfSinglePropertyTooLong("Long", key, propertyArray.length);
+ warnIfSinglePropertyTooLong("Long", path, propertyArray.length);
return propertyArray[0];
}
/**
- * Retrieves a {@code double} value by key.
+ * Retrieves a {@code double} property by path.
+ *
+ * <p>See {@link #getProperty} for a detailed description of the path syntax.
*
- * @param key The key to look for.
- * @return The first {@code double} associated with the given key or default value {@code 0.0}
- * if there is no such key or the value is of a different type.
+ * @param path The path to look for.
+ * @return The first {@code double} associated with the given path or default value {@code 0.0}
+ * if there is no such value or the value is of a different type.
*/
- public double getPropertyDouble(@NonNull String key) {
- Objects.requireNonNull(key);
- double[] propertyArray = getPropertyDoubleArray(key);
+ public double getPropertyDouble(@NonNull String path) {
+ Objects.requireNonNull(path);
+ double[] propertyArray = getPropertyDoubleArray(path);
if (propertyArray == null || propertyArray.length == 0) {
return 0.0;
}
- warnIfSinglePropertyTooLong("Double", key, propertyArray.length);
+ warnIfSinglePropertyTooLong("Double", path, propertyArray.length);
return propertyArray[0];
}
/**
- * Retrieves a {@code boolean} value by key.
+ * Retrieves a {@code boolean} property by path.
*
- * @param key The key to look for.
- * @return The first {@code boolean} associated with the given key or default value {@code
- * false} if there is no such key or the value is of a different type.
+ * <p>See {@link #getProperty} for a detailed description of the path syntax.
+ *
+ * @param path The path to look for.
+ * @return The first {@code boolean} associated with the given path or default value {@code
+ * false} if there is no such value or the value is of a different type.
*/
- public boolean getPropertyBoolean(@NonNull String key) {
- Objects.requireNonNull(key);
- boolean[] propertyArray = getPropertyBooleanArray(key);
+ public boolean getPropertyBoolean(@NonNull String path) {
+ Objects.requireNonNull(path);
+ boolean[] propertyArray = getPropertyBooleanArray(path);
if (propertyArray == null || propertyArray.length == 0) {
return false;
}
- warnIfSinglePropertyTooLong("Boolean", key, propertyArray.length);
+ warnIfSinglePropertyTooLong("Boolean", path, propertyArray.length);
return propertyArray[0];
}
/**
- * Retrieves a {@code byte[]} value by key.
+ * Retrieves a {@code byte[]} property by path.
+ *
+ * <p>See {@link #getProperty} for a detailed description of the path syntax.
*
- * @param key The key to look for.
- * @return The first {@code byte[]} associated with the given key or {@code null} if there is no
- * such key or the value is of a different type.
+ * @param path The path to look for.
+ * @return The first {@code byte[]} associated with the given path or {@code null} if there is
+ * no such value or the value is of a different type.
*/
@Nullable
- public byte[] getPropertyBytes(@NonNull String key) {
- Objects.requireNonNull(key);
- byte[][] propertyArray = getPropertyBytesArray(key);
+ public byte[] getPropertyBytes(@NonNull String path) {
+ Objects.requireNonNull(path);
+ byte[][] propertyArray = getPropertyBytesArray(path);
if (propertyArray == null || propertyArray.length == 0) {
return null;
}
- warnIfSinglePropertyTooLong("ByteArray", key, propertyArray.length);
+ warnIfSinglePropertyTooLong("ByteArray", path, propertyArray.length);
return propertyArray[0];
}
/**
- * Retrieves a {@link GenericDocument} value by key.
+ * Retrieves a {@link GenericDocument} property by path.
*
- * @param key The key to look for.
- * @return The first {@link GenericDocument} associated with the given key or {@code null} if
- * there is no such key or the value is of a different type.
+ * <p>See {@link #getProperty} for a detailed description of the path syntax.
+ *
+ * @param path The path to look for.
+ * @return The first {@link GenericDocument} associated with the given path or {@code null} if
+ * there is no such value or the value is of a different type.
*/
@Nullable
- public GenericDocument getPropertyDocument(@NonNull String key) {
- Objects.requireNonNull(key);
- GenericDocument[] propertyArray = getPropertyDocumentArray(key);
+ public GenericDocument getPropertyDocument(@NonNull String path) {
+ Objects.requireNonNull(path);
+ GenericDocument[] propertyArray = getPropertyDocumentArray(path);
if (propertyArray == null || propertyArray.length == 0) {
return null;
}
- warnIfSinglePropertyTooLong("Document", key, propertyArray.length);
+ warnIfSinglePropertyTooLong("Document", path, propertyArray.length);
return propertyArray[0];
}
/** Prints a warning to logcat if the given propertyLength is greater than 1. */
private static void warnIfSinglePropertyTooLong(
- @NonNull String propertyType, @NonNull String key, int propertyLength) {
+ @NonNull String propertyType, @NonNull String path, int propertyLength) {
if (propertyLength > 1) {
Log.w(
TAG,
"The value for \""
- + key
+ + path
+ "\" contains "
+ propertyLength
+ " elements. Only the first one will be returned from "
@@ -335,141 +724,121 @@ public class GenericDocument {
}
/**
- * Retrieves a repeated {@code String} property by key.
+ * Retrieves a repeated {@code String} property by path.
+ *
+ * <p>See {@link #getProperty} for a detailed description of the path syntax.
*
- * @param key The key to look for.
- * @return The {@code String[]} associated with the given key, or {@code null} if no value is
+ * @param path The path to look for.
+ * @return The {@code String[]} associated with the given path, or {@code null} if no value is
* set or the value is of a different type.
*/
@Nullable
- public String[] getPropertyStringArray(@NonNull String key) {
- Objects.requireNonNull(key);
- return getAndCastPropertyArray(key, String[].class);
+ public String[] getPropertyStringArray(@NonNull String path) {
+ Objects.requireNonNull(path);
+ Object value = getProperty(path);
+ return safeCastProperty(path, value, String[].class);
}
/**
- * Retrieves a repeated {@code long[]} property by key.
+ * Retrieves a repeated {@code long[]} property by path.
*
- * @param key The key to look for.
- * @return The {@code long[]} associated with the given key, or {@code null} if no value is set
+ * <p>See {@link #getProperty} for a detailed description of the path syntax.
+ *
+ * @param path The path to look for.
+ * @return The {@code long[]} associated with the given path, or {@code null} if no value is set
* or the value is of a different type.
*/
@Nullable
- public long[] getPropertyLongArray(@NonNull String key) {
- Objects.requireNonNull(key);
- return getAndCastPropertyArray(key, long[].class);
+ public long[] getPropertyLongArray(@NonNull String path) {
+ Objects.requireNonNull(path);
+ Object value = getProperty(path);
+ return safeCastProperty(path, value, long[].class);
}
/**
- * Retrieves a repeated {@code double} property by key.
+ * Retrieves a repeated {@code double} property by path.
+ *
+ * <p>See {@link #getProperty} for a detailed description of the path syntax.
*
- * @param key The key to look for.
- * @return The {@code double[]} associated with the given key, or {@code null} if no value is
+ * @param path The path to look for.
+ * @return The {@code double[]} associated with the given path, or {@code null} if no value is
* set or the value is of a different type.
*/
@Nullable
- public double[] getPropertyDoubleArray(@NonNull String key) {
- Objects.requireNonNull(key);
- return getAndCastPropertyArray(key, double[].class);
+ public double[] getPropertyDoubleArray(@NonNull String path) {
+ Objects.requireNonNull(path);
+ Object value = getProperty(path);
+ return safeCastProperty(path, value, double[].class);
}
/**
- * Retrieves a repeated {@code boolean} property by key.
+ * Retrieves a repeated {@code boolean} property by path.
+ *
+ * <p>See {@link #getProperty} for a detailed description of the path syntax.
*
- * @param key The key to look for.
- * @return The {@code boolean[]} associated with the given key, or {@code null} if no value is
+ * @param path The path to look for.
+ * @return The {@code boolean[]} associated with the given path, or {@code null} if no value is
* set or the value is of a different type.
*/
@Nullable
- public boolean[] getPropertyBooleanArray(@NonNull String key) {
- Objects.requireNonNull(key);
- return getAndCastPropertyArray(key, boolean[].class);
+ public boolean[] getPropertyBooleanArray(@NonNull String path) {
+ Objects.requireNonNull(path);
+ Object value = getProperty(path);
+ return safeCastProperty(path, value, boolean[].class);
}
/**
- * Retrieves a {@code byte[][]} property by key.
+ * Retrieves a {@code byte[][]} property by path.
*
- * @param key The key to look for.
- * @return The {@code byte[][]} associated with the given key, or {@code null} if no value is
+ * <p>See {@link #getProperty} for a detailed description of the path syntax.
+ *
+ * @param path The path to look for.
+ * @return The {@code byte[][]} associated with the given path, or {@code null} if no value is
* set or the value is of a different type.
*/
@SuppressLint("ArrayReturn")
@Nullable
- @SuppressWarnings("unchecked")
- public byte[][] getPropertyBytesArray(@NonNull String key) {
- Objects.requireNonNull(key);
- ArrayList<Bundle> bundles = getAndCastPropertyArray(key, ArrayList.class);
- if (bundles == null || bundles.size() == 0) {
- return null;
- }
- byte[][] bytes = new byte[bundles.size()][];
- for (int i = 0; i < bundles.size(); i++) {
- Bundle bundle = bundles.get(i);
- if (bundle == null) {
- Log.e(TAG, "The inner bundle is null at " + i + ", for key: " + key);
- continue;
- }
- byte[] innerBytes = bundle.getByteArray(BYTE_ARRAY_FIELD);
- if (innerBytes == null) {
- Log.e(TAG, "The bundle at " + i + " contains a null byte[].");
- continue;
- }
- bytes[i] = innerBytes;
- }
- return bytes;
+ public byte[][] getPropertyBytesArray(@NonNull String path) {
+ Objects.requireNonNull(path);
+ Object value = getProperty(path);
+ return safeCastProperty(path, value, byte[][].class);
}
/**
- * Retrieves a repeated {@link GenericDocument} property by key.
+ * Retrieves a repeated {@link GenericDocument} property by path.
+ *
+ * <p>See {@link #getProperty} for a detailed description of the path syntax.
*
- * @param key The key to look for.
- * @return The {@link GenericDocument}[] associated with the given key, or {@code null} if no
+ * @param path The path to look for.
+ * @return The {@link GenericDocument}[] associated with the given path, or {@code null} if no
* value is set or the value is of a different type.
*/
@SuppressLint("ArrayReturn")
@Nullable
- public GenericDocument[] getPropertyDocumentArray(@NonNull String key) {
- Objects.requireNonNull(key);
- Parcelable[] bundles = getAndCastPropertyArray(key, Parcelable[].class);
- if (bundles == null || bundles.length == 0) {
- return null;
- }
- GenericDocument[] documents = new GenericDocument[bundles.length];
- for (int i = 0; i < bundles.length; i++) {
- if (bundles[i] == null) {
- Log.e(TAG, "The inner bundle is null at " + i + ", for key: " + key);
- continue;
- }
- if (!(bundles[i] instanceof Bundle)) {
- Log.e(
- TAG,
- "The inner element at "
- + i
- + " is a "
- + bundles[i].getClass()
- + ", not a Bundle for key: "
- + key);
- continue;
- }
- documents[i] = new GenericDocument((Bundle) bundles[i]);
- }
- return documents;
+ public GenericDocument[] getPropertyDocumentArray(@NonNull String path) {
+ Objects.requireNonNull(path);
+ Object value = getProperty(path);
+ return safeCastProperty(path, value, GenericDocument[].class);
}
/**
- * Gets a repeated property of the given key, and casts it to the given class type, which must
- * be an array class type.
+ * Casts a repeated property to the provided type, logging an error and returning {@code null}
+ * if the cast fails.
+ *
+ * @param path Path to the property within the document. Used for logging.
+ * @param value Value of the property
+ * @param tClass Class to cast the value into
*/
@Nullable
- private <T> T getAndCastPropertyArray(@NonNull String key, @NonNull Class<T> tClass) {
- Object value = mProperties.get(key);
+ private static <T> T safeCastProperty(
+ @NonNull String path, @Nullable Object value, @NonNull Class<T> tClass) {
if (value == null) {
return null;
}
try {
return tClass.cast(value);
} catch (ClassCastException e) {
- Log.w(TAG, "Error casting to requested type for key \"" + key + "\"", e);
+ Log.w(TAG, "Error casting to requested type for path \"" + path + "\"", e);
return null;
}
}
@@ -500,17 +869,15 @@ public class GenericDocument {
return bundleToString(mBundle).toString();
}
- @SuppressWarnings("unchecked")
private static StringBuilder bundleToString(Bundle bundle) {
StringBuilder stringBuilder = new StringBuilder();
try {
- final Set<String> keySet = bundle.keySet();
- String[] keys = keySet.toArray(new String[0]);
- // Sort keys to make output deterministic. We need a custom comparator to handle
+ String[] names = bundle.keySet().toArray(new String[0]);
+ // Sort names to make output deterministic. We need a custom comparator to handle
// nulls (arbitrarily putting them first, similar to Comparator.nullsFirst, which is
// only available since N).
Arrays.sort(
- keys,
+ names,
(@Nullable String s1, @Nullable String s2) -> {
if (s1 == null) {
return s2 == null ? 0 : -1;
@@ -520,9 +887,9 @@ public class GenericDocument {
return s1.compareTo(s2);
}
});
- for (String key : keys) {
- stringBuilder.append("{ key: '").append(key).append("' value: ");
- Object valueObject = bundle.get(key);
+ for (String name : names) {
+ stringBuilder.append("{ name: '").append(name).append("' value: ");
+ Object valueObject = bundle.get(name);
if (valueObject == null) {
stringBuilder.append("<null>");
} else if (valueObject instanceof Bundle) {
@@ -540,9 +907,11 @@ public class GenericDocument {
stringBuilder.append("' ");
}
stringBuilder.append("]");
- } else if (valueObject instanceof ArrayList) {
- for (Bundle innerBundle : (ArrayList<Bundle>) valueObject) {
- stringBuilder.append(bundleToString(innerBundle));
+ } else if (valueObject instanceof List) {
+ @SuppressWarnings("unchecked")
+ List<Bundle> bundles = (List<Bundle>) valueObject;
+ for (int i = 0; i < bundles.size(); i++) {
+ stringBuilder.append(bundleToString(bundles.get(i)));
}
} else {
stringBuilder.append(valueObject.toString());
@@ -577,12 +946,12 @@ public class GenericDocument {
*
* <p>Once {@link #build} is called, the instance can no longer be used.
*
- * <p>URIs 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.
*
* @param namespace the namespace to set for the {@link GenericDocument}.
- * @param uri the URI to set for the {@link GenericDocument}.
+ * @param id the unique identifier for the {@link GenericDocument} in its namespace.
* @param schemaType the {@link AppSearchSchema} type of the {@link GenericDocument}. The
* provided {@code schemaType} must be defined using {@link AppSearchSession#setSchema}
* prior to inserting a document of this {@code schemaType} into the AppSearch index
@@ -591,13 +960,13 @@ public class GenericDocument {
* AppSearchResult#RESULT_NOT_FOUND}.
*/
@SuppressWarnings("unchecked")
- public Builder(@NonNull String namespace, @NonNull String uri, @NonNull String schemaType) {
+ public Builder(@NonNull String namespace, @NonNull String id, @NonNull String schemaType) {
Objects.requireNonNull(namespace);
- Objects.requireNonNull(uri);
+ Objects.requireNonNull(id);
Objects.requireNonNull(schemaType);
mBuilderTypeInstance = (BuilderType) this;
mBundle.putString(GenericDocument.NAMESPACE_FIELD, namespace);
- mBundle.putString(GenericDocument.URI_FIELD, uri);
+ mBundle.putString(GenericDocument.ID_FIELD, id);
mBundle.putString(GenericDocument.SCHEMA_TYPE_FIELD, schemaType);
// Set current timestamp for creation timestamp by default.
mBundle.putLong(
@@ -641,7 +1010,8 @@ public class GenericDocument {
* @throws IllegalStateException if the builder has already been used.
*/
@NonNull
- public BuilderType setCreationTimestampMillis(long creationTimestampMillis) {
+ public BuilderType setCreationTimestampMillis(
+ @CurrentTimeMillisLong long creationTimestampMillis) {
Preconditions.checkState(!mBuilt, "Builder has already been used");
mBundle.putLong(
GenericDocument.CREATION_TIMESTAMP_MILLIS_FIELD, creationTimestampMillis);
@@ -674,18 +1044,19 @@ public class GenericDocument {
/**
* Sets one or multiple {@code String} values for a property, replacing its previous values.
*
- * @param key the key associated with the {@code values}.
+ * @param name the name associated with the {@code values}. Must match the name for this
+ * property as given in {@link AppSearchSchema.PropertyConfig#getName}.
* @param values the {@code String} values of the property.
* @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}.
* @throws IllegalStateException if the builder has already been used.
*/
@NonNull
- public BuilderType setPropertyString(@NonNull String key, @NonNull String... values) {
+ public BuilderType setPropertyString(@NonNull String name, @NonNull String... values) {
Preconditions.checkState(!mBuilt, "Builder has already been used");
- Objects.requireNonNull(key);
+ Objects.requireNonNull(name);
Objects.requireNonNull(values);
- putInPropertyBundle(key, values);
+ putInPropertyBundle(name, values);
return mBuilderTypeInstance;
}
@@ -693,69 +1064,73 @@ public class GenericDocument {
* Sets one or multiple {@code boolean} values for a property, replacing its previous
* values.
*
- * @param key the key associated with the {@code values}.
+ * @param name the name associated with the {@code values}. Must match the name for this
+ * property as given in {@link AppSearchSchema.PropertyConfig#getName}.
* @param values the {@code boolean} values of the property.
* @throws IllegalArgumentException if values exceed maximum repeated property length.
* @throws IllegalStateException if the builder has already been used.
*/
@NonNull
- public BuilderType setPropertyBoolean(@NonNull String key, @NonNull boolean... values) {
+ public BuilderType setPropertyBoolean(@NonNull String name, @NonNull boolean... values) {
Preconditions.checkState(!mBuilt, "Builder has already been used");
- Objects.requireNonNull(key);
+ Objects.requireNonNull(name);
Objects.requireNonNull(values);
- putInPropertyBundle(key, values);
+ putInPropertyBundle(name, values);
return mBuilderTypeInstance;
}
/**
* Sets one or multiple {@code long} values for a property, replacing its previous values.
*
- * @param key the key associated with the {@code values}.
+ * @param name the name associated with the {@code values}. Must match the name for this
+ * property as given in {@link AppSearchSchema.PropertyConfig#getName}.
* @param values the {@code long} values of the property.
* @throws IllegalArgumentException if values exceed maximum repeated property length.
* @throws IllegalStateException if the builder has already been used.
*/
@NonNull
- public BuilderType setPropertyLong(@NonNull String key, @NonNull long... values) {
+ public BuilderType setPropertyLong(@NonNull String name, @NonNull long... values) {
Preconditions.checkState(!mBuilt, "Builder has already been used");
- Objects.requireNonNull(key);
+ Objects.requireNonNull(name);
Objects.requireNonNull(values);
- putInPropertyBundle(key, values);
+ putInPropertyBundle(name, values);
return mBuilderTypeInstance;
}
/**
* Sets one or multiple {@code double} values for a property, replacing its previous values.
*
- * @param key the key associated with the {@code values}.
+ * @param name the name associated with the {@code values}. Must match the name for this
+ * property as given in {@link AppSearchSchema.PropertyConfig#getName}.
* @param values the {@code double} values of the property.
* @throws IllegalArgumentException if values exceed maximum repeated property length.
* @throws IllegalStateException if the builder has already been used.
*/
@NonNull
- public BuilderType setPropertyDouble(@NonNull String key, @NonNull double... values) {
+ public BuilderType setPropertyDouble(@NonNull String name, @NonNull double... values) {
Preconditions.checkState(!mBuilt, "Builder has already been used");
- Objects.requireNonNull(key);
+ Objects.requireNonNull(name);
Objects.requireNonNull(values);
- putInPropertyBundle(key, values);
+ putInPropertyBundle(name, values);
return mBuilderTypeInstance;
}
/**
* Sets one or multiple {@code byte[]} for a property, replacing its previous values.
*
- * @param key the key associated with the {@code values}.
+ * @param name the name associated with the {@code values}. Must match the name for this
+ * property as given in {@link AppSearchSchema.PropertyConfig#getName}.
* @param values the {@code byte[]} of the property.
* @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}.
* @throws IllegalStateException if the builder has already been used.
*/
@NonNull
- public BuilderType setPropertyBytes(@NonNull String key, @NonNull byte[]... values) {
+ public BuilderType setPropertyBytes(@NonNull String name, @NonNull byte[]... values) {
Preconditions.checkState(!mBuilt, "Builder has already been used");
- Objects.requireNonNull(key);
+ Objects.requireNonNull(name);
Objects.requireNonNull(values);
- putInPropertyBundle(key, values);
+ putInPropertyBundle(name, values);
return mBuilderTypeInstance;
}
@@ -763,7 +1138,8 @@ public class GenericDocument {
* Sets one or multiple {@link GenericDocument} values for a property, replacing its
* previous values.
*
- * @param key the key associated with the {@code values}.
+ * @param name the name associated with the {@code values}. Must match the name for this
+ * property as given in {@link AppSearchSchema.PropertyConfig#getName}.
* @param values the {@link GenericDocument} values of the property.
* @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
@@ -772,17 +1148,17 @@ public class GenericDocument {
*/
@NonNull
public BuilderType setPropertyDocument(
- @NonNull String key, @NonNull GenericDocument... values) {
+ @NonNull String name, @NonNull GenericDocument... values) {
Preconditions.checkState(!mBuilt, "Builder has already been used");
- Objects.requireNonNull(key);
+ Objects.requireNonNull(name);
Objects.requireNonNull(values);
- putInPropertyBundle(key, values);
+ putInPropertyBundle(name, values);
return mBuilderTypeInstance;
}
- private void putInPropertyBundle(@NonNull String key, @NonNull String[] values)
+ private void putInPropertyBundle(@NonNull String name, @NonNull String[] values)
throws IllegalArgumentException {
- validateRepeatedPropertyLength(key, values.length);
+ validateRepeatedPropertyLength(name, values.length);
for (int i = 0; i < values.length; i++) {
if (values[i] == null) {
throw new IllegalArgumentException("The String at " + i + " is null.");
@@ -797,22 +1173,22 @@ public class GenericDocument {
+ ".");
}
}
- mProperties.putStringArray(key, values);
+ mProperties.putStringArray(name, values);
}
- private void putInPropertyBundle(@NonNull String key, @NonNull boolean[] values) {
- validateRepeatedPropertyLength(key, values.length);
- mProperties.putBooleanArray(key, values);
+ private void putInPropertyBundle(@NonNull String name, @NonNull boolean[] values) {
+ validateRepeatedPropertyLength(name, values.length);
+ mProperties.putBooleanArray(name, values);
}
- private void putInPropertyBundle(@NonNull String key, @NonNull double[] values) {
- validateRepeatedPropertyLength(key, values.length);
- mProperties.putDoubleArray(key, values);
+ private void putInPropertyBundle(@NonNull String name, @NonNull double[] values) {
+ validateRepeatedPropertyLength(name, values.length);
+ mProperties.putDoubleArray(name, values);
}
- private void putInPropertyBundle(@NonNull String key, @NonNull long[] values) {
- validateRepeatedPropertyLength(key, values.length);
- mProperties.putLongArray(key, values);
+ private void putInPropertyBundle(@NonNull String name, @NonNull long[] values) {
+ validateRepeatedPropertyLength(name, values.length);
+ mProperties.putLongArray(name, values);
}
/**
@@ -821,8 +1197,8 @@ public class GenericDocument {
* <p>Bundle doesn't support for two dimension array byte[][], we are converting byte[][]
* into ArrayList<Bundle>, and each elements will contain a one dimension byte[].
*/
- private void putInPropertyBundle(@NonNull String key, @NonNull byte[][] values) {
- validateRepeatedPropertyLength(key, values.length);
+ private void putInPropertyBundle(@NonNull String name, @NonNull byte[][] values) {
+ validateRepeatedPropertyLength(name, values.length);
ArrayList<Bundle> bundles = new ArrayList<>(values.length);
for (int i = 0; i < values.length; i++) {
if (values[i] == null) {
@@ -832,11 +1208,11 @@ public class GenericDocument {
bundle.putByteArray(BYTE_ARRAY_FIELD, values[i]);
bundles.add(bundle);
}
- mProperties.putParcelableArrayList(key, bundles);
+ mProperties.putParcelableArrayList(name, bundles);
}
- private void putInPropertyBundle(@NonNull String key, @NonNull GenericDocument[] values) {
- validateRepeatedPropertyLength(key, values.length);
+ private void putInPropertyBundle(@NonNull String name, @NonNull GenericDocument[] values) {
+ validateRepeatedPropertyLength(name, values.length);
Parcelable[] documentBundles = new Parcelable[values.length];
for (int i = 0; i < values.length; i++) {
if (values[i] == null) {
@@ -844,14 +1220,14 @@ public class GenericDocument {
}
documentBundles[i] = values[i].mBundle;
}
- mProperties.putParcelableArray(key, documentBundles);
+ mProperties.putParcelableArray(name, documentBundles);
}
- private static void validateRepeatedPropertyLength(@NonNull String key, int length) {
+ private static void validateRepeatedPropertyLength(@NonNull String name, int length) {
if (length > MAX_REPEATED_PROPERTY_LENGTH) {
throw new IllegalArgumentException(
"Repeated property \""
- + key
+ + name
+ "\" has length "
+ length
+ ", which exceeds the limit of "
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/GetByUriRequest.java b/apex/appsearch/framework/java/external/android/app/appsearch/GetByDocumentIdRequest.java
index 4dc3225bd179..58fd8bee8d4a 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/GetByUriRequest.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/GetByDocumentIdRequest.java
@@ -32,29 +32,29 @@ import java.util.Objects;
import java.util.Set;
/**
- * Encapsulates a request to retrieve documents by namespace and URIs from the {@link
+ * Encapsulates a request to retrieve documents by namespace and IDs from the {@link
* AppSearchSession} database.
*
- * @see AppSearchSession#getByUri
+ * @see AppSearchSession#getByDocumentId
*/
-public final class GetByUriRequest {
+public final class GetByDocumentIdRequest {
/**
- * Schema type to be used in {@link android.app.appsearch.GetByUriRequest.Builder#addProjection}
- * to apply property paths to all results, excepting any types that have had their own, specific
- * property paths set.
+ * Schema type to be used in {@link GetByDocumentIdRequest.Builder#addProjection} to apply
+ * property paths to all results, excepting any types that have had their own, specific property
+ * paths set.
*/
public static final String PROJECTION_SCHEMA_TYPE_WILDCARD = "*";
private final String mNamespace;
- private final Set<String> mUris;
+ private final Set<String> mIds;
private final Map<String, List<String>> mTypePropertyPathsMap;
- GetByUriRequest(
+ GetByDocumentIdRequest(
@NonNull String namespace,
- @NonNull Set<String> uris,
+ @NonNull Set<String> ids,
@NonNull Map<String, List<String>> typePropertyPathsMap) {
mNamespace = Objects.requireNonNull(namespace);
- mUris = Objects.requireNonNull(uris);
+ mIds = Objects.requireNonNull(ids);
mTypePropertyPathsMap = Objects.requireNonNull(typePropertyPathsMap);
}
@@ -64,10 +64,10 @@ public final class GetByUriRequest {
return mNamespace;
}
- /** Returns the set of URIs attached to the request. */
+ /** Returns the set of document IDs attached to the request. */
@NonNull
- public Set<String> getUris() {
- return Collections.unmodifiableSet(mUris);
+ public Set<String> getIds() {
+ return Collections.unmodifiableSet(mIds);
}
/**
@@ -81,8 +81,8 @@ public final class GetByUriRequest {
@NonNull
public Map<String, List<String>> getProjections() {
Map<String, List<String>> copy = new ArrayMap<>();
- for (String key : mTypePropertyPathsMap.keySet()) {
- copy.put(key, new ArrayList<>(mTypePropertyPathsMap.get(key)));
+ for (Map.Entry<String, List<String>> entry : mTypePropertyPathsMap.entrySet()) {
+ copy.put(entry.getKey(), new ArrayList<>(entry.getValue()));
}
return copy;
}
@@ -103,42 +103,42 @@ public final class GetByUriRequest {
}
/**
- * Builder for {@link GetByUriRequest} objects.
+ * Builder for {@link GetByDocumentIdRequest} objects.
*
* <p>Once {@link #build} is called, the instance can no longer be used.
*/
public static final class Builder {
private final String mNamespace;
- private final Set<String> mUris = new ArraySet<>();
+ private final Set<String> mIds = new ArraySet<>();
private final Map<String, List<String>> mProjectionTypePropertyPaths = new ArrayMap<>();
private boolean mBuilt = false;
- /** Creates a {@link GetByUriRequest.Builder} instance. */
+ /** Creates a {@link GetByDocumentIdRequest.Builder} instance. */
public Builder(@NonNull String namespace) {
mNamespace = Objects.requireNonNull(namespace);
}
/**
- * Adds one or more URIs to the request.
+ * Adds one or more document IDs to the request.
*
* @throws IllegalStateException if the builder has already been used.
*/
@NonNull
- public Builder addUris(@NonNull String... uris) {
- Objects.requireNonNull(uris);
- return addUris(Arrays.asList(uris));
+ public Builder addIds(@NonNull String... ids) {
+ Objects.requireNonNull(ids);
+ return addIds(Arrays.asList(ids));
}
/**
- * Adds a collection of URIs to the request.
+ * Adds a collection of IDs to the request.
*
* @throws IllegalStateException if the builder has already been used.
*/
@NonNull
- public Builder addUris(@NonNull Collection<String> uris) {
+ public Builder addIds(@NonNull Collection<String> ids) {
Preconditions.checkState(!mBuilt, "Builder has already been used");
- Objects.requireNonNull(uris);
- mUris.addAll(uris);
+ Objects.requireNonNull(ids);
+ mIds.addAll(ids);
return this;
}
@@ -152,8 +152,9 @@ public final class GetByUriRequest {
* of that type will be retrieved.
*
* <p>If property path is added for the {@link
- * GetByUriRequest#PROJECTION_SCHEMA_TYPE_WILDCARD}, then those property paths will apply to
- * all results, excepting any types that have their own, specific property paths set.
+ * GetByDocumentIdRequest#PROJECTION_SCHEMA_TYPE_WILDCARD}, then those property paths will
+ * apply to all results, excepting any types that have their own, specific property paths
+ * set.
*
* @throws IllegalStateException if the builder has already been used.
* @see SearchSpec.Builder#addProjection
@@ -174,15 +175,15 @@ public final class GetByUriRequest {
}
/**
- * Builds a new {@link GetByUriRequest}.
+ * Builds a new {@link GetByDocumentIdRequest}.
*
* @throws IllegalStateException if the builder has already been used.
*/
@NonNull
- public GetByUriRequest build() {
+ public GetByDocumentIdRequest build() {
Preconditions.checkState(!mBuilt, "Builder has already been used");
mBuilt = true;
- return new GetByUriRequest(mNamespace, mUris, mProjectionTypePropertyPaths);
+ return new GetByDocumentIdRequest(mNamespace, mIds, mProjectionTypePropertyPaths);
}
}
}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/GetSchemaResponse.java b/apex/appsearch/framework/java/external/android/app/appsearch/GetSchemaResponse.java
index 691ef4ff939f..6f8cbe84ab50 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/GetSchemaResponse.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/GetSchemaResponse.java
@@ -75,7 +75,7 @@ public class GetSchemaResponse {
/** Builder for {@link GetSchemaResponse} objects. */
public static final class Builder {
- private int mVersion;
+ private int mVersion = 0;
private boolean mBuilt = false;
private final ArrayList<Bundle> mSchemaBundles = new ArrayList<>();
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/Migrator.java b/apex/appsearch/framework/java/external/android/app/appsearch/Migrator.java
index 511b42ac8f12..c5a0f63c94b6 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/Migrator.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/Migrator.java
@@ -52,7 +52,7 @@ public abstract class Migrator {
*
* <p>If this {@link Migrator} is provided to cover a compatible schema change via {@link
* AppSearchSession#setSchema}, documents under the old version won't be removed unless you use
- * the same URI.
+ * the same document ID.
*
* <p>This method will be invoked on the background worker thread provided via {@link
* AppSearchSession#setSchema}.
@@ -75,7 +75,7 @@ public abstract class Migrator {
*
* <p>If this {@link Migrator} is provided to cover a compatible schema change via {@link
* AppSearchSession#setSchema}, documents under the old version won't be removed unless you use
- * the same URI.
+ * the same document ID.
*
* <p>This method will be invoked on the background worker thread.
*
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/RemoveByUriRequest.java b/apex/appsearch/framework/java/external/android/app/appsearch/RemoveByDocumentIdRequest.java
index 4dcad68d49be..1afbe27116ca 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/RemoveByUriRequest.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/RemoveByDocumentIdRequest.java
@@ -28,18 +28,18 @@ import java.util.Objects;
import java.util.Set;
/**
- * Encapsulates a request to remove documents by namespace and URIs from the {@link
- * AppSearchSession} database.
+ * Encapsulates a request to remove documents by namespace and IDs from the {@link AppSearchSession}
+ * database.
*
* @see AppSearchSession#remove
*/
-public final class RemoveByUriRequest {
+public final class RemoveByDocumentIdRequest {
private final String mNamespace;
- private final Set<String> mUris;
+ private final Set<String> mIds;
- RemoveByUriRequest(String namespace, Set<String> uris) {
+ RemoveByDocumentIdRequest(String namespace, Set<String> ids) {
mNamespace = namespace;
- mUris = uris;
+ mIds = ids;
}
/** Returns the namespace to remove documents from. */
@@ -48,61 +48,61 @@ public final class RemoveByUriRequest {
return mNamespace;
}
- /** Returns the set of URIs attached to the request. */
+ /** Returns the set of document IDs attached to the request. */
@NonNull
- public Set<String> getUris() {
- return Collections.unmodifiableSet(mUris);
+ public Set<String> getIds() {
+ return Collections.unmodifiableSet(mIds);
}
/**
- * Builder for {@link RemoveByUriRequest} objects.
+ * Builder for {@link RemoveByDocumentIdRequest} objects.
*
* <p>Once {@link #build} is called, the instance can no longer be used.
*/
public static final class Builder {
private final String mNamespace;
- private final Set<String> mUris = new ArraySet<>();
+ private final Set<String> mIds = new ArraySet<>();
private boolean mBuilt = false;
- /** Creates a {@link RemoveByUriRequest.Builder} instance. */
+ /** Creates a {@link RemoveByDocumentIdRequest.Builder} instance. */
public Builder(@NonNull String namespace) {
mNamespace = Objects.requireNonNull(namespace);
}
/**
- * Adds one or more URIs to the request.
+ * Adds one or more document IDs to the request.
*
* @throws IllegalStateException if the builder has already been used.
*/
@NonNull
- public Builder addUris(@NonNull String... uris) {
- Objects.requireNonNull(uris);
- return addUris(Arrays.asList(uris));
+ public Builder addIds(@NonNull String... ids) {
+ Objects.requireNonNull(ids);
+ return addIds(Arrays.asList(ids));
}
/**
- * Adds a collection of URIs to the request.
+ * Adds a collection of IDs to the request.
*
* @throws IllegalStateException if the builder has already been used.
*/
@NonNull
- public Builder addUris(@NonNull Collection<String> uris) {
+ public Builder addIds(@NonNull Collection<String> ids) {
Preconditions.checkState(!mBuilt, "Builder has already been used");
- Objects.requireNonNull(uris);
- mUris.addAll(uris);
+ Objects.requireNonNull(ids);
+ mIds.addAll(ids);
return this;
}
/**
- * Builds a new {@link RemoveByUriRequest}.
+ * Builds a new {@link RemoveByDocumentIdRequest}.
*
* @throws IllegalStateException if the builder has already been used.
*/
@NonNull
- public RemoveByUriRequest build() {
+ public RemoveByDocumentIdRequest build() {
Preconditions.checkState(!mBuilt, "Builder has already been used");
mBuilt = true;
- return new RemoveByUriRequest(mNamespace, mUris);
+ return new RemoveByDocumentIdRequest(mNamespace, mIds);
}
}
}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/ReportSystemUsageRequest.java b/apex/appsearch/framework/java/external/android/app/appsearch/ReportSystemUsageRequest.java
index 8aff3b41cbc7..3947ba78cdd5 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/ReportSystemUsageRequest.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/ReportSystemUsageRequest.java
@@ -16,6 +16,7 @@
package android.app.appsearch;
+import android.annotation.CurrentTimeMillisLong;
import android.annotation.NonNull;
import com.android.internal.util.Preconditions;
@@ -35,20 +36,20 @@ public final class ReportSystemUsageRequest {
private final String mPackageName;
private final String mDatabase;
private final String mNamespace;
- private final String mUri;
- private final long mUsageTimeMillis;
+ private final String mDocumentId;
+ private final long mUsageTimestampMillis;
ReportSystemUsageRequest(
@NonNull String packageName,
@NonNull String database,
@NonNull String namespace,
- @NonNull String uri,
- long usageTimeMillis) {
+ @NonNull String documentId,
+ long usageTimestampMillis) {
mPackageName = Objects.requireNonNull(packageName);
mDatabase = Objects.requireNonNull(database);
mNamespace = Objects.requireNonNull(namespace);
- mUri = Objects.requireNonNull(uri);
- mUsageTimeMillis = usageTimeMillis;
+ mDocumentId = Objects.requireNonNull(documentId);
+ mUsageTimestampMillis = usageTimestampMillis;
}
/** Returns the package name of the app which owns the document that was used. */
@@ -69,10 +70,10 @@ public final class ReportSystemUsageRequest {
return mNamespace;
}
- /** Returns the URI of document that was used. */
+ /** Returns the ID of document that was used. */
@NonNull
- public String getUri() {
- return mUri;
+ public String getDocumentId() {
+ return mDocumentId;
}
/**
@@ -81,8 +82,9 @@ public final class ReportSystemUsageRequest {
*
* <p>The value is in the {@link System#currentTimeMillis} time base.
*/
- public long getUsageTimeMillis() {
- return mUsageTimeMillis;
+ @CurrentTimeMillisLong
+ public long getUsageTimestampMillis() {
+ return mUsageTimestampMillis;
}
/** Builder for {@link ReportSystemUsageRequest} objects. */
@@ -90,31 +92,20 @@ public final class ReportSystemUsageRequest {
private final String mPackageName;
private final String mDatabase;
private final String mNamespace;
- private String mUri;
- private Long mUsageTimeMillis;
+ private final String mDocumentId;
+ private Long mUsageTimestampMillis;
private boolean mBuilt = false;
/** Creates a {@link ReportSystemUsageRequest.Builder} instance. */
public Builder(
- @NonNull String packageName, @NonNull String database, @NonNull String namespace) {
+ @NonNull String packageName,
+ @NonNull String database,
+ @NonNull String namespace,
+ @NonNull String documentId) {
mPackageName = Objects.requireNonNull(packageName);
mDatabase = Objects.requireNonNull(database);
mNamespace = Objects.requireNonNull(namespace);
- }
-
- /**
- * Sets the URI of the document being used.
- *
- * <p>This field is required.
- *
- * @throws IllegalStateException if the builder has already been used
- */
- @NonNull
- public ReportSystemUsageRequest.Builder setUri(@NonNull String uri) {
- Preconditions.checkState(!mBuilt, "Builder has already been used");
- Objects.requireNonNull(uri);
- mUri = uri;
- return this;
+ mDocumentId = Objects.requireNonNull(documentId);
}
/**
@@ -129,28 +120,27 @@ public final class ReportSystemUsageRequest {
* @throws IllegalStateException if the builder has already been used
*/
@NonNull
- public ReportSystemUsageRequest.Builder setUsageTimeMillis(long usageTimeMillis) {
+ public ReportSystemUsageRequest.Builder setUsageTimestampMillis(
+ @CurrentTimeMillisLong long usageTimestampMillis) {
Preconditions.checkState(!mBuilt, "Builder has already been used");
- mUsageTimeMillis = usageTimeMillis;
+ mUsageTimestampMillis = usageTimestampMillis;
return this;
}
/**
* Builds a new {@link ReportSystemUsageRequest}.
*
- * @throws NullPointerException if {@link #setUri} has never been called
* @throws IllegalStateException if the builder has already been used
*/
@NonNull
public ReportSystemUsageRequest build() {
Preconditions.checkState(!mBuilt, "Builder has already been used");
- Objects.requireNonNull(mUri, "ReportUsageRequest is missing a URI");
- if (mUsageTimeMillis == null) {
- mUsageTimeMillis = System.currentTimeMillis();
+ if (mUsageTimestampMillis == null) {
+ mUsageTimestampMillis = System.currentTimeMillis();
}
mBuilt = true;
return new ReportSystemUsageRequest(
- mPackageName, mDatabase, mNamespace, mUri, mUsageTimeMillis);
+ mPackageName, mDatabase, mNamespace, mDocumentId, mUsageTimestampMillis);
}
}
}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/ReportUsageRequest.java b/apex/appsearch/framework/java/external/android/app/appsearch/ReportUsageRequest.java
index 925bde92d69d..8c8ade8c52d0 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/ReportUsageRequest.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/ReportUsageRequest.java
@@ -16,6 +16,7 @@
package android.app.appsearch;
+import android.annotation.CurrentTimeMillisLong;
import android.annotation.NonNull;
import com.android.internal.util.Preconditions;
@@ -31,13 +32,14 @@ import java.util.Objects;
*/
public final class ReportUsageRequest {
private final String mNamespace;
- private final String mUri;
- private final long mUsageTimeMillis;
+ private final String mDocumentId;
+ private final long mUsageTimestampMillis;
- ReportUsageRequest(@NonNull String namespace, @NonNull String uri, long usageTimeMillis) {
+ ReportUsageRequest(
+ @NonNull String namespace, @NonNull String documentId, long usageTimestampMillis) {
mNamespace = Objects.requireNonNull(namespace);
- mUri = Objects.requireNonNull(uri);
- mUsageTimeMillis = usageTimeMillis;
+ mDocumentId = Objects.requireNonNull(documentId);
+ mUsageTimestampMillis = usageTimestampMillis;
}
/** Returns the namespace of the document that was used. */
@@ -46,10 +48,10 @@ public final class ReportUsageRequest {
return mNamespace;
}
- /** Returns the URI of document that was used. */
+ /** Returns the ID of document that was used. */
@NonNull
- public String getUri() {
- return mUri;
+ public String getDocumentId() {
+ return mDocumentId;
}
/**
@@ -58,35 +60,22 @@ public final class ReportUsageRequest {
*
* <p>The value is in the {@link System#currentTimeMillis} time base.
*/
- public long getUsageTimeMillis() {
- return mUsageTimeMillis;
+ @CurrentTimeMillisLong
+ public long getUsageTimestampMillis() {
+ return mUsageTimestampMillis;
}
/** Builder for {@link ReportUsageRequest} objects. */
public static final class Builder {
private final String mNamespace;
- private String mUri;
- private Long mUsageTimeMillis;
+ private final String mDocumentId;
+ private Long mUsageTimestampMillis;
private boolean mBuilt = false;
/** Creates a {@link ReportUsageRequest.Builder} instance. */
- public Builder(@NonNull String namespace) {
+ public Builder(@NonNull String namespace, @NonNull String documentId) {
mNamespace = Objects.requireNonNull(namespace);
- }
-
- /**
- * Sets the URI of the document being used.
- *
- * <p>This field is required.
- *
- * @throws IllegalStateException if the builder has already been used
- */
- @NonNull
- public ReportUsageRequest.Builder setUri(@NonNull String uri) {
- Preconditions.checkState(!mBuilt, "Builder has already been used");
- Objects.requireNonNull(uri);
- mUri = uri;
- return this;
+ mDocumentId = Objects.requireNonNull(documentId);
}
/**
@@ -101,27 +90,26 @@ public final class ReportUsageRequest {
* @throws IllegalStateException if the builder has already been used
*/
@NonNull
- public ReportUsageRequest.Builder setUsageTimeMillis(long usageTimeMillis) {
+ public ReportUsageRequest.Builder setUsageTimestampMillis(
+ @CurrentTimeMillisLong long usageTimestampMillis) {
Preconditions.checkState(!mBuilt, "Builder has already been used");
- mUsageTimeMillis = usageTimeMillis;
+ mUsageTimestampMillis = usageTimestampMillis;
return this;
}
/**
* Builds a new {@link ReportUsageRequest}.
*
- * @throws NullPointerException if {@link #setUri} has never been called
* @throws IllegalStateException if the builder has already been used
*/
@NonNull
public ReportUsageRequest build() {
Preconditions.checkState(!mBuilt, "Builder has already been used");
- Objects.requireNonNull(mUri, "ReportUsageRequest is missing a URI");
- if (mUsageTimeMillis == null) {
- mUsageTimeMillis = System.currentTimeMillis();
+ if (mUsageTimestampMillis == null) {
+ mUsageTimestampMillis = System.currentTimeMillis();
}
mBuilt = true;
- return new ReportUsageRequest(mNamespace, mUri, mUsageTimeMillis);
+ return new ReportUsageRequest(mNamespace, mDocumentId, mUsageTimestampMillis);
}
}
}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/SearchResult.java b/apex/appsearch/framework/java/external/android/app/appsearch/SearchResult.java
index 432f838bc78c..4fc654f7e5d2 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/SearchResult.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/SearchResult.java
@@ -415,16 +415,13 @@ public final class SearchResult {
private static String getPropertyValues(GenericDocument document, String propertyName) {
// In IcingLib snippeting is available for only 3 data types i.e String, double and
// long, so we need to check which of these three are requested.
- // TODO (tytytyww): getPropertyStringArray takes property name, handle for property
- // path.
// TODO (tytytyww): support double[] and long[].
- String[] values = document.getPropertyStringArray(propertyName);
- if (values == null) {
- throw new IllegalStateException("No content found for requested property path!");
+ String result = document.getPropertyString(propertyName);
+ if (result == null) {
+ throw new IllegalStateException(
+ "No content found for requested property path: " + propertyName);
}
-
- // TODO(b/175146044): Return the proper match based on the index in the propertyName.
- return values[0];
+ return result;
}
/** Builder for {@link MatchInfo} objects. */
@@ -433,23 +430,22 @@ public final class SearchResult {
private boolean mBuilt = false;
/**
- * Sets the property path corresponding to the given entry.
+ * Creates a new {@link MatchInfo.Builder} reporting a match with the given property
+ * path.
*
- * <p>A property path is a '.' - delimited sequence of property names indicating which
+ * <p>A property path is a dot-delimited sequence of property names indicating which
* property in the document these snippets correspond to.
*
- * <p>Example properties: 'body', 'sender.name', 'sender.emailaddress', etc. For class
- * example 1 this returns "subject"
+ * <p>Example properties: 'body', 'sender.name', 'sender.emailaddress', etc.
+ * For class example 1 this returns "subject".
*
- * @throws IllegalStateException if the builder has already been used
+ * @param propertyPath A {@code dot-delimited sequence of property names indicating
+ * which property in the document these snippets correspond to.
*/
- @NonNull
- public Builder setPropertyPath(@NonNull String propertyPath) {
- Preconditions.checkState(!mBuilt, "Builder has already been used");
+ public Builder(@NonNull String propertyPath) {
mBundle.putString(
SearchResult.MatchInfo.PROPERTY_PATH_FIELD,
Objects.requireNonNull(propertyPath));
- return this;
}
/**
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/SearchSpec.java b/apex/appsearch/framework/java/external/android/app/appsearch/SearchSpec.java
index d466bf1359d0..20e5b9da8d53 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/SearchSpec.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/SearchSpec.java
@@ -20,7 +20,6 @@ import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.SuppressLint;
-import android.app.appsearch.exceptions.IllegalSearchSpecException;
import android.os.Bundle;
import android.util.ArrayMap;
@@ -323,9 +322,15 @@ public final class SearchSpec {
public Builder() {
mBundle = new Bundle();
mBundle.putInt(NUM_PER_PAGE_FIELD, DEFAULT_NUM_PER_PAGE);
+ mBundle.putInt(TERM_MATCH_TYPE_FIELD, TERM_MATCH_PREFIX);
}
- /** Indicates how the query terms should match {@code TermMatchCode} in the index. */
+ /**
+ * Indicates how the query terms should match {@code TermMatchCode} in the index.
+ *
+ * <p>If this method is not called, the default term match type is {@link
+ * SearchSpec#TERM_MATCH_PREFIX}.
+ */
@NonNull
public Builder setTermMatch(@TermMatch int termMatchTypeCode) {
Preconditions.checkState(!mBuilt, "Builder has already been used");
@@ -634,9 +639,6 @@ public final class SearchSpec {
@NonNull
public SearchSpec build() {
Preconditions.checkState(!mBuilt, "Builder has already been used");
- if (!mBundle.containsKey(TERM_MATCH_TYPE_FIELD)) {
- throw new IllegalSearchSpecException("Missing termMatchType field.");
- }
mBundle.putStringArrayList(NAMESPACE_FIELD, mNamespaces);
mBundle.putStringArrayList(SCHEMA_FIELD, mSchemas);
mBundle.putStringArrayList(PACKAGE_NAME_FIELD, mPackageNames);
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaRequest.java b/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaRequest.java
index 8f7a0bf61f3e..275b2c337c3c 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaRequest.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaRequest.java
@@ -414,7 +414,6 @@ public final class SetSchemaRequest {
@NonNull
public SetSchemaRequest build() {
Preconditions.checkState(!mBuilt, "Builder has already been used");
- mBuilt = true;
// Verify that any schema types with display or visibility settings refer to a real
// schema.
@@ -432,6 +431,7 @@ public final class SetSchemaRequest {
"Schema types " + referencedSchemas + " referenced, but were not added.");
}
+ mBuilt = true;
return new SetSchemaRequest(
mSchemas,
mSchemasNotDisplayedBySystem,
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaResponse.java b/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaResponse.java
index 7be589f727ce..8a162d49e151 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaResponse.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaResponse.java
@@ -86,7 +86,7 @@ public class SetSchemaResponse {
* <p>A {@link MigrationFailure} will be generated if the system trying to save a post-migrated
* {@link GenericDocument} but fail.
*
- * <p>{@link MigrationFailure} contains the uri, namespace and schemaType of the post-migrated
+ * <p>{@link MigrationFailure} contains the namespace, id and schemaType of the post-migrated
* {@link GenericDocument} and the error reason. Mostly it will be mismatch the schema it
* migrated to.
*/
@@ -257,14 +257,40 @@ public class SetSchemaResponse {
public static class MigrationFailure {
private static final String SCHEMA_TYPE_FIELD = "schemaType";
private static final String NAMESPACE_FIELD = "namespace";
- private static final String URI_FIELD = "uri";
+ private static final String DOCUMENT_ID_FIELD = "id";
private static final String ERROR_MESSAGE_FIELD = "errorMessage";
private static final String RESULT_CODE_FIELD = "resultCode";
private final Bundle mBundle;
+ /**
+ * Constructs a new {@link MigrationFailure}.
+ *
+ * @param namespace The namespace of the document which failed to be migrated.
+ * @param documentId The id of the document which failed to be migrated.
+ * @param schemaType The type of the document which failed to be migrated.
+ * @param failedResult The reason why the document failed to be indexed.
+ * @throws IllegalArgumentException if the provided {@code failedResult} was not a failure.
+ */
+ public MigrationFailure(
+ @NonNull String namespace,
+ @NonNull String documentId,
+ @NonNull String schemaType,
+ @NonNull AppSearchResult<?> failedResult) {
+ mBundle = new Bundle();
+ mBundle.putString(NAMESPACE_FIELD, Objects.requireNonNull(namespace));
+ mBundle.putString(DOCUMENT_ID_FIELD, Objects.requireNonNull(documentId));
+ mBundle.putString(SCHEMA_TYPE_FIELD, Objects.requireNonNull(schemaType));
+
+ Objects.requireNonNull(failedResult);
+ Preconditions.checkArgument(
+ !failedResult.isSuccess(), "failedResult was actually successful");
+ mBundle.putString(ERROR_MESSAGE_FIELD, failedResult.getErrorMessage());
+ mBundle.putInt(RESULT_CODE_FIELD, failedResult.getResultCode());
+ }
+
MigrationFailure(@NonNull Bundle bundle) {
- mBundle = bundle;
+ mBundle = Objects.requireNonNull(bundle);
}
/**
@@ -277,27 +303,27 @@ public class SetSchemaResponse {
return mBundle;
}
- /** Returns the schema type of the {@link GenericDocument} that fails to be migrated. */
+ /** Returns the namespace of the {@link GenericDocument} that failed to be migrated. */
@NonNull
- public String getSchemaType() {
- return mBundle.getString(SCHEMA_TYPE_FIELD, /*defaultValue=*/ "");
+ public String getNamespace() {
+ return mBundle.getString(NAMESPACE_FIELD, /*defaultValue=*/ "");
}
- /** Returns the namespace of the {@link GenericDocument} that fails to be migrated. */
+ /** Returns the id of the {@link GenericDocument} that failed to be migrated. */
@NonNull
- public String getNamespace() {
- return mBundle.getString(NAMESPACE_FIELD, /*defaultValue=*/ "");
+ public String getDocumentId() {
+ return mBundle.getString(DOCUMENT_ID_FIELD, /*defaultValue=*/ "");
}
- /** Returns the uri of the {@link GenericDocument} that fails to be migrated. */
+ /** Returns the schema type of the {@link GenericDocument} that failed to be migrated. */
@NonNull
- public String getUri() {
- return mBundle.getString(URI_FIELD, /*defaultValue=*/ "");
+ public String getSchemaType() {
+ return mBundle.getString(SCHEMA_TYPE_FIELD, /*defaultValue=*/ "");
}
/**
- * Returns the {@link AppSearchResult} that indicates why the post-migrated {@link
- * GenericDocument} fails to be saved.
+ * Returns the {@link AppSearchResult} that indicates why the post-migration {@link
+ * GenericDocument} failed to be indexed.
*/
@NonNull
public AppSearchResult<Void> getAppSearchResult() {
@@ -305,61 +331,5 @@ public class SetSchemaResponse {
mBundle.getInt(RESULT_CODE_FIELD),
mBundle.getString(ERROR_MESSAGE_FIELD, /*defaultValue=*/ ""));
}
-
- /** Builder for {@link MigrationFailure} objects. */
- public static final class Builder {
- private String mSchemaType;
- private String mNamespace;
- private String mUri;
- private final Bundle mBundle = new Bundle();
- private AppSearchResult<Void> mFailureResult;
- private boolean mBuilt = false;
-
- /** Sets the schema type for the {@link MigrationFailure}. */
- @NonNull
- public Builder setSchemaType(@NonNull String schemaType) {
- Preconditions.checkState(!mBuilt, "Builder has already been used");
- mSchemaType = Objects.requireNonNull(schemaType);
- return this;
- }
-
- /** Sets the namespace for the {@link MigrationFailure}. */
- @NonNull
- public Builder setNamespace(@NonNull String namespace) {
- Preconditions.checkState(!mBuilt, "Builder has already been used");
- mNamespace = Objects.requireNonNull(namespace);
- return this;
- }
-
- /** Sets the uri for the {@link MigrationFailure}. */
- @NonNull
- public Builder setUri(@NonNull String uri) {
- Preconditions.checkState(!mBuilt, "Builder has already been used");
- mUri = Objects.requireNonNull(uri);
- return this;
- }
-
- /** Sets the failure {@link AppSearchResult} for the {@link MigrationFailure}. */
- @NonNull
- public Builder setAppSearchResult(@NonNull AppSearchResult<Void> appSearchResult) {
- Preconditions.checkState(!mBuilt, "Builder has already been used");
- Preconditions.checkState(!appSearchResult.isSuccess(), "Input a success result");
- mFailureResult = Objects.requireNonNull(appSearchResult);
- return this;
- }
-
- /** Builds a {@link MigrationFailure} object. */
- @NonNull
- public MigrationFailure build() {
- Preconditions.checkState(!mBuilt, "Builder has already been used");
- mBundle.putString(SCHEMA_TYPE_FIELD, mSchemaType);
- mBundle.putString(NAMESPACE_FIELD, mNamespace);
- mBundle.putString(URI_FIELD, mUri);
- mBundle.putString(ERROR_MESSAGE_FIELD, mFailureResult.getErrorMessage());
- mBundle.putInt(RESULT_CODE_FIELD, mFailureResult.getResultCode());
- mBuilt = true;
- return new MigrationFailure(mBundle);
- }
- }
}
}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/exceptions/IllegalSearchSpecException.java b/apex/appsearch/framework/java/external/android/app/appsearch/exceptions/IllegalSearchSpecException.java
deleted file mode 100644
index 0b5dc2ece6f1..000000000000
--- a/apex/appsearch/framework/java/external/android/app/appsearch/exceptions/IllegalSearchSpecException.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.appsearch.exceptions;
-
-import android.annotation.NonNull;
-
-/**
- * Indicates that a {@link android.app.appsearch.SearchResult} has logical inconsistencies such as
- * unpopulated mandatory fields or illegal combinations of parameters.
- *
- * @hide
- */
-public class IllegalSearchSpecException extends IllegalArgumentException {
- /**
- * Constructs a new {@link IllegalSearchSpecException}.
- *
- * @param message A developer-readable description of the issue with the bundle.
- */
- public IllegalSearchSpecException(@NonNull String message) {
- super(message);
- }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
index f6f5c98856c7..ec81ed25025a 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
@@ -308,13 +308,13 @@ public class AppSearchManagerService extends SystemService {
GenericDocument document = new GenericDocument(documentBundles.get(i));
try {
impl.putDocument(packageName, databaseName, document, logger);
- resultBuilder.setSuccess(document.getUri(), /*result=*/ null);
+ resultBuilder.setSuccess(document.getId(), /*result=*/ null);
++operationSuccessCount;
} catch (Throwable t) {
- resultBuilder.setResult(document.getUri(),
+ resultBuilder.setResult(document.getId(),
throwableToFailedResult(t));
AppSearchResult<Void> result = throwableToFailedResult(t);
- resultBuilder.setResult(document.getUri(), result);
+ resultBuilder.setResult(document.getId(), result);
// for failures, we would just log the one for last failure
statusCode = result.getResultCode();
++operationFailureCount;
@@ -354,14 +354,14 @@ public class AppSearchManagerService extends SystemService {
@NonNull String packageName,
@NonNull String databaseName,
@NonNull String namespace,
- @NonNull List<String> uris,
+ @NonNull List<String> ids,
@NonNull Map<String, List<String>> typePropertyPaths,
@UserIdInt int userId,
@NonNull IAppSearchBatchResultCallback callback) {
Objects.requireNonNull(packageName);
Objects.requireNonNull(databaseName);
Objects.requireNonNull(namespace);
- Objects.requireNonNull(uris);
+ Objects.requireNonNull(ids);
Objects.requireNonNull(callback);
int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid);
@@ -373,19 +373,19 @@ public class AppSearchManagerService extends SystemService {
new AppSearchBatchResult.Builder<>();
AppSearchImpl impl =
mImplInstanceManager.getAppSearchImpl(callingUserId);
- for (int i = 0; i < uris.size(); i++) {
- String uri = uris.get(i);
+ for (int i = 0; i < ids.size(); i++) {
+ String id = ids.get(i);
try {
GenericDocument document =
impl.getDocument(
packageName,
databaseName,
namespace,
- uri,
+ id,
typePropertyPaths);
- resultBuilder.setSuccess(uri, document.getBundle());
+ resultBuilder.setSuccess(id, document.getBundle());
} catch (Throwable t) {
- resultBuilder.setResult(uri, throwableToFailedResult(t));
+ resultBuilder.setResult(id, throwableToFailedResult(t));
}
}
invokeCallbackOnResult(callback, resultBuilder.build());
@@ -578,14 +578,12 @@ public class AppSearchManagerService extends SystemService {
impl.putDocument(packageName, databaseName, document,
/*logger=*/ null);
} catch (Throwable t) {
- migrationFailureBundles.add(
- new SetSchemaResponse.MigrationFailure.Builder()
- .setNamespace(document.getNamespace())
- .setSchemaType(document.getSchemaType())
- .setUri(document.getUri())
- .setAppSearchResult(AppSearchResult
- .throwableToFailedResult(t))
- .build().getBundle());
+ migrationFailureBundles.add(new SetSchemaResponse.MigrationFailure(
+ document.getNamespace(),
+ document.getId(),
+ document.getSchemaType(),
+ AppSearchResult.throwableToFailedResult(t))
+ .getBundle());
}
}
}
@@ -603,14 +601,14 @@ public class AppSearchManagerService extends SystemService {
@NonNull String packageName,
@NonNull String databaseName,
@NonNull String namespace,
- @NonNull String uri,
+ @NonNull String documentId,
long usageTimeMillis,
boolean systemUsage,
@UserIdInt int userId,
@NonNull IAppSearchResultCallback callback) {
Objects.requireNonNull(databaseName);
Objects.requireNonNull(namespace);
- Objects.requireNonNull(uri);
+ Objects.requireNonNull(documentId);
Objects.requireNonNull(callback);
int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid);
@@ -625,7 +623,7 @@ public class AppSearchManagerService extends SystemService {
AppSearchImpl impl =
mImplInstanceManager.getAppSearchImpl(callingUserId);
impl.reportUsage(
- packageName, databaseName, namespace, uri,
+ packageName, databaseName, namespace, documentId,
usageTimeMillis, systemUsage);
invokeCallbackOnResult(
callback, AppSearchResult.newSuccessfulResult(/*result=*/ null));
@@ -636,16 +634,16 @@ public class AppSearchManagerService extends SystemService {
}
@Override
- public void removeByUri(
+ public void removeByDocumentId(
@NonNull String packageName,
@NonNull String databaseName,
@NonNull String namespace,
- @NonNull List<String> uris,
+ @NonNull List<String> ids,
@UserIdInt int userId,
@NonNull IAppSearchBatchResultCallback callback) {
Objects.requireNonNull(packageName);
Objects.requireNonNull(databaseName);
- Objects.requireNonNull(uris);
+ Objects.requireNonNull(ids);
Objects.requireNonNull(callback);
int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid);
@@ -657,13 +655,13 @@ public class AppSearchManagerService extends SystemService {
new AppSearchBatchResult.Builder<>();
AppSearchImpl impl =
mImplInstanceManager.getAppSearchImpl(callingUserId);
- for (int i = 0; i < uris.size(); i++) {
- String uri = uris.get(i);
+ for (int i = 0; i < ids.size(); i++) {
+ String id = ids.get(i);
try {
- impl.remove(packageName, databaseName, namespace, uri);
- resultBuilder.setSuccess(uri, /*result= */ null);
+ impl.remove(packageName, databaseName, namespace, id);
+ resultBuilder.setSuccess(id, /*result= */ null);
} catch (Throwable t) {
- resultBuilder.setResult(uri, throwableToFailedResult(t));
+ resultBuilder.setResult(id, throwableToFailedResult(t));
}
}
// Now that the batch has been written. Persist the newly written data.
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/VisibilityStore.java b/apex/appsearch/service/java/com/android/server/appsearch/VisibilityStore.java
index 4de52fb65d93..a8d429b24c63 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/VisibilityStore.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/VisibilityStore.java
@@ -103,14 +103,13 @@ public class VisibilityStore {
new AppSearchSchema.Builder(VISIBILITY_TYPE)
.addProperty(
new AppSearchSchema.StringPropertyConfig.Builder(
- NOT_PLATFORM_SURFACEABLE_PROPERTY)
+ NOT_PLATFORM_SURFACEABLE_PROPERTY)
.setCardinality(
AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
.build())
.addProperty(
new AppSearchSchema.DocumentPropertyConfig.Builder(
- PACKAGE_ACCESSIBLE_PROPERTY)
- .setSchemaType(PACKAGE_ACCESSIBLE_TYPE)
+ PACKAGE_ACCESSIBLE_PROPERTY, PACKAGE_ACCESSIBLE_TYPE)
.setCardinality(
AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
.build())
@@ -160,9 +159,9 @@ public class VisibilityStore {
private static final String NAMESPACE = "";
/**
- * Prefix to add to all visibility document uri's. IcingSearchEngine doesn't allow empty uri's.
+ * Prefix to add to all visibility document ids. IcingSearchEngine doesn't allow empty ids.
*/
- private static final String URI_PREFIX = "uri:";
+ private static final String ID_PREFIX = "uri:";
private final AppSearchImpl mAppSearchImpl;
@@ -259,13 +258,13 @@ public class VisibilityStore {
}
try {
- // Note: We use the other clients' prefixed names as uris
+ // Note: We use the other clients' prefixed names as ids
GenericDocument document =
mAppSearchImpl.getDocument(
PACKAGE_NAME,
DATABASE_NAME,
NAMESPACE,
- /*uri=*/ addUriPrefix(prefix),
+ /*id=*/ addIdPrefix(prefix),
/*typePropertyPaths=*/ Collections.emptyMap());
// Update platform visibility settings
@@ -340,7 +339,7 @@ public class VisibilityStore {
// Persist the document
GenericDocument.Builder<?> visibilityDocument =
new GenericDocument.Builder<>(
- NAMESPACE, /*uri=*/ addUriPrefix(prefix), VISIBILITY_TYPE);
+ NAMESPACE, /*id=*/ addIdPrefix(prefix), VISIBILITY_TYPE);
if (!schemasNotPlatformSurfaceable.isEmpty()) {
visibilityDocument.setPropertyString(
NOT_PLATFORM_SURFACEABLE_PROPERTY,
@@ -353,7 +352,7 @@ public class VisibilityStore {
schemasPackageAccessible.entrySet()) {
for (int i = 0; i < entry.getValue().size(); i++) {
GenericDocument packageAccessibleDocument = new GenericDocument.Builder<>(
- NAMESPACE, /*uri=*/ "", PACKAGE_ACCESSIBLE_TYPE)
+ NAMESPACE, /*id=*/ "", PACKAGE_ACCESSIBLE_TYPE)
.setPropertyString(
PACKAGE_NAME_PROPERTY,
entry.getValue().get(i).getPackageName())
@@ -480,13 +479,13 @@ public class VisibilityStore {
}
/**
- * Adds a uri prefix to create a visibility store document's uri.
+ * Adds a prefix to create a visibility store document's id.
*
- * @param uri Non-prefixed uri
- * @return Prefixed uri
+ * @param id Non-prefixed id
+ * @return Prefixed id
*/
- private static String addUriPrefix(String uri) {
- return URI_PREFIX + uri;
+ private static String addIdPrefix(String id) {
+ return ID_PREFIX + id;
}
/**
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java
index 50ac054a05fc..98fcb1370d8b 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java
@@ -30,7 +30,7 @@ import android.annotation.Nullable;
import android.annotation.WorkerThread;
import android.app.appsearch.AppSearchSchema;
import android.app.appsearch.GenericDocument;
-import android.app.appsearch.GetByUriRequest;
+import android.app.appsearch.GetByDocumentIdRequest;
import android.app.appsearch.GetSchemaResponse;
import android.app.appsearch.PackageIdentifier;
import android.app.appsearch.SearchResultPage;
@@ -573,14 +573,14 @@ public final class AppSearchImpl implements Closeable {
}
/**
- * Retrieves a document from the AppSearch index by URI.
+ * Retrieves a document from the AppSearch index by namespace and document ID.
*
* <p>This method belongs to query group.
*
* @param packageName The package that owns this document.
* @param databaseName The databaseName this document resides in.
* @param namespace The namespace this document resides in.
- * @param uri The URI of the document to get.
+ * @param id The ID of the document to get.
* @param typePropertyPaths A map of schema type to a list of property paths to return in the
* result.
* @return The Document contents
@@ -591,7 +591,7 @@ public final class AppSearchImpl implements Closeable {
@NonNull String packageName,
@NonNull String databaseName,
@NonNull String namespace,
- @NonNull String uri,
+ @NonNull String id,
@NonNull Map<String, List<String>> typePropertyPaths)
throws AppSearchException {
mReadWriteLock.readLock().lock();
@@ -606,7 +606,8 @@ public final class AppSearchImpl implements Closeable {
TypePropertyMask typePropertyMask = nonPrefixedPropertyMasks.get(i);
String nonPrefixedType = typePropertyMask.getSchemaType();
String prefixedType =
- nonPrefixedType.equals(GetByUriRequest.PROJECTION_SCHEMA_TYPE_WILDCARD)
+ nonPrefixedType.equals(
+ GetByDocumentIdRequest.PROJECTION_SCHEMA_TYPE_WILDCARD)
? nonPrefixedType
: prefix + nonPrefixedType;
prefixedPropertyMasks.add(
@@ -618,7 +619,7 @@ public final class AppSearchImpl implements Closeable {
.build();
GetResultProto getResultProto =
- mIcingSearchEngineLocked.get(prefix + namespace, uri, getResultSpec);
+ mIcingSearchEngineLocked.get(prefix + namespace, id, getResultSpec);
checkSuccess(getResultProto.getStatus());
// The schema type map cannot be null at this point. It could only be null if no
@@ -881,7 +882,7 @@ public final class AppSearchImpl implements Closeable {
@NonNull String packageName,
@NonNull String databaseName,
@NonNull String namespace,
- @NonNull String uri,
+ @NonNull String documentId,
long usageTimestampMillis,
boolean systemUsage)
throws AppSearchException {
@@ -897,7 +898,7 @@ public final class AppSearchImpl implements Closeable {
UsageReport report =
UsageReport.newBuilder()
.setDocumentNamespace(prefixedNamespace)
- .setDocumentUri(uri)
+ .setDocumentUri(documentId)
.setUsageTimestampMs(usageTimestampMillis)
.setUsageType(usageType)
.build();
@@ -910,21 +911,21 @@ public final class AppSearchImpl implements Closeable {
}
/**
- * Removes the given document by URI.
+ * Removes the given document by id.
*
* <p>This method belongs to mutate group.
*
* @param packageName The package name that owns the document.
* @param databaseName The databaseName the document is in.
* @param namespace Namespace of the document to remove.
- * @param uri URI of the document to remove.
+ * @param id ID of the document to remove.
* @throws AppSearchException on IcingSearchEngine error.
*/
public void remove(
@NonNull String packageName,
@NonNull String databaseName,
@NonNull String namespace,
- @NonNull String uri)
+ @NonNull String id)
throws AppSearchException {
mReadWriteLock.writeLock().lock();
try {
@@ -932,7 +933,7 @@ public final class AppSearchImpl implements Closeable {
String prefixedNamespace = createPrefix(packageName, databaseName) + namespace;
DeleteResultProto deleteResultProto =
- mIcingSearchEngineLocked.delete(prefixedNamespace, uri);
+ mIcingSearchEngineLocked.delete(prefixedNamespace, id);
checkSuccess(deleteResultProto.getStatus());
} finally {
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverter.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverter.java
index 5ff56abd870a..0cdad37d2080 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverter.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverter.java
@@ -52,7 +52,7 @@ public final class GenericDocumentToProtoConverter {
Objects.requireNonNull(document);
DocumentProto.Builder mProtoBuilder = DocumentProto.newBuilder();
mProtoBuilder
- .setUri(document.getUri())
+ .setUri(document.getId())
.setSchema(document.getSchemaType())
.setNamespace(document.getNamespace())
.setScore(document.getScore())
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverter.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverter.java
index e3fa7e08aac4..80f700746b35 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverter.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverter.java
@@ -104,7 +104,7 @@ public final class SchemaToProtoConverter {
.setDocumentIndexingConfig(
DocumentIndexingConfig.newBuilder()
.setIndexNestedProperties(
- documentProperty.isIndexNestedProperties()));
+ documentProperty.shouldIndexNestedProperties()));
}
return builder.build();
}
@@ -174,10 +174,10 @@ public final class SchemaToProtoConverter {
@NonNull
private static AppSearchSchema.DocumentPropertyConfig toDocumentPropertyConfig(
@NonNull PropertyConfigProto proto) {
- return new AppSearchSchema.DocumentPropertyConfig.Builder(proto.getPropertyName())
+ return new AppSearchSchema.DocumentPropertyConfig.Builder(
+ proto.getPropertyName(), proto.getSchemaType())
.setCardinality(proto.getCardinality().getNumber())
- .setSchemaType(proto.getSchemaType())
- .setIndexNestedProperties(
+ .setShouldIndexNestedProperties(
proto.getDocumentIndexingConfig().getIndexNestedProperties())
.build();
}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchResultToProtoConverter.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchResultToProtoConverter.java
index 57c1590d2bef..84220d72cbab 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchResultToProtoConverter.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchResultToProtoConverter.java
@@ -125,8 +125,7 @@ public class SearchResultToProtoConverter {
private static SearchResult.MatchInfo toMatchInfo(
@NonNull SnippetMatchProto snippetMatchProto, @NonNull String propertyPath) {
- return new SearchResult.MatchInfo.Builder()
- .setPropertyPath(propertyPath)
+ return new SearchResult.MatchInfo.Builder(propertyPath)
.setExactMatchRange(
new SearchResult.MatchRange(
snippetMatchProto.getExactMatchPosition(),
diff --git a/apex/appsearch/synced_jetpack_changeid.txt b/apex/appsearch/synced_jetpack_changeid.txt
index f99664b4c685..ce0ebe62f65b 100644
--- a/apex/appsearch/synced_jetpack_changeid.txt
+++ b/apex/appsearch/synced_jetpack_changeid.txt
@@ -1 +1 @@
-If9d1d770d2327d7d0db7d82acfc54787b5de64bc
+I06df2c636d26419e653c5d8c9e7d15449da6816e
diff --git a/apex/appsearch/testing/java/com/android/server/appsearch/testing/AppSearchSessionShimImpl.java b/apex/appsearch/testing/java/com/android/server/appsearch/testing/AppSearchSessionShimImpl.java
index 61933672a1e1..930cd60beb58 100644
--- a/apex/appsearch/testing/java/com/android/server/appsearch/testing/AppSearchSessionShimImpl.java
+++ b/apex/appsearch/testing/java/com/android/server/appsearch/testing/AppSearchSessionShimImpl.java
@@ -24,10 +24,10 @@ import android.app.appsearch.AppSearchSession;
import android.app.appsearch.AppSearchSessionShim;
import android.app.appsearch.BatchResultCallback;
import android.app.appsearch.GenericDocument;
-import android.app.appsearch.GetByUriRequest;
+import android.app.appsearch.GetByDocumentIdRequest;
import android.app.appsearch.GetSchemaResponse;
import android.app.appsearch.PutDocumentsRequest;
-import android.app.appsearch.RemoveByUriRequest;
+import android.app.appsearch.RemoveByDocumentIdRequest;
import android.app.appsearch.ReportUsageRequest;
import android.app.appsearch.SearchResults;
import android.app.appsearch.SearchResultsShim;
@@ -121,11 +121,12 @@ public class AppSearchSessionShimImpl implements AppSearchSessionShim {
@Override
@NonNull
- public ListenableFuture<AppSearchBatchResult<String, GenericDocument>> getByUri(
- @NonNull GetByUriRequest request) {
+ public ListenableFuture<AppSearchBatchResult<String, GenericDocument>> getByDocumentId(
+ @NonNull GetByDocumentIdRequest request) {
SettableFuture<AppSearchBatchResult<String, GenericDocument>> future =
SettableFuture.create();
- mAppSearchSession.getByUri(request, mExecutor, new BatchResultCallbackAdapter<>(future));
+ mAppSearchSession.getByDocumentId(
+ request, mExecutor, new BatchResultCallbackAdapter<>(future));
return future;
}
@@ -148,7 +149,7 @@ public class AppSearchSessionShimImpl implements AppSearchSessionShim {
@Override
@NonNull
public ListenableFuture<AppSearchBatchResult<String, Void>> remove(
- @NonNull RemoveByUriRequest request) {
+ @NonNull RemoveByDocumentIdRequest request) {
SettableFuture<AppSearchBatchResult<String, Void>> future = SettableFuture.create();
mAppSearchSession.remove(request, mExecutor, new BatchResultCallbackAdapter<>(future));
return future;
diff --git a/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchSessionShim.java b/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchSessionShim.java
index 494945db5655..345b059d037c 100644
--- a/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchSessionShim.java
+++ b/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchSessionShim.java
@@ -25,10 +25,14 @@ import java.io.Closeable;
import java.util.Set;
/**
- * Represents a connection to an AppSearch storage system where {@link GenericDocument}s can be
- * placed and queried.
+ * Provides a connection to a single AppSearch database.
+ *
+ * <p>An {@link AppSearchSessionShim} instance provides access to database operations such as
+ * setting a schema, adding documents, and searching.
*
* <p>All implementations of this interface must be thread safe.
+ *
+ * @see GlobalSearchSessionShim
*/
public interface AppSearchSessionShim extends Closeable {
@@ -76,28 +80,29 @@ public interface AppSearchSessionShim extends Closeable {
*
* @param request containing documents to be indexed.
* @return a {@link ListenableFuture} which resolves to an {@link AppSearchBatchResult}. The
- * keys of the returned {@link AppSearchBatchResult} are the URIs of the input documents.
- * The values are either {@code null} if the corresponding document was successfully
- * indexed, or a failed {@link AppSearchResult} otherwise.
+ * keys of the returned {@link AppSearchBatchResult} are the IDs of the input documents. The
+ * values are either {@code null} if the corresponding document was successfully indexed, or
+ * a failed {@link AppSearchResult} otherwise.
*/
@NonNull
ListenableFuture<AppSearchBatchResult<String, Void>> put(@NonNull PutDocumentsRequest request);
/**
- * Gets {@link GenericDocument} objects by URIs and namespace from the {@link
+ * Gets {@link GenericDocument} objects by document IDs in a namespace from the {@link
* AppSearchSessionShim} database.
*
- * @param request a request containing URIs and namespace to get documents for.
+ * @param request a request containing a namespace and IDs to get documents for.
* @return A {@link ListenableFuture} which resolves to an {@link AppSearchBatchResult}. The
- * keys of the {@link AppSearchBatchResult} represent the input URIs from the {@link
- * GetByUriRequest} object. The values are either the corresponding {@link GenericDocument}
- * object for the URI on success, or an {@link AppSearchResult} object on failure. For
- * example, if a URI is not found, the value for that URI will be set to an {@link
- * AppSearchResult} object with result code: {@link AppSearchResult#RESULT_NOT_FOUND}.
+ * keys of the {@link AppSearchBatchResult} represent the input document IDs from the {@link
+ * GetByDocumentIdRequest} object. The values are either the corresponding {@link
+ * GenericDocument} object for the ID on success, or an {@link AppSearchResult} object on
+ * failure. For example, if an ID is not found, the value for that ID will be set to an
+ * {@link AppSearchResult} object with result code: {@link
+ * AppSearchResult#RESULT_NOT_FOUND}.
*/
@NonNull
- ListenableFuture<AppSearchBatchResult<String, GenericDocument>> getByUri(
- @NonNull GetByUriRequest request);
+ ListenableFuture<AppSearchBatchResult<String, GenericDocument>> getByDocumentId(
+ @NonNull GetByDocumentIdRequest request);
/**
* Retrieves documents from the open {@link AppSearchSessionShim} that match a given query
@@ -162,7 +167,7 @@ public interface AppSearchSessionShim extends Closeable {
SearchResultsShim search(@NonNull String queryExpression, @NonNull SearchSpec searchSpec);
/**
- * Reports usage of a particular document by URI and namespace.
+ * Reports usage of a particular document by namespace and ID.
*
* <p>A usage report represents an event in which a user interacted with or viewed a document.
*
@@ -181,25 +186,26 @@ public interface AppSearchSessionShim extends Closeable {
ListenableFuture<Void> reportUsage(@NonNull ReportUsageRequest request);
/**
- * Removes {@link GenericDocument} objects by URIs and namespace from the {@link
+ * Removes {@link GenericDocument} objects by document IDs in a namespace from the {@link
* AppSearchSessionShim} database.
*
- * <p>Removed documents will no longer be surfaced by {@link #search} or {@link #getByUri}
- * calls.
+ * <p>Removed documents will no longer be surfaced by {@link #search} or {@link
+ * #getByDocumentId} calls.
*
* <p>Once the database crosses the document count or byte usage threshold, removed documents
* will be deleted from disk.
*
- * @param request {@link RemoveByUriRequest} with URIs and namespace to remove from the index.
+ * @param request {@link RemoveByDocumentIdRequest} with IDs in a namespace to remove from the
+ * index.
* @return a {@link ListenableFuture} which resolves to an {@link AppSearchBatchResult}. The
- * keys of the {@link AppSearchBatchResult} represent the input URIs from the {@link
- * RemoveByUriRequest} object. The values are either {@code null} on success, or a failed
- * {@link AppSearchResult} otherwise. URIs that are not found will return a failed {@link
- * AppSearchResult} with a result code of {@link AppSearchResult#RESULT_NOT_FOUND}.
+ * keys of the {@link AppSearchBatchResult} represent the input IDs from the {@link
+ * RemoveByDocumentIdRequest} object. The values are either {@code null} on success, or a
+ * failed {@link AppSearchResult} otherwise. IDs that are not found will return a failed
+ * {@link AppSearchResult} with a result code of {@link AppSearchResult#RESULT_NOT_FOUND}.
*/
@NonNull
ListenableFuture<AppSearchBatchResult<String, Void>> remove(
- @NonNull RemoveByUriRequest request);
+ @NonNull RemoveByDocumentIdRequest request);
/**
* Removes {@link GenericDocument}s from the index by Query. Documents will be removed if they
diff --git a/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchTestUtils.java b/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchTestUtils.java
index fd4734cea65f..ec9a42eaa276 100644
--- a/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchTestUtils.java
+++ b/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchTestUtils.java
@@ -22,7 +22,7 @@ import static com.google.common.truth.Truth.assertWithMessage;
import android.app.appsearch.AppSearchBatchResult;
import android.app.appsearch.AppSearchSessionShim;
import android.app.appsearch.GenericDocument;
-import android.app.appsearch.GetByUriRequest;
+import android.app.appsearch.GetByDocumentIdRequest;
import android.app.appsearch.SearchResult;
import android.app.appsearch.SearchResultsShim;
@@ -43,30 +43,30 @@ public class AppSearchTestUtils {
}
public static List<GenericDocument> doGet(
- AppSearchSessionShim session, String namespace, String... uris) throws Exception {
+ AppSearchSessionShim session, String namespace, String... ids) throws Exception {
AppSearchBatchResult<String, GenericDocument> result =
checkIsBatchResultSuccess(
- session.getByUri(
- new GetByUriRequest.Builder(namespace).addUris(uris).build()));
- assertThat(result.getSuccesses()).hasSize(uris.length);
+ session.getByDocumentId(
+ new GetByDocumentIdRequest.Builder(namespace).addIds(ids).build()));
+ assertThat(result.getSuccesses()).hasSize(ids.length);
assertThat(result.getFailures()).isEmpty();
- List<GenericDocument> list = new ArrayList<>(uris.length);
- for (String uri : uris) {
- list.add(result.getSuccesses().get(uri));
+ List<GenericDocument> list = new ArrayList<>(ids.length);
+ for (String id : ids) {
+ list.add(result.getSuccesses().get(id));
}
return list;
}
- public static List<GenericDocument> doGet(AppSearchSessionShim session, GetByUriRequest request)
- throws Exception {
+ public static List<GenericDocument> doGet(
+ AppSearchSessionShim session, GetByDocumentIdRequest request) throws Exception {
AppSearchBatchResult<String, GenericDocument> result =
- checkIsBatchResultSuccess(session.getByUri(request));
- Set<String> uris = request.getUris();
- assertThat(result.getSuccesses()).hasSize(uris.size());
+ checkIsBatchResultSuccess(session.getByDocumentId(request));
+ Set<String> ids = request.getIds();
+ assertThat(result.getSuccesses()).hasSize(ids.size());
assertThat(result.getFailures()).isEmpty();
- List<GenericDocument> list = new ArrayList<>(uris.size());
- for (String uri : uris) {
- list.add(result.getSuccesses().get(uri));
+ List<GenericDocument> list = new ArrayList<>(ids.size());
+ for (String id : ids) {
+ list.add(result.getSuccesses().get(id));
}
return list;
}
diff --git a/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/GlobalSearchSessionShim.java b/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/GlobalSearchSessionShim.java
index f39916ee1510..892f84e5bdb8 100644
--- a/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/GlobalSearchSessionShim.java
+++ b/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/GlobalSearchSessionShim.java
@@ -23,9 +23,12 @@ import com.google.common.util.concurrent.ListenableFuture;
import java.io.Closeable;
/**
- * This class provides global access to the centralized AppSearch index maintained by the system.
+ * Provides a connection to all AppSearch databases the querying application has been granted access
+ * to.
*
- * <p>Apps can retrieve indexed documents through the {@link #search} API.
+ * <p>All implementations of this interface must be thread safe.
+ *
+ * @see AppSearchSessionShim
*/
public interface GlobalSearchSessionShim extends Closeable {
/**
diff --git a/core/java/android/content/pm/AppSearchPerson.java b/core/java/android/content/pm/AppSearchPerson.java
index 9283e5fd3cbd..98d150b6ffdd 100644
--- a/core/java/android/content/pm/AppSearchPerson.java
+++ b/core/java/android/content/pm/AppSearchPerson.java
@@ -91,7 +91,7 @@ public class AppSearchPerson extends GenericDocument {
String uri;
try {
uri = UriCodec.decode(
- getUri(), false /* convertPlus */, StandardCharsets.UTF_8,
+ getId(), false /* convertPlus */, StandardCharsets.UTF_8,
true /* throwOnFailure */);
} catch (IllegalArgumentException e) {
uri = null;
diff --git a/core/java/android/content/pm/AppSearchShortcutInfo.java b/core/java/android/content/pm/AppSearchShortcutInfo.java
index eb50924579f6..afaecec7a29a 100644
--- a/core/java/android/content/pm/AppSearchShortcutInfo.java
+++ b/core/java/android/content/pm/AppSearchShortcutInfo.java
@@ -153,8 +153,8 @@ public class AppSearchShortcutInfo extends GenericDocument {
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
.build()
- ).addProperty(new AppSearchSchema.DocumentPropertyConfig.Builder(KEY_PERSON)
- .setSchemaType(AppSearchPerson.SCHEMA_TYPE)
+ ).addProperty(new AppSearchSchema.DocumentPropertyConfig.Builder(
+ KEY_PERSON, AppSearchPerson.SCHEMA_TYPE)
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
.build()
@@ -419,7 +419,7 @@ public class AppSearchShortcutInfo extends GenericDocument {
final String bitmapPath = getPropertyString(KEY_BITMAP_PATH);
final int disabledReason = Integer.parseInt(getPropertyString(KEY_DISABLED_REASON));
final ShortcutInfo si = new ShortcutInfo(
- userId, getUri(), packageName, activity, icon, shortLabel, shortLabelResId,
+ userId, getId(), packageName, activity, icon, shortLabel, shortLabelResId,
shortLabelResName, longLabel, longLabelResId, longLabelResName, disabledMessage,
disabledMessageResId, disabledMessageResName, categoriesSet, intents, rank, extras,
getCreationTimestampMillis(), flags, iconResId, iconResName, bitmapPath, iconUri,
diff --git a/core/tests/coretests/src/android/app/appsearch/external/app/AppSearchEmailTest.java b/core/tests/coretests/src/android/app/appsearch/external/app/AppSearchEmailTest.java
index ed53d5f39a39..3989ec7c95d6 100644
--- a/core/tests/coretests/src/android/app/appsearch/external/app/AppSearchEmailTest.java
+++ b/core/tests/coretests/src/android/app/appsearch/external/app/AppSearchEmailTest.java
@@ -25,7 +25,7 @@ public class AppSearchEmailTest {
@Test
public void testBuildEmailAndGetValue() {
AppSearchEmail email =
- new AppSearchEmail.Builder("namespace", "uri")
+ new AppSearchEmail.Builder("namespace", "id")
.setFrom("FakeFromAddress")
.setCc("CC1", "CC2")
// Score and Property are mixed into the middle to make sure
@@ -38,7 +38,7 @@ public class AppSearchEmailTest {
.build();
assertThat(email.getNamespace()).isEqualTo("namespace");
- assertThat(email.getUri()).isEqualTo("uri");
+ assertThat(email.getId()).isEqualTo("id");
assertThat(email.getFrom()).isEqualTo("FakeFromAddress");
assertThat(email.getTo()).isNull();
assertThat(email.getCc()).asList().containsExactly("CC1", "CC2");
diff --git a/core/tests/coretests/src/android/app/appsearch/external/app/GenericDocumentTest.java b/core/tests/coretests/src/android/app/appsearch/external/app/GenericDocumentTest.java
index b884ddcd1420..6884f13d4cc9 100644
--- a/core/tests/coretests/src/android/app/appsearch/external/app/GenericDocumentTest.java
+++ b/core/tests/coretests/src/android/app/appsearch/external/app/GenericDocumentTest.java
@@ -27,13 +27,13 @@ public class GenericDocumentTest {
@Test
public void testRecreateFromParcel() {
GenericDocument inDoc =
- new GenericDocument.Builder<>("namespace", "uri1", "schema1")
+ new GenericDocument.Builder<>("namespace", "id1", "schema1")
.setScore(42)
.setPropertyString("propString", "Hello")
.setPropertyBytes("propBytes", new byte[][] {{1, 2}})
.setPropertyDocument(
"propDocument",
- new GenericDocument.Builder<>("namespace", "uri2", "schema2")
+ new GenericDocument.Builder<>("namespace", "id2", "schema2")
.setPropertyString("propString", "Goodbye")
.setPropertyBytes("propBytes", new byte[][] {{3, 4}})
.build())
diff --git a/core/tests/coretests/src/android/app/appsearch/external/app/PutDocumentsRequestTest.java b/core/tests/coretests/src/android/app/appsearch/external/app/PutDocumentsRequestTest.java
index 76372141ca04..a1f7986f62df 100644
--- a/core/tests/coretests/src/android/app/appsearch/external/app/PutDocumentsRequestTest.java
+++ b/core/tests/coretests/src/android/app/appsearch/external/app/PutDocumentsRequestTest.java
@@ -36,7 +36,7 @@ public class PutDocumentsRequestTest {
PutDocumentsRequest request =
new PutDocumentsRequest.Builder().addGenericDocuments(emails).build();
- assertThat(request.getGenericDocuments().get(0).getUri()).isEqualTo("test1");
- assertThat(request.getGenericDocuments().get(1).getUri()).isEqualTo("test2");
+ assertThat(request.getGenericDocuments().get(0).getId()).isEqualTo("test1");
+ assertThat(request.getGenericDocuments().get(1).getId()).isEqualTo("test2");
}
}
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index ada65860018a..b690e6c0b8fa 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -23,10 +23,10 @@ import android.app.appsearch.AppSearchManager;
import android.app.appsearch.AppSearchResult;
import android.app.appsearch.AppSearchSession;
import android.app.appsearch.GenericDocument;
-import android.app.appsearch.GetByUriRequest;
+import android.app.appsearch.GetByDocumentIdRequest;
import android.app.appsearch.PackageIdentifier;
import android.app.appsearch.PutDocumentsRequest;
-import android.app.appsearch.RemoveByUriRequest;
+import android.app.appsearch.RemoveByDocumentIdRequest;
import android.app.appsearch.ReportUsageRequest;
import android.app.appsearch.SearchResult;
import android.app.appsearch.SearchResults;
@@ -449,8 +449,8 @@ class ShortcutPackage extends ShortcutPackageItem {
session -> {
final AndroidFuture<Boolean> future = new AndroidFuture<>();
session.reportUsage(
- new ReportUsageRequest.Builder(getPackageName())
- .setUri(newShortcut.getId()).build(),
+ new ReportUsageRequest.Builder(
+ getPackageName(), newShortcut.getId()).build(),
mShortcutUser.mExecutor,
result -> future.complete(result.isSuccess()));
return future;
@@ -2377,7 +2377,8 @@ class ShortcutPackage extends ShortcutPackageItem {
}
awaitInAppSearch("Removing shortcut with id=" + id, session -> {
final AndroidFuture<Boolean> future = new AndroidFuture<>();
- session.remove(new RemoveByUriRequest.Builder(getPackageName()).addUris(id).build(),
+ session.remove(
+ new RemoveByDocumentIdRequest.Builder(getPackageName()).addIds(id).build(),
mShortcutUser.mExecutor, result -> {
if (!result.isSuccess()) {
final Map<String, AppSearchResult<Void>> failures =
@@ -2420,8 +2421,9 @@ class ShortcutPackage extends ShortcutPackageItem {
}
return awaitInAppSearch("Getting shortcut by id", session -> {
final AndroidFuture<List<ShortcutInfo>> future = new AndroidFuture<>();
- session.getByUri(
- new GetByUriRequest.Builder(getPackageName()).addUris(shortcutIds).build(),
+ session.getByDocumentId(
+ new GetByDocumentIdRequest.Builder(getPackageName())
+ .addIds(shortcutIds).build(),
mShortcutUser.mExecutor,
results -> {
final List<ShortcutInfo> ret = new ArrayList<>(1);
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java
index 380d9be5ae57..9a7cf803763d 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java
@@ -307,13 +307,13 @@ public class AppSearchImplTest {
public void testAddDocumentTypePrefix() {
DocumentProto insideDocument =
DocumentProto.newBuilder()
- .setUri("inside-uri")
+ .setUri("inside-id")
.setSchema("type")
.setNamespace("namespace")
.build();
DocumentProto documentProto =
DocumentProto.newBuilder()
- .setUri("uri")
+ .setUri("id")
.setSchema("type")
.setNamespace("namespace")
.addProperties(PropertyProto.newBuilder().addDocumentValues(insideDocument))
@@ -321,13 +321,13 @@ public class AppSearchImplTest {
DocumentProto expectedInsideDocument =
DocumentProto.newBuilder()
- .setUri("inside-uri")
+ .setUri("inside-id")
.setSchema("package$databaseName/type")
.setNamespace("package$databaseName/namespace")
.build();
DocumentProto expectedDocumentProto =
DocumentProto.newBuilder()
- .setUri("uri")
+ .setUri("id")
.setSchema("package$databaseName/type")
.setNamespace("package$databaseName/namespace")
.addProperties(
@@ -344,13 +344,13 @@ public class AppSearchImplTest {
public void testRemoveDocumentTypePrefixes() throws Exception {
DocumentProto insideDocument =
DocumentProto.newBuilder()
- .setUri("inside-uri")
+ .setUri("inside-id")
.setSchema("package$databaseName/type")
.setNamespace("package$databaseName/namespace")
.build();
DocumentProto documentProto =
DocumentProto.newBuilder()
- .setUri("uri")
+ .setUri("id")
.setSchema("package$databaseName/type")
.setNamespace("package$databaseName/namespace")
.addProperties(PropertyProto.newBuilder().addDocumentValues(insideDocument))
@@ -358,14 +358,14 @@ public class AppSearchImplTest {
DocumentProto expectedInsideDocument =
DocumentProto.newBuilder()
- .setUri("inside-uri")
+ .setUri("inside-id")
.setSchema("type")
.setNamespace("namespace")
.build();
DocumentProto expectedDocumentProto =
DocumentProto.newBuilder()
- .setUri("uri")
+ .setUri("id")
.setSchema("type")
.setNamespace("namespace")
.addProperties(
@@ -383,7 +383,7 @@ public class AppSearchImplTest {
// Set two different database names in the document, which should never happen
DocumentProto documentProto =
DocumentProto.newBuilder()
- .setUri("uri")
+ .setUri("id")
.setSchema("prefix1/type")
.setNamespace("prefix2/namespace")
.build();
@@ -401,13 +401,13 @@ public class AppSearchImplTest {
// happen.
DocumentProto insideDocument =
DocumentProto.newBuilder()
- .setUri("inside-uri")
+ .setUri("inside-id")
.setSchema("prefix1/type")
.setNamespace("prefix1/namespace")
.build();
DocumentProto documentProto =
DocumentProto.newBuilder()
- .setUri("uri")
+ .setUri("id")
.setSchema("prefix2/type")
.setNamespace("prefix2/namespace")
.addProperties(PropertyProto.newBuilder().addDocumentValues(insideDocument))
@@ -441,7 +441,7 @@ public class AppSearchImplTest {
+ AppSearchImpl.CHECK_OPTIMIZE_INTERVAL;
i++) {
GenericDocument document =
- new GenericDocument.Builder<>("namespace", "uri" + i, "type").build();
+ new GenericDocument.Builder<>("namespace", "id" + i, "type").build();
mAppSearchImpl.putDocument("package", "database", document, /*logger=*/ null);
}
@@ -452,7 +452,7 @@ public class AppSearchImplTest {
// delete 999 documents, we will reach the threshold to trigger optimize() in next
// deletion.
for (int i = 0; i < AppSearchImpl.OPTIMIZE_THRESHOLD_DOC_COUNT - 1; i++) {
- mAppSearchImpl.remove("package", "database", "namespace", "uri" + i);
+ mAppSearchImpl.remove("package", "database", "namespace", "id" + i);
}
// Updates the check for optimize counter, checkForOptimize() will be triggered since
@@ -472,7 +472,7 @@ public class AppSearchImplTest {
< AppSearchImpl.OPTIMIZE_THRESHOLD_DOC_COUNT
+ AppSearchImpl.CHECK_OPTIMIZE_INTERVAL;
i++) {
- mAppSearchImpl.remove("package", "database", "namespace", "uri" + i);
+ mAppSearchImpl.remove("package", "database", "namespace", "id" + i);
}
// updates the check for optimize counter, will reach both CHECK_OPTIMIZE_INTERVAL and
// OPTIMIZE_THRESHOLD_DOC_COUNT this time and trigger a optimize().
@@ -501,8 +501,7 @@ public class AppSearchImplTest {
/*version=*/ 0);
// Insert document
- GenericDocument document =
- new GenericDocument.Builder<>("namespace", "uri", "type").build();
+ GenericDocument document = new GenericDocument.Builder<>("namespace", "id", "type").build();
mAppSearchImpl.putDocument("package", "database", document, /*logger=*/ null);
// Rewrite SearchSpec
@@ -544,11 +543,11 @@ public class AppSearchImplTest {
// Insert documents
GenericDocument document1 =
- new GenericDocument.Builder<>("namespace", "uri", "typeA").build();
+ new GenericDocument.Builder<>("namespace", "id", "typeA").build();
mAppSearchImpl.putDocument("package", "database1", document1, /*logger=*/ null);
GenericDocument document2 =
- new GenericDocument.Builder<>("namespace", "uri", "typeB").build();
+ new GenericDocument.Builder<>("namespace", "id", "typeB").build();
mAppSearchImpl.putDocument("package", "database2", document2, /*logger=*/ null);
// Rewrite SearchSpec
@@ -587,8 +586,7 @@ public class AppSearchImplTest {
/*version=*/ 0);
// Insert document
- GenericDocument document =
- new GenericDocument.Builder<>("namespace", "uri", "type").build();
+ GenericDocument document = new GenericDocument.Builder<>("namespace", "id", "type").build();
mAppSearchImpl.putDocument("package", "database", document, /*logger=*/ null);
// If 'allowedPrefixedSchemas' is empty, this returns false since there's nothing to
@@ -642,7 +640,7 @@ public class AppSearchImplTest {
// Insert package1 document
GenericDocument document =
- new GenericDocument.Builder<>("namespace", "uri", "schema1").build();
+ new GenericDocument.Builder<>("namespace", "id", "schema1").build();
mAppSearchImpl.putDocument("package1", "database1", document, /*logger=*/ null);
// No query filters specified, package2 shouldn't be able to query for package1's documents.
@@ -653,7 +651,7 @@ public class AppSearchImplTest {
assertThat(searchResultPage.getResults()).isEmpty();
// Insert package2 document
- document = new GenericDocument.Builder<>("namespace", "uri", "schema2").build();
+ document = new GenericDocument.Builder<>("namespace", "id", "schema2").build();
mAppSearchImpl.putDocument("package2", "database2", document, /*logger=*/ null);
// No query filters specified. package2 should only get its own documents back.
@@ -694,7 +692,7 @@ public class AppSearchImplTest {
// Insert package1 document
GenericDocument document =
- new GenericDocument.Builder<>("namespace", "uri", "schema1").build();
+ new GenericDocument.Builder<>("namespace", "id", "schema1").build();
mAppSearchImpl.putDocument("package1", "database1", document, /*logger=*/ null);
// "package1" filter specified, but package2 shouldn't be able to query for package1's
@@ -709,7 +707,7 @@ public class AppSearchImplTest {
assertThat(searchResultPage.getResults()).isEmpty();
// Insert package2 document
- document = new GenericDocument.Builder<>("namespace", "uri", "schema2").build();
+ document = new GenericDocument.Builder<>("namespace", "id", "schema2").build();
mAppSearchImpl.putDocument("package2", "database2", document, /*logger=*/ null);
// "package2" filter specified, package2 should only get its own documents back.
@@ -1028,7 +1026,7 @@ public class AppSearchImplTest {
// Insert package document
GenericDocument document =
- new GenericDocument.Builder<>("namespace", "uri", "schema").build();
+ new GenericDocument.Builder<>("namespace", "id", "schema").build();
mAppSearchImpl.putDocument("package", "database", document, /*logger=*/ null);
// Verify the document is indexed.
@@ -1135,14 +1133,14 @@ public class AppSearchImplTest {
+ PrefixUtil.PACKAGE_DELIMITER
+ "databaseName"
+ PrefixUtil.DATABASE_DELIMITER;
- final String uri = "uri";
+ final String id = "id";
final String namespace = prefix + "namespace";
final String schemaType = prefix + "schema";
// Building the SearchResult received from query.
DocumentProto documentProto =
DocumentProto.newBuilder()
- .setUri(uri)
+ .setUri(id)
.setNamespace(namespace)
.setSchema(schemaType)
.build();
@@ -1185,32 +1183,32 @@ public class AppSearchImplTest {
// Insert two docs
GenericDocument document1 =
- new GenericDocument.Builder<>("namespace", "uri1", "type").build();
+ new GenericDocument.Builder<>("namespace", "id1", "type").build();
GenericDocument document2 =
- new GenericDocument.Builder<>("namespace", "uri2", "type").build();
+ new GenericDocument.Builder<>("namespace", "id2", "type").build();
mAppSearchImpl.putDocument("package", "database", document1, /*logger=*/ null);
mAppSearchImpl.putDocument("package", "database", document2, /*logger=*/ null);
- // Report some usages. uri1 has 2 app and 1 system usage, uri2 has 1 app and 2 system usage.
+ // Report some usages. id1 has 2 app and 1 system usage, id2 has 1 app and 2 system usage.
mAppSearchImpl.reportUsage(
"package",
"database",
"namespace",
- "uri1",
+ "id1",
/*usageTimestampMillis=*/ 10,
/*systemUsage=*/ false);
mAppSearchImpl.reportUsage(
"package",
"database",
"namespace",
- "uri1",
+ "id1",
/*usageTimestampMillis=*/ 20,
/*systemUsage=*/ false);
mAppSearchImpl.reportUsage(
"package",
"database",
"namespace",
- "uri1",
+ "id1",
/*usageTimestampMillis=*/ 1000,
/*systemUsage=*/ true);
@@ -1218,25 +1216,25 @@ public class AppSearchImplTest {
"package",
"database",
"namespace",
- "uri2",
+ "id2",
/*usageTimestampMillis=*/ 100,
/*systemUsage=*/ false);
mAppSearchImpl.reportUsage(
"package",
"database",
"namespace",
- "uri2",
+ "id2",
/*usageTimestampMillis=*/ 200,
/*systemUsage=*/ true);
mAppSearchImpl.reportUsage(
"package",
"database",
"namespace",
- "uri2",
+ "id2",
/*usageTimestampMillis=*/ 150,
/*systemUsage=*/ true);
- // Sort by app usage count: uri1 should win
+ // Sort by app usage count: id1 should win
List<SearchResult> page =
mAppSearchImpl
.query(
@@ -1249,10 +1247,10 @@ public class AppSearchImplTest {
.build())
.getResults();
assertThat(page).hasSize(2);
- assertThat(page.get(0).getGenericDocument().getUri()).isEqualTo("uri1");
- assertThat(page.get(1).getGenericDocument().getUri()).isEqualTo("uri2");
+ assertThat(page.get(0).getGenericDocument().getId()).isEqualTo("id1");
+ assertThat(page.get(1).getGenericDocument().getId()).isEqualTo("id2");
- // Sort by app usage timestamp: uri2 should win
+ // Sort by app usage timestamp: id2 should win
page =
mAppSearchImpl
.query(
@@ -1267,10 +1265,10 @@ public class AppSearchImplTest {
.build())
.getResults();
assertThat(page).hasSize(2);
- assertThat(page.get(0).getGenericDocument().getUri()).isEqualTo("uri2");
- assertThat(page.get(1).getGenericDocument().getUri()).isEqualTo("uri1");
+ assertThat(page.get(0).getGenericDocument().getId()).isEqualTo("id2");
+ assertThat(page.get(1).getGenericDocument().getId()).isEqualTo("id1");
- // Sort by system usage count: uri2 should win
+ // Sort by system usage count: id2 should win
page =
mAppSearchImpl
.query(
@@ -1284,10 +1282,10 @@ public class AppSearchImplTest {
.build())
.getResults();
assertThat(page).hasSize(2);
- assertThat(page.get(0).getGenericDocument().getUri()).isEqualTo("uri2");
- assertThat(page.get(1).getGenericDocument().getUri()).isEqualTo("uri1");
+ assertThat(page.get(0).getGenericDocument().getId()).isEqualTo("id2");
+ assertThat(page.get(1).getGenericDocument().getId()).isEqualTo("id1");
- // Sort by system usage timestamp: uri1 should win
+ // Sort by system usage timestamp: id1 should win
page =
mAppSearchImpl
.query(
@@ -1302,8 +1300,8 @@ public class AppSearchImplTest {
.build())
.getResults();
assertThat(page).hasSize(2);
- assertThat(page.get(0).getGenericDocument().getUri()).isEqualTo("uri1");
- assertThat(page.get(1).getGenericDocument().getUri()).isEqualTo("uri2");
+ assertThat(page.get(0).getGenericDocument().getId()).isEqualTo("id1");
+ assertThat(page.get(1).getGenericDocument().getId()).isEqualTo("id2");
}
@Test
@@ -1353,7 +1351,7 @@ public class AppSearchImplTest {
// Insert document for "package1"
GenericDocument document =
- new GenericDocument.Builder<>("namespace", "uri1", "type").build();
+ new GenericDocument.Builder<>("namespace", "id1", "type").build();
mAppSearchImpl.putDocument("package1", "database", document, /*logger=*/ null);
// Insert schema for "package2"
@@ -1367,9 +1365,9 @@ public class AppSearchImplTest {
/*version=*/ 0);
// Insert two documents for "package2"
- document = new GenericDocument.Builder<>("namespace", "uri1", "type").build();
+ document = new GenericDocument.Builder<>("namespace", "id1", "type").build();
mAppSearchImpl.putDocument("package2", "database", document, /*logger=*/ null);
- document = new GenericDocument.Builder<>("namespace", "uri2", "type").build();
+ document = new GenericDocument.Builder<>("namespace", "id2", "type").build();
mAppSearchImpl.putDocument("package2", "database", document, /*logger=*/ null);
StorageInfo storageInfo = mAppSearchImpl.getStorageInfoForPackage("package1");
@@ -1467,13 +1465,13 @@ public class AppSearchImplTest {
// Add a document for "package1", "database1"
GenericDocument document =
- new GenericDocument.Builder<>("namespace1", "uri1", "type").build();
+ new GenericDocument.Builder<>("namespace1", "id1", "type").build();
mAppSearchImpl.putDocument("package1", "database1", document, /*logger=*/ null);
// Add two documents for "package1", "database2"
- document = new GenericDocument.Builder<>("namespace1", "uri1", "type").build();
+ document = new GenericDocument.Builder<>("namespace1", "id1", "type").build();
mAppSearchImpl.putDocument("package1", "database2", document, /*logger=*/ null);
- document = new GenericDocument.Builder<>("namespace1", "uri2", "type").build();
+ document = new GenericDocument.Builder<>("namespace1", "id2", "type").build();
mAppSearchImpl.putDocument("package1", "database2", document, /*logger=*/ null);
StorageInfo storageInfo = mAppSearchImpl.getStorageInfoForDatabase("package1", "database1");
@@ -1543,7 +1541,7 @@ public class AppSearchImplTest {
appSearchImpl.putDocument(
"package",
"database",
- new GenericDocument.Builder<>("namespace", "uri", "type").build(),
+ new GenericDocument.Builder<>("namespace", "id", "type").build(),
/*logger=*/ null);
});
@@ -1551,7 +1549,7 @@ public class AppSearchImplTest {
IllegalStateException.class,
() -> {
appSearchImpl.getDocument(
- "package", "database", "namespace", "uri", Collections.emptyMap());
+ "package", "database", "namespace", "id", Collections.emptyMap());
});
expectThrows(
@@ -1597,7 +1595,7 @@ public class AppSearchImplTest {
"package",
"database",
"namespace",
- "uri",
+ "id",
/*usageTimestampMillis=*/ 1000L,
/*systemUsage=*/ false);
});
@@ -1605,7 +1603,7 @@ public class AppSearchImplTest {
expectThrows(
IllegalStateException.class,
() -> {
- appSearchImpl.remove("package", "database", "namespace", "uri");
+ appSearchImpl.remove("package", "database", "namespace", "id");
});
expectThrows(
@@ -1664,13 +1662,13 @@ public class AppSearchImplTest {
// Add a document and persist it.
GenericDocument document =
- new GenericDocument.Builder<>("namespace1", "uri1", "type").build();
+ new GenericDocument.Builder<>("namespace1", "id1", "type").build();
appSearchImpl.putDocument("package", "database", document, /*logger=*/ null);
appSearchImpl.persistToDisk(PersistType.Code.LITE);
GenericDocument getResult =
appSearchImpl.getDocument(
- "package", "database", "namespace1", "uri1", Collections.emptyMap());
+ "package", "database", "namespace1", "id1", Collections.emptyMap());
assertThat(getResult).isEqualTo(document);
// That document should be visible even from another instance.
@@ -1682,7 +1680,7 @@ public class AppSearchImplTest {
/*globalQuerierPackage=*/ "");
getResult =
appSearchImpl2.getDocument(
- "package", "database", "namespace1", "uri1", Collections.emptyMap());
+ "package", "database", "namespace1", "id1", Collections.emptyMap());
assertThat(getResult).isEqualTo(document);
}
@@ -1711,24 +1709,24 @@ public class AppSearchImplTest {
// Add two documents and persist them.
GenericDocument document1 =
- new GenericDocument.Builder<>("namespace1", "uri1", "type").build();
+ new GenericDocument.Builder<>("namespace1", "id1", "type").build();
appSearchImpl.putDocument("package", "database", document1, /*logger=*/ null);
GenericDocument document2 =
- new GenericDocument.Builder<>("namespace1", "uri2", "type").build();
+ new GenericDocument.Builder<>("namespace1", "id2", "type").build();
appSearchImpl.putDocument("package", "database", document2, /*logger=*/ null);
appSearchImpl.persistToDisk(PersistType.Code.LITE);
GenericDocument getResult =
appSearchImpl.getDocument(
- "package", "database", "namespace1", "uri1", Collections.emptyMap());
+ "package", "database", "namespace1", "id1", Collections.emptyMap());
assertThat(getResult).isEqualTo(document1);
getResult =
appSearchImpl.getDocument(
- "package", "database", "namespace1", "uri2", Collections.emptyMap());
+ "package", "database", "namespace1", "id2", Collections.emptyMap());
assertThat(getResult).isEqualTo(document2);
// Delete the first document
- appSearchImpl.remove("package", "database", "namespace1", "uri1");
+ appSearchImpl.remove("package", "database", "namespace1", "id1");
appSearchImpl.persistToDisk(PersistType.Code.LITE);
expectThrows(
AppSearchException.class,
@@ -1737,11 +1735,11 @@ public class AppSearchImplTest {
"package",
"database",
"namespace1",
- "uri1",
+ "id1",
Collections.emptyMap()));
getResult =
appSearchImpl.getDocument(
- "package", "database", "namespace1", "uri2", Collections.emptyMap());
+ "package", "database", "namespace1", "id2", Collections.emptyMap());
assertThat(getResult).isEqualTo(document2);
// Only the second document should be retrievable from another instance.
@@ -1758,11 +1756,11 @@ public class AppSearchImplTest {
"package",
"database",
"namespace1",
- "uri1",
+ "id1",
Collections.emptyMap()));
getResult =
appSearchImpl2.getDocument(
- "package", "database", "namespace1", "uri2", Collections.emptyMap());
+ "package", "database", "namespace1", "id2", Collections.emptyMap());
assertThat(getResult).isEqualTo(document2);
}
@@ -1791,20 +1789,20 @@ public class AppSearchImplTest {
// Add two documents and persist them.
GenericDocument document1 =
- new GenericDocument.Builder<>("namespace1", "uri1", "type").build();
+ new GenericDocument.Builder<>("namespace1", "id1", "type").build();
appSearchImpl.putDocument("package", "database", document1, /*logger=*/ null);
GenericDocument document2 =
- new GenericDocument.Builder<>("namespace2", "uri2", "type").build();
+ new GenericDocument.Builder<>("namespace2", "id2", "type").build();
appSearchImpl.putDocument("package", "database", document2, /*logger=*/ null);
appSearchImpl.persistToDisk(PersistType.Code.LITE);
GenericDocument getResult =
appSearchImpl.getDocument(
- "package", "database", "namespace1", "uri1", Collections.emptyMap());
+ "package", "database", "namespace1", "id1", Collections.emptyMap());
assertThat(getResult).isEqualTo(document1);
getResult =
appSearchImpl.getDocument(
- "package", "database", "namespace2", "uri2", Collections.emptyMap());
+ "package", "database", "namespace2", "id2", Collections.emptyMap());
assertThat(getResult).isEqualTo(document2);
// Delete the first document
@@ -1824,11 +1822,11 @@ public class AppSearchImplTest {
"package",
"database",
"namespace1",
- "uri1",
+ "id1",
Collections.emptyMap()));
getResult =
appSearchImpl.getDocument(
- "package", "database", "namespace2", "uri2", Collections.emptyMap());
+ "package", "database", "namespace2", "id2", Collections.emptyMap());
assertThat(getResult).isEqualTo(document2);
// Only the second document should be retrievable from another instance.
@@ -1845,11 +1843,11 @@ public class AppSearchImplTest {
"package",
"database",
"namespace1",
- "uri1",
+ "id1",
Collections.emptyMap()));
getResult =
appSearchImpl2.getDocument(
- "package", "database", "namespace2", "uri2", Collections.emptyMap());
+ "package", "database", "namespace2", "id2", Collections.emptyMap());
assertThat(getResult).isEqualTo(document2);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchLoggerTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchLoggerTest.java
index 673b7ee24eff..1194e76ee2b5 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchLoggerTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchLoggerTest.java
@@ -129,8 +129,7 @@ public class AppSearchLoggerTest {
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
- GenericDocument document =
- new GenericDocument.Builder<>("namespace", "uri", "type").build();
+ GenericDocument document = new GenericDocument.Builder<>("namespace", "id", "type").build();
mAppSearchImpl.putDocument(testPackageName, testDatabase, document, mLogger);
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverterTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverterTest.java
index 63f031722ede..ada49ff4b97a 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverterTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverterTest.java
@@ -64,7 +64,7 @@ public class GenericDocumentToProtoConverterTest {
public void testDocumentProtoConvert() {
GenericDocument document =
new GenericDocument.Builder<GenericDocument.Builder<?>>(
- "namespace", "uri1", SCHEMA_TYPE_1)
+ "namespace", "id1", SCHEMA_TYPE_1)
.setCreationTimestampMillis(5L)
.setScore(1)
.setTtlMillis(1L)
@@ -80,7 +80,7 @@ public class GenericDocumentToProtoConverterTest {
// Create the Document proto. Need to sort the property order by key.
DocumentProto.Builder documentProtoBuilder =
DocumentProto.newBuilder()
- .setUri("uri1")
+ .setUri("id1")
.setSchema(SCHEMA_TYPE_1)
.setCreationTimestampMs(5L)
.setScore(1)
@@ -140,7 +140,7 @@ public class GenericDocumentToProtoConverterTest {
String emptyStringPropertyName = "emptyStringProperty";
DocumentProto documentProto =
DocumentProto.newBuilder()
- .setUri("uri1")
+ .setUri("id1")
.setSchema(SCHEMA_TYPE_1)
.setCreationTimestampMs(5L)
.setNamespace("namespace")
@@ -167,7 +167,7 @@ public class GenericDocumentToProtoConverterTest {
GenericDocument expectedDocument =
new GenericDocument.Builder<GenericDocument.Builder<?>>(
- "namespace", "uri1", SCHEMA_TYPE_1)
+ "namespace", "id1", SCHEMA_TYPE_1)
.setCreationTimestampMillis(5L)
.setPropertyString(emptyStringPropertyName)
.build();
@@ -181,7 +181,7 @@ public class GenericDocumentToProtoConverterTest {
String documentPropertyName = "documentProperty";
DocumentProto nestedDocumentProto =
DocumentProto.newBuilder()
- .setUri("uri2")
+ .setUri("id2")
.setSchema(SCHEMA_TYPE_2)
.setCreationTimestampMs(5L)
.setNamespace("namespace")
@@ -190,7 +190,7 @@ public class GenericDocumentToProtoConverterTest {
.build();
DocumentProto documentProto =
DocumentProto.newBuilder()
- .setUri("uri1")
+ .setUri("id1")
.setSchema(SCHEMA_TYPE_1)
.setCreationTimestampMs(5L)
.setNamespace("namespace")
@@ -236,12 +236,12 @@ public class GenericDocumentToProtoConverterTest {
GenericDocument expectedDocument =
new GenericDocument.Builder<GenericDocument.Builder<?>>(
- "namespace", "uri1", SCHEMA_TYPE_1)
+ "namespace", "id1", SCHEMA_TYPE_1)
.setCreationTimestampMillis(5L)
.setPropertyDocument(
documentPropertyName,
new GenericDocument.Builder<GenericDocument.Builder<?>>(
- "namespace", "uri2", SCHEMA_TYPE_2)
+ "namespace", "id2", SCHEMA_TYPE_2)
.setCreationTimestampMillis(5L)
.setPropertyString(emptyStringPropertyName)
.build())
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SnippetTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SnippetTest.java
index 26fac492ccd2..d0ce31720fe3 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SnippetTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SnippetTest.java
@@ -54,22 +54,19 @@ public class SnippetTest {
"A commonly used fake word is foo.\n"
+ " Another nonsense word that’s used a lot\n"
+ " is bar.\n";
- final String uri = "uri1";
- final String searchWord = "foo";
+ final String id = "id1";
final String exactMatch = "foo";
final String window = "is foo";
// Building the SearchResult received from query.
- PropertyProto property =
- PropertyProto.newBuilder()
- .setName(propertyKeyString)
- .addStringValues(propertyValueString)
- .build();
DocumentProto documentProto =
DocumentProto.newBuilder()
- .setUri(uri)
+ .setUri(id)
.setSchema(SCHEMA_TYPE)
- .addProperties(property)
+ .addProperties(
+ PropertyProto.newBuilder()
+ .setName(propertyKeyString)
+ .addStringValues(propertyValueString))
.build();
SnippetProto snippetProto =
SnippetProto.newBuilder()
@@ -81,17 +78,15 @@ public class SnippetTest {
.setExactMatchPosition(29)
.setExactMatchBytes(3)
.setWindowPosition(26)
- .setWindowBytes(6)
- .build())
- .build())
- .build();
- SearchResultProto.ResultProto resultProto =
- SearchResultProto.ResultProto.newBuilder()
- .setDocument(documentProto)
- .setSnippet(snippetProto)
+ .setWindowBytes(6)))
.build();
SearchResultProto searchResultProto =
- SearchResultProto.newBuilder().addResults(resultProto).build();
+ SearchResultProto.newBuilder()
+ .addResults(
+ SearchResultProto.ResultProto.newBuilder()
+ .setDocument(documentProto)
+ .setSnippet(snippetProto))
+ .build();
// Making ResultReader and getting Snippet values.
SearchResultPage searchResultPage =
@@ -100,50 +95,45 @@ public class SnippetTest {
Collections.singletonList(PACKAGE_NAME),
Collections.singletonList(DATABASE_NAME),
SCHEMA_MAP);
- for (SearchResult result : searchResultPage.getResults()) {
- SearchResult.MatchInfo match = result.getMatches().get(0);
- assertThat(match.getPropertyPath()).isEqualTo(propertyKeyString);
- assertThat(match.getFullText()).isEqualTo(propertyValueString);
- assertThat(match.getExactMatch()).isEqualTo(exactMatch);
- assertThat(match.getExactMatchRange())
- .isEqualTo(new SearchResult.MatchRange(/*lower=*/ 29, /*upper=*/ 32));
- assertThat(match.getFullText()).isEqualTo(propertyValueString);
- assertThat(match.getSnippetRange())
- .isEqualTo(new SearchResult.MatchRange(/*lower=*/ 26, /*upper=*/ 32));
- assertThat(match.getSnippet()).isEqualTo(window);
- }
+ assertThat(searchResultPage.getResults()).hasSize(1);
+ SearchResult.MatchInfo match = searchResultPage.getResults().get(0).getMatches().get(0);
+ assertThat(match.getPropertyPath()).isEqualTo(propertyKeyString);
+ assertThat(match.getFullText()).isEqualTo(propertyValueString);
+ assertThat(match.getExactMatch()).isEqualTo(exactMatch);
+ assertThat(match.getExactMatchRange())
+ .isEqualTo(new SearchResult.MatchRange(/*lower=*/ 29, /*upper=*/ 32));
+ assertThat(match.getFullText()).isEqualTo(propertyValueString);
+ assertThat(match.getSnippetRange())
+ .isEqualTo(new SearchResult.MatchRange(/*lower=*/ 26, /*upper=*/ 32));
+ assertThat(match.getSnippet()).isEqualTo(window);
}
// TODO(tytytyww): Add tests for Double and Long Snippets.
@Test
- public void testNoSnippets() throws Exception {
-
+ public void testNoSnippets() {
final String propertyKeyString = "content";
final String propertyValueString =
"A commonly used fake word is foo.\n"
+ " Another nonsense word that’s used a lot\n"
+ " is bar.\n";
- final String uri = "uri1";
- final String searchWord = "foo";
- final String exactMatch = "foo";
- final String window = "is foo";
+ final String id = "id1";
// Building the SearchResult received from query.
- PropertyProto property =
- PropertyProto.newBuilder()
- .setName(propertyKeyString)
- .addStringValues(propertyValueString)
- .build();
DocumentProto documentProto =
DocumentProto.newBuilder()
- .setUri(uri)
+ .setUri(id)
.setSchema(SCHEMA_TYPE)
- .addProperties(property)
+ .addProperties(
+ PropertyProto.newBuilder()
+ .setName(propertyKeyString)
+ .addStringValues(propertyValueString))
.build();
- SearchResultProto.ResultProto resultProto =
- SearchResultProto.ResultProto.newBuilder().setDocument(documentProto).build();
SearchResultProto searchResultProto =
- SearchResultProto.newBuilder().addResults(resultProto).build();
+ SearchResultProto.newBuilder()
+ .addResults(
+ SearchResultProto.ResultProto.newBuilder()
+ .setDocument(documentProto))
+ .build();
SearchResultPage searchResultPage =
SearchResultToProtoConverter.toSearchResultPage(
@@ -151,65 +141,137 @@ public class SnippetTest {
Collections.singletonList(PACKAGE_NAME),
Collections.singletonList(DATABASE_NAME),
SCHEMA_MAP);
- for (SearchResult result : searchResultPage.getResults()) {
- assertThat(result.getMatches()).isEmpty();
- }
+ assertThat(searchResultPage.getResults()).hasSize(1);
+ assertThat(searchResultPage.getResults().get(0).getMatches()).isEmpty();
}
@Test
- public void testMultipleStringSnippet() throws Exception {
- final String searchWord = "Test";
-
+ public void testMultipleStringSnippet() {
// Building the SearchResult received from query.
- PropertyProto property1 =
- PropertyProto.newBuilder()
- .setName("sender.name")
- .addStringValues("Test Name Jr.")
- .build();
- PropertyProto property2 =
- PropertyProto.newBuilder()
- .setName("sender.email")
- .addStringValues("TestNameJr@gmail.com")
- .build();
DocumentProto documentProto =
DocumentProto.newBuilder()
.setUri("uri1")
.setSchema(SCHEMA_TYPE)
- .addProperties(property1)
- .addProperties(property2)
+ .addProperties(
+ PropertyProto.newBuilder()
+ .setName("senderName")
+ .addStringValues("Test Name Jr."))
+ .addProperties(
+ PropertyProto.newBuilder()
+ .setName("senderEmail")
+ .addStringValues("TestNameJr@gmail.com"))
.build();
SnippetProto snippetProto =
SnippetProto.newBuilder()
.addEntries(
SnippetProto.EntryProto.newBuilder()
- .setPropertyName("sender.name")
+ .setPropertyName("senderName")
.addSnippetMatches(
SnippetMatchProto.newBuilder()
.setExactMatchPosition(0)
.setExactMatchBytes(4)
.setWindowPosition(0)
- .setWindowBytes(9)
- .build())
- .build())
+ .setWindowBytes(9)))
.addEntries(
SnippetProto.EntryProto.newBuilder()
- .setPropertyName("sender.email")
+ .setPropertyName("senderEmail")
.addSnippetMatches(
SnippetMatchProto.newBuilder()
.setExactMatchPosition(0)
.setExactMatchBytes(20)
.setWindowPosition(0)
- .setWindowBytes(20)
- .build())
- .build())
+ .setWindowBytes(20)))
.build();
- SearchResultProto.ResultProto resultProto =
- SearchResultProto.ResultProto.newBuilder()
- .setDocument(documentProto)
- .setSnippet(snippetProto)
+ SearchResultProto searchResultProto =
+ SearchResultProto.newBuilder()
+ .addResults(
+ SearchResultProto.ResultProto.newBuilder()
+ .setDocument(documentProto)
+ .setSnippet(snippetProto))
+ .build();
+
+ // Making ResultReader and getting Snippet values.
+ SearchResultPage searchResultPage =
+ SearchResultToProtoConverter.toSearchResultPage(
+ searchResultProto,
+ Collections.singletonList(PACKAGE_NAME),
+ Collections.singletonList(DATABASE_NAME),
+ SCHEMA_MAP);
+ assertThat(searchResultPage.getResults()).hasSize(1);
+ SearchResult.MatchInfo match1 = searchResultPage.getResults().get(0).getMatches().get(0);
+ assertThat(match1.getPropertyPath()).isEqualTo("senderName");
+ assertThat(match1.getFullText()).isEqualTo("Test Name Jr.");
+ assertThat(match1.getExactMatchRange())
+ .isEqualTo(new SearchResult.MatchRange(/*lower=*/ 0, /*upper=*/ 4));
+ assertThat(match1.getExactMatch()).isEqualTo("Test");
+ assertThat(match1.getSnippetRange())
+ .isEqualTo(new SearchResult.MatchRange(/*lower=*/ 0, /*upper=*/ 9));
+ assertThat(match1.getSnippet()).isEqualTo("Test Name");
+
+ SearchResult.MatchInfo match2 = searchResultPage.getResults().get(0).getMatches().get(1);
+ assertThat(match2.getPropertyPath()).isEqualTo("senderEmail");
+ assertThat(match2.getFullText()).isEqualTo("TestNameJr@gmail.com");
+ assertThat(match2.getExactMatchRange())
+ .isEqualTo(new SearchResult.MatchRange(/*lower=*/ 0, /*upper=*/ 20));
+ assertThat(match2.getExactMatch()).isEqualTo("TestNameJr@gmail.com");
+ assertThat(match2.getSnippetRange())
+ .isEqualTo(new SearchResult.MatchRange(/*lower=*/ 0, /*upper=*/ 20));
+ assertThat(match2.getSnippet()).isEqualTo("TestNameJr@gmail.com");
+ }
+
+ @Test
+ public void testNestedDocumentSnippet() {
+ // Building the SearchResult received from query.
+ DocumentProto documentProto =
+ DocumentProto.newBuilder()
+ .setUri("id1")
+ .setSchema(SCHEMA_TYPE)
+ .addProperties(
+ PropertyProto.newBuilder()
+ .setName("sender")
+ .addDocumentValues(
+ DocumentProto.newBuilder()
+ .addProperties(
+ PropertyProto.newBuilder()
+ .setName("name")
+ .addStringValues(
+ "Test Name Jr."))
+ .addProperties(
+ PropertyProto.newBuilder()
+ .setName("email")
+ .addStringValues(
+ "TestNameJr@gmail.com")
+ .addStringValues(
+ "TestNameJr2@gmail.com"))))
+ .build();
+ SnippetProto snippetProto =
+ SnippetProto.newBuilder()
+ .addEntries(
+ SnippetProto.EntryProto.newBuilder()
+ .setPropertyName("sender.name")
+ .addSnippetMatches(
+ SnippetMatchProto.newBuilder()
+ .setExactMatchPosition(0)
+ .setExactMatchBytes(4)
+ .setWindowPosition(0)
+ .setWindowBytes(9)))
+ .addEntries(
+ SnippetProto.EntryProto.newBuilder()
+ .setPropertyName("sender.email[1]")
+ .addSnippetMatches(
+ SnippetMatchProto.newBuilder()
+ .setExactMatchPosition(0)
+ .setExactMatchBytes(21)
+ .setWindowPosition(0)
+ .setWindowBytes(21)))
.build();
SearchResultProto searchResultProto =
- SearchResultProto.newBuilder().addResults(resultProto).build();
+ SearchResultProto.newBuilder()
+ .addResults(
+ SearchResultProto.ResultProto.newBuilder()
+ .setDocument(documentProto)
+ .setSnippet(snippetProto))
+ .build();
// Making ResultReader and getting Snippet values.
SearchResultPage searchResultPage =
@@ -218,27 +280,25 @@ public class SnippetTest {
Collections.singletonList(PACKAGE_NAME),
Collections.singletonList(DATABASE_NAME),
SCHEMA_MAP);
- for (SearchResult result : searchResultPage.getResults()) {
-
- SearchResult.MatchInfo match1 = result.getMatches().get(0);
- assertThat(match1.getPropertyPath()).isEqualTo("sender.name");
- assertThat(match1.getFullText()).isEqualTo("Test Name Jr.");
- assertThat(match1.getExactMatchRange())
- .isEqualTo(new SearchResult.MatchRange(/*lower=*/ 0, /*upper=*/ 4));
- assertThat(match1.getExactMatch()).isEqualTo("Test");
- assertThat(match1.getSnippetRange())
- .isEqualTo(new SearchResult.MatchRange(/*lower=*/ 0, /*upper=*/ 9));
- assertThat(match1.getSnippet()).isEqualTo("Test Name");
-
- SearchResult.MatchInfo match2 = result.getMatches().get(1);
- assertThat(match2.getPropertyPath()).isEqualTo("sender.email");
- assertThat(match2.getFullText()).isEqualTo("TestNameJr@gmail.com");
- assertThat(match2.getExactMatchRange())
- .isEqualTo(new SearchResult.MatchRange(/*lower=*/ 0, /*upper=*/ 20));
- assertThat(match2.getExactMatch()).isEqualTo("TestNameJr@gmail.com");
- assertThat(match2.getSnippetRange())
- .isEqualTo(new SearchResult.MatchRange(/*lower=*/ 0, /*upper=*/ 20));
- assertThat(match2.getSnippet()).isEqualTo("TestNameJr@gmail.com");
- }
+ assertThat(searchResultPage.getResults()).hasSize(1);
+ SearchResult.MatchInfo match1 = searchResultPage.getResults().get(0).getMatches().get(0);
+ assertThat(match1.getPropertyPath()).isEqualTo("sender.name");
+ assertThat(match1.getFullText()).isEqualTo("Test Name Jr.");
+ assertThat(match1.getExactMatchRange())
+ .isEqualTo(new SearchResult.MatchRange(/*lower=*/ 0, /*upper=*/ 4));
+ assertThat(match1.getExactMatch()).isEqualTo("Test");
+ assertThat(match1.getSnippetRange())
+ .isEqualTo(new SearchResult.MatchRange(/*lower=*/ 0, /*upper=*/ 9));
+ assertThat(match1.getSnippet()).isEqualTo("Test Name");
+
+ SearchResult.MatchInfo match2 = searchResultPage.getResults().get(0).getMatches().get(1);
+ assertThat(match2.getPropertyPath()).isEqualTo("sender.email[1]");
+ assertThat(match2.getFullText()).isEqualTo("TestNameJr2@gmail.com");
+ assertThat(match2.getExactMatchRange())
+ .isEqualTo(new SearchResult.MatchRange(/*lower=*/ 0, /*upper=*/ 21));
+ assertThat(match2.getExactMatch()).isEqualTo("TestNameJr2@gmail.com");
+ assertThat(match2.getSnippetRange())
+ .isEqualTo(new SearchResult.MatchRange(/*lower=*/ 0, /*upper=*/ 21));
+ assertThat(match2.getSnippet()).isEqualTo("TestNameJr2@gmail.com");
}
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index b9f70da60de2..358120664cea 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -704,36 +704,36 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
final String key = getKey(userId, databaseName);
Map<String, GenericDocument> docMap = mDocumentMap.get(key);
for (GenericDocument doc : docs) {
- builder.setSuccess(doc.getUri(), null);
+ builder.setSuccess(doc.getId(), null);
if (docMap == null) {
docMap = new ArrayMap<>(1);
mDocumentMap.put(key, docMap);
}
- docMap.put(doc.getUri(), doc);
+ docMap.put(doc.getId(), doc);
}
callback.onResult(builder.build());
}
@Override
public void getDocuments(String packageName, String databaseName, String namespace,
- List<String> uris, Map<String, List<String>> typePropertyPaths, int userId,
+ List<String> ids, Map<String, List<String>> typePropertyPaths, int userId,
IAppSearchBatchResultCallback callback) throws RemoteException {
final AppSearchBatchResult.Builder<String, Bundle> builder =
new AppSearchBatchResult.Builder<>();
final String key = getKey(userId, databaseName);
if (!mDocumentMap.containsKey(key)) {
- for (String uri : uris) {
- builder.setFailure(uri, AppSearchResult.RESULT_NOT_FOUND,
- key + " not found when getting: " + uri);
+ for (String id : ids) {
+ builder.setFailure(id, AppSearchResult.RESULT_NOT_FOUND,
+ key + " not found when getting: " + id);
}
} else {
final Map<String, GenericDocument> docs = mDocumentMap.get(key);
- for (String uri : uris) {
- if (docs.containsKey(uri)) {
- builder.setSuccess(uri, docs.get(uri).getBundle());
+ for (String id : ids) {
+ if (docs.containsKey(id)) {
+ builder.setSuccess(id, docs.get(id).getBundle());
} else {
- builder.setFailure(uri, AppSearchResult.RESULT_NOT_FOUND,
- "shortcut not found: " + uri);
+ builder.setFailure(id, AppSearchResult.RESULT_NOT_FOUND,
+ "shortcut not found: " + id);
}
}
}
@@ -805,33 +805,33 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
@Override
public void reportUsage(String packageName, String databaseName, String namespace,
- String uri, long usageTimeMillis, boolean systemUsage, int userId,
+ String documentId, long usageTimestampMillis, boolean systemUsage, int userId,
IAppSearchResultCallback callback)
throws RemoteException {
ignore(callback);
}
@Override
- public void removeByUri(String packageName, String databaseName, String namespace,
- List<String> uris, int userId, IAppSearchBatchResultCallback callback)
+ public void removeByDocumentId(String packageName, String databaseName, String namespace,
+ List<String> ids, int userId, IAppSearchBatchResultCallback callback)
throws RemoteException {
final AppSearchBatchResult.Builder<String, Void> builder =
new AppSearchBatchResult.Builder<>();
final String key = getKey(userId, databaseName);
if (!mDocumentMap.containsKey(key)) {
- for (String uri : uris) {
- builder.setFailure(uri, AppSearchResult.RESULT_NOT_FOUND,
- "package " + key + " not found when removing " + uri);
+ for (String id : ids) {
+ builder.setFailure(id, AppSearchResult.RESULT_NOT_FOUND,
+ "package " + key + " not found when removing " + id);
}
} else {
final Map<String, GenericDocument> docs = mDocumentMap.get(key);
- for (String uri : uris) {
- if (docs.containsKey(uri)) {
- docs.remove(uri);
- builder.setSuccess(uri, null);
+ for (String id : ids) {
+ if (docs.containsKey(id)) {
+ docs.remove(id);
+ builder.setSuccess(id, null);
} else {
- builder.setFailure(uri, AppSearchResult.RESULT_NOT_FOUND,
- "shortcut not found when removing " + uri);
+ builder.setFailure(id, AppSearchResult.RESULT_NOT_FOUND,
+ "shortcut not found when removing " + id);
}
}
}