Merge "Update framework from jetpack." into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
5681f7c05f
@@ -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 {
|
||||
|
||||
@@ -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}.
|
||||
*/
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -100,7 +100,7 @@ interface IAppSearchManager {
|
||||
* will be called with the cause throwable. Otherwise,
|
||||
* {@link IAppSearchBatchResultCallback#onResult} will be called with an
|
||||
* {@link AppSearchBatchResult}<{@link String}, {@link Void}>
|
||||
* 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}<{@link String}, {@link Bundle}>
|
||||
* 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}<{@link String}, {@link Void}>
|
||||
* 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);
|
||||
|
||||
|
||||
@@ -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} */
|
||||
|
||||
@@ -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) {
|
||||
/**
|
||||
* Creates a new {@link DocumentPropertyConfig.Builder}.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
public Builder(@NonNull String propertyName, @NonNull String schemaType) {
|
||||
mBundle.putString(NAME_FIELD, propertyName);
|
||||
mBundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_DOCUMENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* The logical schema-type of the contents of this property.
|
||||
*
|
||||
* <p>This property must be set.
|
||||
*/
|
||||
@NonNull
|
||||
public DocumentPropertyConfig.Builder setSchemaType(@NonNull String schemaType) {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
Objects.requireNonNull(schemaType);
|
||||
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);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<>();
|
||||
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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. */
|
||||
@NonNull
|
||||
public String getSchemaType() {
|
||||
return mBundle.getString(SCHEMA_TYPE_FIELD, /*defaultValue=*/ "");
|
||||
}
|
||||
|
||||
/** Returns the namespace of the {@link GenericDocument} that fails to be migrated. */
|
||||
/** Returns the namespace of the {@link GenericDocument} that failed to be migrated. */
|
||||
@NonNull
|
||||
public String getNamespace() {
|
||||
return mBundle.getString(NAMESPACE_FIELD, /*defaultValue=*/ "");
|
||||
}
|
||||
|
||||
/** Returns the uri of the {@link GenericDocument} that fails to be migrated. */
|
||||
/** Returns the id of the {@link GenericDocument} that failed to be migrated. */
|
||||
@NonNull
|
||||
public String getUri() {
|
||||
return mBundle.getString(URI_FIELD, /*defaultValue=*/ "");
|
||||
public String getDocumentId() {
|
||||
return mBundle.getString(DOCUMENT_ID_FIELD, /*defaultValue=*/ "");
|
||||
}
|
||||
|
||||
/** Returns the schema type of the {@link GenericDocument} that failed to be migrated. */
|
||||
@NonNull
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -1 +1 @@
|
||||
If9d1d770d2327d7d0db7d82acfc54787b5de64bc
|
||||
I06df2c636d26419e653c5d8c9e7d15449da6816e
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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,32 +141,108 @@ 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("senderName")
|
||||
.addSnippetMatches(
|
||||
SnippetMatchProto.newBuilder()
|
||||
.setExactMatchPosition(0)
|
||||
.setExactMatchBytes(4)
|
||||
.setWindowPosition(0)
|
||||
.setWindowBytes(9)))
|
||||
.addEntries(
|
||||
SnippetProto.EntryProto.newBuilder()
|
||||
.setPropertyName("senderEmail")
|
||||
.addSnippetMatches(
|
||||
SnippetMatchProto.newBuilder()
|
||||
.setExactMatchPosition(0)
|
||||
.setExactMatchBytes(20)
|
||||
.setWindowPosition(0)
|
||||
.setWindowBytes(20)))
|
||||
.build();
|
||||
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()
|
||||
@@ -188,28 +254,24 @@ public class SnippetTest {
|
||||
.setExactMatchPosition(0)
|
||||
.setExactMatchBytes(4)
|
||||
.setWindowPosition(0)
|
||||
.setWindowBytes(9)
|
||||
.build())
|
||||
.build())
|
||||
.setWindowBytes(9)))
|
||||
.addEntries(
|
||||
SnippetProto.EntryProto.newBuilder()
|
||||
.setPropertyName("sender.email")
|
||||
.setPropertyName("sender.email[1]")
|
||||
.addSnippetMatches(
|
||||
SnippetMatchProto.newBuilder()
|
||||
.setExactMatchPosition(0)
|
||||
.setExactMatchBytes(20)
|
||||
.setExactMatchBytes(21)
|
||||
.setWindowPosition(0)
|
||||
.setWindowBytes(20)
|
||||
.build())
|
||||
.build())
|
||||
.build();
|
||||
SearchResultProto.ResultProto resultProto =
|
||||
SearchResultProto.ResultProto.newBuilder()
|
||||
.setDocument(documentProto)
|
||||
.setSnippet(snippetProto)
|
||||
.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()) {
|
||||
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 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");
|
||||
}
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user