Update framework from Jetpack.
Changes included: * 081c412: Remove spam logs from GenericDocumentToPlatformConverter. * 69df01d: Fix an issue with nested documents after serialization. * 0197939: Update Jetpack API usages to build against the latest SDK. * 843f415: Rename @AppSearchDocument to @Document. * 37adb0f: Update docs around database name. * 19383f8: Apply naming changes to AppSearchSession and GlobalSearchSession. * 8359c2b: Update SetSchemaRequest to comply with API council requirements. * 4b04aba: Update PutDocumentsRequest APIs to align with API council guidance. * 3c8ebfb: Update SearchSpec APIs to match API council recommendations. Bug: 174614009 Bug: 178540467 Bug: 175763859 Bug: 171340471 Test: Presubmit Change-Id: I4649ffe1d1c94b0c6125943772d33c6fb38d0006
This commit is contained in:
@@ -143,11 +143,11 @@ package android.app.appsearch {
|
||||
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 getSchema(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<java.util.Set<android.app.appsearch.AppSearchSchema>>>);
|
||||
method public void putDocuments(@NonNull android.app.appsearch.PutDocumentsRequest, @NonNull java.util.concurrent.Executor, @NonNull android.app.appsearch.BatchResultCallback<java.lang.String,java.lang.Void>);
|
||||
method @NonNull public android.app.appsearch.SearchResults query(@NonNull String, @NonNull android.app.appsearch.SearchSpec, @NonNull java.util.concurrent.Executor);
|
||||
method public void removeByQuery(@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 removeByUri(@NonNull android.app.appsearch.RemoveByUriRequest, @NonNull java.util.concurrent.Executor, @NonNull android.app.appsearch.BatchResultCallback<java.lang.String,java.lang.Void>);
|
||||
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 String, @NonNull android.app.appsearch.SearchSpec, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<java.lang.Void>>);
|
||||
method @NonNull 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, @NonNull java.util.concurrent.Executor);
|
||||
method public void setSchema(@NonNull android.app.appsearch.SetSchemaRequest, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<android.app.appsearch.SetSchemaResponse>>);
|
||||
}
|
||||
|
||||
@@ -216,7 +216,7 @@ package android.app.appsearch {
|
||||
|
||||
public class GlobalSearchSession implements java.io.Closeable {
|
||||
method public void close();
|
||||
method @NonNull public android.app.appsearch.SearchResults query(@NonNull String, @NonNull android.app.appsearch.SearchSpec, @NonNull java.util.concurrent.Executor);
|
||||
method @NonNull public android.app.appsearch.SearchResults search(@NonNull String, @NonNull android.app.appsearch.SearchSpec, @NonNull java.util.concurrent.Executor);
|
||||
}
|
||||
|
||||
public class PackageIdentifier {
|
||||
@@ -226,13 +226,13 @@ package android.app.appsearch {
|
||||
}
|
||||
|
||||
public final class PutDocumentsRequest {
|
||||
method @NonNull public java.util.List<android.app.appsearch.GenericDocument> getDocuments();
|
||||
method @NonNull public java.util.List<android.app.appsearch.GenericDocument> getGenericDocuments();
|
||||
}
|
||||
|
||||
public static final class PutDocumentsRequest.Builder {
|
||||
ctor public PutDocumentsRequest.Builder();
|
||||
method @NonNull public android.app.appsearch.PutDocumentsRequest.Builder addGenericDocument(@NonNull android.app.appsearch.GenericDocument...);
|
||||
method @NonNull public android.app.appsearch.PutDocumentsRequest.Builder addGenericDocument(@NonNull java.util.Collection<? extends android.app.appsearch.GenericDocument>);
|
||||
method @NonNull public android.app.appsearch.PutDocumentsRequest.Builder addGenericDocuments(@NonNull android.app.appsearch.GenericDocument...);
|
||||
method @NonNull public android.app.appsearch.PutDocumentsRequest.Builder addGenericDocuments(@NonNull java.util.Collection<? extends android.app.appsearch.GenericDocument>);
|
||||
method @NonNull public android.app.appsearch.PutDocumentsRequest build();
|
||||
}
|
||||
|
||||
@@ -290,14 +290,14 @@ package android.app.appsearch {
|
||||
}
|
||||
|
||||
public final class SearchSpec {
|
||||
method @NonNull public java.util.List<java.lang.String> getFilterNamespaces();
|
||||
method @NonNull public java.util.List<java.lang.String> getFilterPackageNames();
|
||||
method @NonNull public java.util.List<java.lang.String> getFilterSchemas();
|
||||
method public int getMaxSnippetSize();
|
||||
method @NonNull public java.util.List<java.lang.String> getNamespaces();
|
||||
method public int getOrder();
|
||||
method @NonNull public java.util.Map<java.lang.String,java.util.List<java.lang.String>> getProjections();
|
||||
method public int getRankingStrategy();
|
||||
method public int getResultCountPerPage();
|
||||
method @NonNull public java.util.List<java.lang.String> getSchemaTypes();
|
||||
method public int getSnippetCount();
|
||||
method public int getSnippetCountPerProperty();
|
||||
method public int getTermMatch();
|
||||
@@ -316,14 +316,14 @@ package android.app.appsearch {
|
||||
|
||||
public static final class SearchSpec.Builder {
|
||||
ctor public SearchSpec.Builder();
|
||||
method @NonNull public android.app.appsearch.SearchSpec.Builder addFilterNamespaces(@NonNull java.lang.String...);
|
||||
method @NonNull public android.app.appsearch.SearchSpec.Builder addFilterNamespaces(@NonNull java.util.Collection<java.lang.String>);
|
||||
method @NonNull public android.app.appsearch.SearchSpec.Builder addFilterPackageNames(@NonNull java.lang.String...);
|
||||
method @NonNull public android.app.appsearch.SearchSpec.Builder addFilterPackageNames(@NonNull java.util.Collection<java.lang.String>);
|
||||
method @NonNull public android.app.appsearch.SearchSpec.Builder addNamespace(@NonNull java.lang.String...);
|
||||
method @NonNull public android.app.appsearch.SearchSpec.Builder addNamespace(@NonNull java.util.Collection<java.lang.String>);
|
||||
method @NonNull public android.app.appsearch.SearchSpec.Builder addFilterSchemas(@NonNull java.lang.String...);
|
||||
method @NonNull public android.app.appsearch.SearchSpec.Builder addFilterSchemas(@NonNull java.util.Collection<java.lang.String>);
|
||||
method @NonNull public android.app.appsearch.SearchSpec.Builder addProjection(@NonNull String, @NonNull java.lang.String...);
|
||||
method @NonNull public android.app.appsearch.SearchSpec.Builder addProjection(@NonNull String, @NonNull java.util.Collection<java.lang.String>);
|
||||
method @NonNull public android.app.appsearch.SearchSpec.Builder addSchemaType(@NonNull java.lang.String...);
|
||||
method @NonNull public android.app.appsearch.SearchSpec.Builder addSchemaType(@NonNull java.util.Collection<java.lang.String>);
|
||||
method @NonNull public android.app.appsearch.SearchSpec build();
|
||||
method @NonNull public android.app.appsearch.SearchSpec.Builder setMaxSnippetSize(@IntRange(from=0, to=android.app.appsearch.SearchSpec.MAX_SNIPPET_SIZE_LIMIT) int);
|
||||
method @NonNull public android.app.appsearch.SearchSpec.Builder setOrder(int);
|
||||
@@ -344,8 +344,8 @@ package android.app.appsearch {
|
||||
|
||||
public static final class SetSchemaRequest.Builder {
|
||||
ctor public SetSchemaRequest.Builder();
|
||||
method @NonNull public android.app.appsearch.SetSchemaRequest.Builder addSchema(@NonNull android.app.appsearch.AppSearchSchema...);
|
||||
method @NonNull public android.app.appsearch.SetSchemaRequest.Builder addSchema(@NonNull java.util.Collection<android.app.appsearch.AppSearchSchema>);
|
||||
method @NonNull public android.app.appsearch.SetSchemaRequest.Builder addSchemas(@NonNull android.app.appsearch.AppSearchSchema...);
|
||||
method @NonNull public android.app.appsearch.SetSchemaRequest.Builder addSchemas(@NonNull java.util.Collection<android.app.appsearch.AppSearchSchema>);
|
||||
method @NonNull public android.app.appsearch.SetSchemaRequest build();
|
||||
method @NonNull public android.app.appsearch.SetSchemaRequest.Builder setForceOverride(boolean);
|
||||
method @NonNull public android.app.appsearch.SetSchemaRequest.Builder setMigrator(@NonNull String, @NonNull android.app.appsearch.AppSearchSchema.Migrator);
|
||||
|
||||
@@ -270,12 +270,12 @@ public class AppSearchManager {
|
||||
* they were successfully indexed, or a failed {@link AppSearchResult} otherwise.
|
||||
* @throws RuntimeException If an error occurred during the execution.
|
||||
* @hide
|
||||
* @deprecated use {@link AppSearchSession#putDocuments} instead.
|
||||
* @deprecated use {@link AppSearchSession#put} instead.
|
||||
*/
|
||||
public AppSearchBatchResult<String, Void> putDocuments(@NonNull PutDocumentsRequest request) {
|
||||
// TODO(b/146386470): Transmit these documents as a RemoteStream instead of sending them in
|
||||
// one big list.
|
||||
List<GenericDocument> documents = request.getDocuments();
|
||||
List<GenericDocument> documents = request.getGenericDocuments();
|
||||
List<Bundle> documentBundles = new ArrayList<>(documents.size());
|
||||
for (int i = 0; i < documents.size(); i++) {
|
||||
documentBundles.add(documents.get(i).getBundle());
|
||||
@@ -330,7 +330,7 @@ public class AppSearchManager {
|
||||
DEFAULT_DATABASE_NAME,
|
||||
request.getNamespace(),
|
||||
uris,
|
||||
request.getProjectionsVisibleToPackagesInternal(),
|
||||
request.getProjectionsInternal(),
|
||||
mContext.getUserId(),
|
||||
new IAppSearchBatchResultCallback.Stub() {
|
||||
public void onResult(AppSearchBatchResult result) {
|
||||
@@ -465,7 +465,7 @@ public class AppSearchManager {
|
||||
* {@link AppSearchResult} with a result code of {@link AppSearchResult#RESULT_NOT_FOUND}.
|
||||
* @throws RuntimeException If an error occurred during the execution.
|
||||
* @hide
|
||||
* @deprecated use {@link AppSearchSession#removeByUri} instead.
|
||||
* @deprecated use {@link AppSearchSession#remove} instead.
|
||||
*/
|
||||
public AppSearchBatchResult<String, Void> removeByUri(@NonNull RemoveByUriRequest request) {
|
||||
List<String> uris = new ArrayList<>(request.getUris());
|
||||
|
||||
@@ -102,7 +102,7 @@ public final class AppSearchSession implements Closeable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the schema that will be used by documents provided to the {@link #putDocuments} method.
|
||||
* Sets the schema that will be used by documents provided to the {@link #put} method.
|
||||
*
|
||||
* <p>The schema provided here is compared to the stored copy of the schema previously supplied
|
||||
* to {@link #setSchema}, if any, to determine how to treat existing documents. The following
|
||||
@@ -268,7 +268,7 @@ public final class AppSearchSession implements Closeable {
|
||||
* {@link Throwable} if an unexpected internal error occurred in AppSearch
|
||||
* service.
|
||||
*/
|
||||
public void putDocuments(
|
||||
public void put(
|
||||
@NonNull PutDocumentsRequest request,
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull BatchResultCallback<String, Void> callback) {
|
||||
@@ -276,7 +276,7 @@ public final class AppSearchSession implements Closeable {
|
||||
Objects.requireNonNull(executor);
|
||||
Objects.requireNonNull(callback);
|
||||
Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
|
||||
List<GenericDocument> documents = request.getDocuments();
|
||||
List<GenericDocument> documents = request.getGenericDocuments();
|
||||
List<Bundle> documentBundles = new ArrayList<>(documents.size());
|
||||
for (int i = 0; i < documents.size(); i++) {
|
||||
documentBundles.add(documents.get(i).getBundle());
|
||||
@@ -327,7 +327,7 @@ public final class AppSearchSession implements Closeable {
|
||||
mDatabaseName,
|
||||
request.getNamespace(),
|
||||
new ArrayList<>(request.getUris()),
|
||||
request.getProjectionsVisibleToPackagesInternal(),
|
||||
request.getProjectionsInternal(),
|
||||
mUserId,
|
||||
new IAppSearchBatchResultCallback.Stub() {
|
||||
public void onResult(AppSearchBatchResult result) {
|
||||
@@ -423,7 +423,7 @@ public final class AppSearchSession implements Closeable {
|
||||
* @return The search result of performing this operation.
|
||||
*/
|
||||
@NonNull
|
||||
public SearchResults query(
|
||||
public SearchResults search(
|
||||
@NonNull String queryExpression,
|
||||
@NonNull SearchSpec searchSpec,
|
||||
@NonNull @CallbackExecutor Executor executor) {
|
||||
@@ -441,7 +441,7 @@ public final class AppSearchSession implements Closeable {
|
||||
* <p>A usage report represents an event in which a user interacted with or viewed a document.
|
||||
*
|
||||
* <p>For each call to {@link #reportUsage}, AppSearch updates usage count and usage recency
|
||||
* metrics for that particular document. These metrics are used for ordering {@link #query}
|
||||
* metrics for that particular document. These metrics are used for ordering {@link #search}
|
||||
* results by the {@link SearchSpec#RANKING_STRATEGY_USAGE_COUNT} and
|
||||
* {@link SearchSpec#RANKING_STRATEGY_USAGE_LAST_USED_TIMESTAMP} ranking strategies.
|
||||
*
|
||||
@@ -494,7 +494,7 @@ public final class AppSearchSession implements Closeable {
|
||||
* {@link Throwable} if an unexpected internal error occurred in AppSearch
|
||||
* service.
|
||||
*/
|
||||
public void removeByUri(
|
||||
public void remove(
|
||||
@NonNull RemoveByUriRequest request,
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull BatchResultCallback<String, Void> callback) {
|
||||
@@ -523,7 +523,8 @@ public final class AppSearchSession implements Closeable {
|
||||
/**
|
||||
* Removes {@link GenericDocument}s from the index by Query. Documents will be removed if they
|
||||
* match the {@code queryExpression} in given namespaces and schemaTypes which is set via
|
||||
* {@link SearchSpec.Builder#addNamespace} and {@link SearchSpec.Builder#addSchemaType}.
|
||||
* {@link SearchSpec.Builder#addFilterNamespaces} and
|
||||
* {@link SearchSpec.Builder#addFilterSchemas}.
|
||||
*
|
||||
* <p> An empty {@code queryExpression} matches all documents.
|
||||
*
|
||||
@@ -539,7 +540,8 @@ public final class AppSearchSession implements Closeable {
|
||||
* the operation succeeds, the callback will be invoked with
|
||||
* {@code null}.
|
||||
*/
|
||||
public void removeByQuery(@NonNull String queryExpression,
|
||||
public void remove(
|
||||
@NonNull String queryExpression,
|
||||
@NonNull SearchSpec searchSpec,
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull Consumer<AppSearchResult<Void>> callback) {
|
||||
|
||||
@@ -134,7 +134,7 @@ public class GlobalSearchSession implements Closeable {
|
||||
* @return The search result of performing this operation.
|
||||
*/
|
||||
@NonNull
|
||||
public SearchResults query(
|
||||
public SearchResults search(
|
||||
@NonNull String queryExpression,
|
||||
@NonNull SearchSpec searchSpec,
|
||||
@NonNull @CallbackExecutor Executor executor) {
|
||||
|
||||
@@ -141,10 +141,6 @@ public final class AppSearchSchema {
|
||||
}
|
||||
|
||||
/** Adds a property to the given type. */
|
||||
// TODO(b/171360120): MissingGetterMatchingBuilder expects a method called getPropertys, but
|
||||
// we provide the (correct) method getProperties. Once the bug referenced in this TODO is
|
||||
// fixed, remove this SuppressLint.
|
||||
@SuppressLint("MissingGetterMatchingBuilder")
|
||||
@NonNull
|
||||
public AppSearchSchema.Builder addProperty(@NonNull PropertyConfig propertyConfig) {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.annotation.Nullable;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.appsearch.util.BundleUtil;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
@@ -37,9 +38,9 @@ import java.util.Set;
|
||||
*
|
||||
* <p>Documents are constructed via {@link GenericDocument.Builder}.
|
||||
*
|
||||
* @see AppSearchSession#putDocuments
|
||||
* @see AppSearchSession#put
|
||||
* @see AppSearchSession#getByUri
|
||||
* @see AppSearchSession#query
|
||||
* @see AppSearchSession#search
|
||||
*/
|
||||
public class GenericDocument {
|
||||
private static final String TAG = "AppSearchGenericDocumen";
|
||||
@@ -210,7 +211,7 @@ public class GenericDocument {
|
||||
Object property = mProperties.get(key);
|
||||
if (property instanceof ArrayList) {
|
||||
return getPropertyBytesArray(key);
|
||||
} else if (property instanceof Bundle[]) {
|
||||
} else if (property instanceof Parcelable[]) {
|
||||
return getPropertyDocumentArray(key);
|
||||
}
|
||||
return property;
|
||||
@@ -436,7 +437,7 @@ public class GenericDocument {
|
||||
@Nullable
|
||||
public GenericDocument[] getPropertyDocumentArray(@NonNull String key) {
|
||||
Preconditions.checkNotNull(key);
|
||||
Bundle[] bundles = getAndCastPropertyArray(key, Bundle[].class);
|
||||
Parcelable[] bundles = getAndCastPropertyArray(key, Parcelable[].class);
|
||||
if (bundles == null || bundles.length == 0) {
|
||||
return null;
|
||||
}
|
||||
@@ -446,7 +447,18 @@ public class GenericDocument {
|
||||
Log.e(TAG, "The inner bundle is null at " + i + ", for key: " + key);
|
||||
continue;
|
||||
}
|
||||
documents[i] = new GenericDocument(bundles[i]);
|
||||
if (!(bundles[i] instanceof Bundle)) {
|
||||
Log.e(
|
||||
TAG,
|
||||
"The inner element at "
|
||||
+ i
|
||||
+ " is a "
|
||||
+ bundles[i].getClass()
|
||||
+ ", not a Bundle for key: "
|
||||
+ key);
|
||||
continue;
|
||||
}
|
||||
documents[i] = new GenericDocument((Bundle) bundles[i]);
|
||||
}
|
||||
return documents;
|
||||
}
|
||||
@@ -574,8 +586,8 @@ public class GenericDocument {
|
||||
* @param schemaType The schema type of the {@link GenericDocument}. The passed-in {@code
|
||||
* schemaType} must be defined using {@link AppSearchSession#setSchema} prior to
|
||||
* inserting a document of this {@code schemaType} into the AppSearch index using {@link
|
||||
* AppSearchSession#putDocuments}. Otherwise, the document will be rejected by {@link
|
||||
* AppSearchSession#putDocuments}.
|
||||
* AppSearchSession#put}. Otherwise, the document will be rejected by {@link
|
||||
* AppSearchSession#put}.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Builder(@NonNull String uri, @NonNull String schemaType) {
|
||||
@@ -817,7 +829,7 @@ public class GenericDocument {
|
||||
|
||||
private void putInPropertyBundle(@NonNull String key, @NonNull GenericDocument[] values) {
|
||||
validateRepeatedPropertyLength(key, values.length);
|
||||
Bundle[] documentBundles = new Bundle[values.length];
|
||||
Parcelable[] documentBundles = new Parcelable[values.length];
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
if (values[i] == null) {
|
||||
throw new IllegalArgumentException("The document at " + i + " is null.");
|
||||
|
||||
@@ -96,7 +96,7 @@ public final class GetByUriRequest {
|
||||
* @hide
|
||||
*/
|
||||
@NonNull
|
||||
public Map<String, List<String>> getProjectionsVisibleToPackagesInternal() {
|
||||
public Map<String, List<String>> getProjectionsInternal() {
|
||||
return mTypePropertyPathsMap;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
package android.app.appsearch;
|
||||
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.SuppressLint;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
@@ -41,7 +41,7 @@ public final class PutDocumentsRequest {
|
||||
|
||||
/** Returns the documents that are part of this request. */
|
||||
@NonNull
|
||||
public List<GenericDocument> getDocuments() {
|
||||
public List<GenericDocument> getGenericDocuments() {
|
||||
return Collections.unmodifiableList(mDocuments);
|
||||
}
|
||||
|
||||
@@ -55,17 +55,15 @@ public final class PutDocumentsRequest {
|
||||
private boolean mBuilt = false;
|
||||
|
||||
/** Adds one or more {@link GenericDocument} objects to the request. */
|
||||
@SuppressLint("MissingGetterMatchingBuilder") // Merged list available from getDocuments()
|
||||
@NonNull
|
||||
public Builder addGenericDocument(@NonNull GenericDocument... documents) {
|
||||
public Builder addGenericDocuments(@NonNull GenericDocument... documents) {
|
||||
Preconditions.checkNotNull(documents);
|
||||
return addGenericDocument(Arrays.asList(documents));
|
||||
return addGenericDocuments(Arrays.asList(documents));
|
||||
}
|
||||
|
||||
/** Adds a collection of {@link GenericDocument} objects to the request. */
|
||||
@SuppressLint("MissingGetterMatchingBuilder") // Merged list available from getDocuments()
|
||||
@NonNull
|
||||
public Builder addGenericDocument(
|
||||
public Builder addGenericDocuments(
|
||||
@NonNull Collection<? extends GenericDocument> documents) {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
Preconditions.checkNotNull(documents);
|
||||
|
||||
@@ -29,7 +29,7 @@ import java.util.Set;
|
||||
/**
|
||||
* Encapsulates a request to remove documents by namespace and URI.
|
||||
*
|
||||
* @see AppSearchSession#removeByUri
|
||||
* @see AppSearchSession#remove
|
||||
*/
|
||||
public final class RemoveByUriRequest {
|
||||
private final String mNamespace;
|
||||
|
||||
@@ -19,7 +19,6 @@ package android.app.appsearch;
|
||||
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;
|
||||
@@ -49,7 +48,7 @@ public final class SearchSpec {
|
||||
public static final String PROJECTION_SCHEMA_TYPE_WILDCARD = "*";
|
||||
|
||||
static final String TERM_MATCH_TYPE_FIELD = "termMatchType";
|
||||
static final String SCHEMA_TYPE_FIELD = "schemaType";
|
||||
static final String SCHEMA_FIELD = "schema";
|
||||
static final String NAMESPACE_FIELD = "namespace";
|
||||
static final String PACKAGE_NAME_FIELD = "packageName";
|
||||
static final String NUM_PER_PAGE_FIELD = "numPerPage";
|
||||
@@ -171,12 +170,12 @@ public final class SearchSpec {
|
||||
* <p>If empty, the query will search over all schema types.
|
||||
*/
|
||||
@NonNull
|
||||
public List<String> getSchemaTypes() {
|
||||
List<String> schemaTypes = mBundle.getStringArrayList(SCHEMA_TYPE_FIELD);
|
||||
if (schemaTypes == null) {
|
||||
public List<String> getFilterSchemas() {
|
||||
List<String> schemas = mBundle.getStringArrayList(SCHEMA_FIELD);
|
||||
if (schemas == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Collections.unmodifiableList(schemaTypes);
|
||||
return Collections.unmodifiableList(schemas);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -185,7 +184,7 @@ public final class SearchSpec {
|
||||
* <p>If empty, the query will search over all namespaces.
|
||||
*/
|
||||
@NonNull
|
||||
public List<String> getNamespaces() {
|
||||
public List<String> getFilterNamespaces() {
|
||||
List<String> namespaces = mBundle.getStringArrayList(NAMESPACE_FIELD);
|
||||
if (namespaces == null) {
|
||||
return Collections.emptyList();
|
||||
@@ -209,24 +208,6 @@ public final class SearchSpec {
|
||||
return Collections.unmodifiableList(packageNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of package names to search over.
|
||||
*
|
||||
* <p>If unset, the query will search over all packages that the caller has access to. If
|
||||
* package names are specified which caller doesn't have access to, then those package names
|
||||
* will be ignored.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@NonNull
|
||||
public List<String> getPackageNames() {
|
||||
List<String> packageNames = mBundle.getStringArrayList(PACKAGE_NAME_FIELD);
|
||||
if (packageNames == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Collections.unmodifiableList(packageNames);
|
||||
}
|
||||
|
||||
/** Returns the number of results per page in the result set. */
|
||||
public int getResultCountPerPage() {
|
||||
return mBundle.getInt(NUM_PER_PAGE_FIELD, DEFAULT_NUM_PER_PAGE);
|
||||
@@ -270,11 +251,10 @@ public final class SearchSpec {
|
||||
@NonNull
|
||||
public Map<String, List<String>> getProjections() {
|
||||
Bundle typePropertyPathsBundle = mBundle.getBundle(PROJECTION_TYPE_PROPERTY_PATHS_FIELD);
|
||||
Set<String> schemaTypes = typePropertyPathsBundle.keySet();
|
||||
Map<String, List<String>> typePropertyPathsMap = new ArrayMap<>(schemaTypes.size());
|
||||
for (String schemaType : schemaTypes) {
|
||||
typePropertyPathsMap.put(
|
||||
schemaType, typePropertyPathsBundle.getStringArrayList(schemaType));
|
||||
Set<String> schemas = typePropertyPathsBundle.keySet();
|
||||
Map<String, List<String>> typePropertyPathsMap = new ArrayMap<>(schemas.size());
|
||||
for (String schema : schemas) {
|
||||
typePropertyPathsMap.put(schema, typePropertyPathsBundle.getStringArrayList(schema));
|
||||
}
|
||||
return typePropertyPathsMap;
|
||||
}
|
||||
@@ -283,7 +263,7 @@ public final class SearchSpec {
|
||||
public static final class Builder {
|
||||
|
||||
private final Bundle mBundle;
|
||||
private final ArrayList<String> mSchemaTypes = new ArrayList<>();
|
||||
private final ArrayList<String> mSchemas = new ArrayList<>();
|
||||
private final ArrayList<String> mNamespaces = new ArrayList<>();
|
||||
private final ArrayList<String> mPackageNames = new ArrayList<>();
|
||||
private final Bundle mProjectionTypePropertyMasks = new Bundle();
|
||||
@@ -312,10 +292,10 @@ public final class SearchSpec {
|
||||
* <p>If unset, the query will search over all schema types.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder addSchemaType(@NonNull String... schemaTypes) {
|
||||
Preconditions.checkNotNull(schemaTypes);
|
||||
public Builder addFilterSchemas(@NonNull String... schemas) {
|
||||
Preconditions.checkNotNull(schemas);
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
return addSchemaType(Arrays.asList(schemaTypes));
|
||||
return addFilterSchemas(Arrays.asList(schemas));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -325,10 +305,10 @@ public final class SearchSpec {
|
||||
* <p>If unset, the query will search over all schema types.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder addSchemaType(@NonNull Collection<String> schemaTypes) {
|
||||
Preconditions.checkNotNull(schemaTypes);
|
||||
public Builder addFilterSchemas(@NonNull Collection<String> schemas) {
|
||||
Preconditions.checkNotNull(schemas);
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
mSchemaTypes.addAll(schemaTypes);
|
||||
mSchemas.addAll(schemas);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -339,10 +319,10 @@ public final class SearchSpec {
|
||||
* <p>If unset, the query will search over all namespaces.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder addNamespace(@NonNull String... namespaces) {
|
||||
public Builder addFilterNamespaces(@NonNull String... namespaces) {
|
||||
Preconditions.checkNotNull(namespaces);
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
return addNamespace(Arrays.asList(namespaces));
|
||||
return addFilterNamespaces(Arrays.asList(namespaces));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -352,7 +332,7 @@ public final class SearchSpec {
|
||||
* <p>If unset, the query will search over all namespaces.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder addNamespace(@NonNull Collection<String> namespaces) {
|
||||
public Builder addFilterNamespaces(@NonNull Collection<String> namespaces) {
|
||||
Preconditions.checkNotNull(namespaces);
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
mNamespaces.addAll(namespaces);
|
||||
@@ -367,9 +347,6 @@ public final class SearchSpec {
|
||||
* package names are specified which caller doesn't have access to, then those package names
|
||||
* will be ignored.
|
||||
*/
|
||||
// Getter is called "getFilterPackageNames" (as opposed to the suggested
|
||||
// "getFilterPackageNameses")
|
||||
@SuppressLint("MissingGetterMatchingBuilder")
|
||||
@NonNull
|
||||
public Builder addFilterPackageNames(@NonNull String... packageNames) {
|
||||
Preconditions.checkNotNull(packageNames);
|
||||
@@ -385,9 +362,6 @@ public final class SearchSpec {
|
||||
* package names are specified which caller doesn't have access to, then those package names
|
||||
* will be ignored.
|
||||
*/
|
||||
// Getter is called "getFilterPackageNames" (as opposed to the suggested
|
||||
// "getFilterPackageNameses")
|
||||
@SuppressLint("MissingGetterMatchingBuilder")
|
||||
@NonNull
|
||||
public Builder addFilterPackageNames(@NonNull Collection<String> packageNames) {
|
||||
Preconditions.checkNotNull(packageNames);
|
||||
@@ -537,7 +511,7 @@ public final class SearchSpec {
|
||||
* type property paths:
|
||||
*
|
||||
* <pre>{@code
|
||||
* {schemaType: "Email", ["subject", "sender.name", "recipients.name"]}
|
||||
* {schema: "Email", ["subject", "sender.name", "recipients.name"]}
|
||||
* }</pre>
|
||||
*
|
||||
* <p>The above document will be returned as:
|
||||
@@ -561,9 +535,9 @@ public final class SearchSpec {
|
||||
*/
|
||||
@NonNull
|
||||
public SearchSpec.Builder addProjection(
|
||||
@NonNull String schemaType, @NonNull String... propertyPaths) {
|
||||
@NonNull String schema, @NonNull String... propertyPaths) {
|
||||
Preconditions.checkNotNull(propertyPaths);
|
||||
return addProjection(schemaType, Arrays.asList(propertyPaths));
|
||||
return addProjection(schema, Arrays.asList(propertyPaths));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -583,16 +557,16 @@ public final class SearchSpec {
|
||||
*/
|
||||
@NonNull
|
||||
public SearchSpec.Builder addProjection(
|
||||
@NonNull String schemaType, @NonNull Collection<String> propertyPaths) {
|
||||
@NonNull String schema, @NonNull Collection<String> propertyPaths) {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
Preconditions.checkNotNull(schemaType);
|
||||
Preconditions.checkNotNull(schema);
|
||||
Preconditions.checkNotNull(propertyPaths);
|
||||
ArrayList<String> propertyPathsArrayList = new ArrayList<>(propertyPaths.size());
|
||||
for (String propertyPath : propertyPaths) {
|
||||
Preconditions.checkNotNull(propertyPath);
|
||||
propertyPathsArrayList.add(propertyPath);
|
||||
}
|
||||
mProjectionTypePropertyMasks.putStringArrayList(schemaType, propertyPathsArrayList);
|
||||
mProjectionTypePropertyMasks.putStringArrayList(schema, propertyPathsArrayList);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -608,7 +582,7 @@ public final class SearchSpec {
|
||||
throw new IllegalSearchSpecException("Missing termMatchType field.");
|
||||
}
|
||||
mBundle.putStringArrayList(NAMESPACE_FIELD, mNamespaces);
|
||||
mBundle.putStringArrayList(SCHEMA_TYPE_FIELD, mSchemaTypes);
|
||||
mBundle.putStringArrayList(SCHEMA_FIELD, mSchemas);
|
||||
mBundle.putStringArrayList(PACKAGE_NAME_FIELD, mPackageNames);
|
||||
mBundle.putBundle(PROJECTION_TYPE_PROPERTY_PATHS_FIELD, mProjectionTypePropertyMasks);
|
||||
mBuilt = true;
|
||||
|
||||
@@ -126,9 +126,9 @@ public final class SetSchemaRequest {
|
||||
* <p>Any documents of these types will be visible on system UI surfaces by default.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder addSchema(@NonNull AppSearchSchema... schemas) {
|
||||
public Builder addSchemas(@NonNull AppSearchSchema... schemas) {
|
||||
Preconditions.checkNotNull(schemas);
|
||||
return addSchema(Arrays.asList(schemas));
|
||||
return addSchemas(Arrays.asList(schemas));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -137,7 +137,7 @@ public final class SetSchemaRequest {
|
||||
* <p>Any documents of these types will be visible on system UI surfaces by default.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder addSchema(@NonNull Collection<AppSearchSchema> schemas) {
|
||||
public Builder addSchemas(@NonNull Collection<AppSearchSchema> schemas) {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
Preconditions.checkNotNull(schemas);
|
||||
mSchemas.addAll(schemas);
|
||||
|
||||
@@ -179,9 +179,9 @@ public class SetSchemaResponse {
|
||||
|
||||
/** Adds migratedTypes to the list of migrated schema types. */
|
||||
@NonNull
|
||||
public Builder addMigratedType(@NonNull String migratedType) {
|
||||
public Builder addMigratedType(@NonNull Collection<String> migratedTypes) {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
mMigratedTypes.add(Preconditions.checkNotNull(migratedType));
|
||||
mMigratedTypes.addAll(Preconditions.checkNotNull(migratedTypes));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -195,8 +195,7 @@ public final class AppSearchImpl {
|
||||
mIcingSearchEngineLocked = new IcingSearchEngine(options);
|
||||
|
||||
mVisibilityStoreLocked =
|
||||
new VisibilityStore(
|
||||
this, context, userId, globalQuerierPackage);
|
||||
new VisibilityStore(this, context, userId, globalQuerierPackage);
|
||||
|
||||
InitializeResultProto initializeResultProto = mIcingSearchEngineLocked.initialize();
|
||||
SchemaProto schemaProto;
|
||||
@@ -508,8 +507,8 @@ public final class AppSearchImpl {
|
||||
@NonNull String queryExpression,
|
||||
@NonNull SearchSpec searchSpec)
|
||||
throws AppSearchException {
|
||||
if (!searchSpec.getPackageNames().isEmpty()
|
||||
&& !searchSpec.getPackageNames().contains(packageName)) {
|
||||
List<String> filterPackageNames = searchSpec.getFilterPackageNames();
|
||||
if (!filterPackageNames.isEmpty() && !filterPackageNames.contains(packageName)) {
|
||||
// Client wanted to query over some packages that weren't its own. This isn't
|
||||
// allowed through local query so we can return early with no results.
|
||||
return new SearchResultPage(Bundle.EMPTY);
|
||||
@@ -553,7 +552,7 @@ public final class AppSearchImpl {
|
||||
throws AppSearchException {
|
||||
mReadWriteLock.readLock().lock();
|
||||
try {
|
||||
Set<String> packageFilters = new ArraySet<>(searchSpec.getPackageNames());
|
||||
Set<String> packageFilters = new ArraySet<>(searchSpec.getFilterPackageNames());
|
||||
Set<String> prefixFilters = new ArraySet<>();
|
||||
Set<String> allPrefixes = mNamespaceMapLocked.keySet();
|
||||
if (packageFilters.isEmpty()) {
|
||||
@@ -573,7 +572,7 @@ public final class AppSearchImpl {
|
||||
|
||||
// Find which schemas the client is allowed to query over.
|
||||
Set<String> allowedPrefixedSchemas = new ArraySet<>();
|
||||
List<String> schemaFilters = searchSpec.getSchemaTypes();
|
||||
List<String> schemaFilters = searchSpec.getFilterSchemas();
|
||||
for (String prefix : prefixFilters) {
|
||||
String packageName = getPackageName(prefix);
|
||||
|
||||
@@ -752,8 +751,8 @@ public final class AppSearchImpl {
|
||||
@NonNull String queryExpression,
|
||||
@NonNull SearchSpec searchSpec)
|
||||
throws AppSearchException {
|
||||
if (!searchSpec.getPackageNames().isEmpty()
|
||||
&& !searchSpec.getPackageNames().contains(packageName)) {
|
||||
List<String> filterPackageNames = searchSpec.getFilterPackageNames();
|
||||
if (!filterPackageNames.isEmpty() && !filterPackageNames.contains(packageName)) {
|
||||
// We're only removing documents within the parameter `packageName`. If we're not
|
||||
// restricting our remove-query to this package name, then there's nothing for us to
|
||||
// remove.
|
||||
@@ -1085,7 +1084,7 @@ public final class AppSearchImpl {
|
||||
Set<String> allowedPrefixedSchemas = new ArraySet<>();
|
||||
|
||||
// Add all the schema filters the client specified.
|
||||
List<String> schemaFilters = searchSpec.getSchemaTypes();
|
||||
List<String> schemaFilters = searchSpec.getFilterSchemas();
|
||||
for (int i = 0; i < schemaFilters.size(); i++) {
|
||||
allowedPrefixedSchemas.add(prefix + schemaFilters.get(i));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright 2021 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 com.android.server.appsearch.external.localstorage;
|
||||
|
||||
import static android.app.appsearch.AppSearchResult.throwableToFailedResult;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.app.appsearch.AppSearchBatchResult;
|
||||
import android.app.appsearch.AppSearchMigrationHelper;
|
||||
import android.app.appsearch.GenericDocument;
|
||||
import android.app.appsearch.SearchResultPage;
|
||||
import android.app.appsearch.SearchSpec;
|
||||
import android.app.appsearch.SetSchemaResponse;
|
||||
import android.app.appsearch.exceptions.AppSearchException;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import com.google.protobuf.CodedInputStream;
|
||||
import com.google.protobuf.CodedOutputStream;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* An implementation of {@link AppSearchMigrationHelper} which query document and save post-migrated
|
||||
* documents to locally in the app's storage space.
|
||||
*/
|
||||
class AppSearchMigrationHelperImpl implements AppSearchMigrationHelper {
|
||||
private final AppSearchImpl mAppSearchImpl;
|
||||
private final String mPackageName;
|
||||
private final String mDatabaseName;
|
||||
private final File mFile;
|
||||
private final Map<String, Integer> mCurrentVersionMap;
|
||||
private final Map<String, Integer> mFinalVersionMap;
|
||||
|
||||
AppSearchMigrationHelperImpl(
|
||||
@NonNull AppSearchImpl appSearchImpl,
|
||||
@NonNull Map<String, Integer> currentVersionMap,
|
||||
@NonNull Map<String, Integer> finalVersionMap,
|
||||
@NonNull String packageName,
|
||||
@NonNull String databaseName)
|
||||
throws IOException {
|
||||
mAppSearchImpl = Preconditions.checkNotNull(appSearchImpl);
|
||||
mCurrentVersionMap = Preconditions.checkNotNull(currentVersionMap);
|
||||
mFinalVersionMap = Preconditions.checkNotNull(finalVersionMap);
|
||||
mPackageName = Preconditions.checkNotNull(packageName);
|
||||
mDatabaseName = Preconditions.checkNotNull(databaseName);
|
||||
mFile = File.createTempFile(/*prefix=*/ "appsearch", /*suffix=*/ null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queryAndTransform(
|
||||
@NonNull String schemaType, @NonNull AppSearchMigrationHelper.Transformer migrator)
|
||||
throws Exception {
|
||||
Preconditions.checkState(mFile.exists(), "Internal temp file does not exist.");
|
||||
int currentVersion = mCurrentVersionMap.get(schemaType);
|
||||
int finalVersion = mFinalVersionMap.get(schemaType);
|
||||
try (FileOutputStream outputStream = new FileOutputStream(mFile)) {
|
||||
// TODO(b/151178558) change the output stream so that we can use it in platform
|
||||
CodedOutputStream codedOutputStream = CodedOutputStream.newInstance(outputStream);
|
||||
SearchResultPage searchResultPage =
|
||||
mAppSearchImpl.query(
|
||||
mPackageName,
|
||||
mDatabaseName,
|
||||
/*queryExpression=*/ "",
|
||||
new SearchSpec.Builder()
|
||||
.addFilterSchemas(schemaType)
|
||||
.setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
|
||||
.build());
|
||||
while (!searchResultPage.getResults().isEmpty()) {
|
||||
for (int i = 0; i < searchResultPage.getResults().size(); i++) {
|
||||
GenericDocument newDocument =
|
||||
migrator.transform(
|
||||
currentVersion,
|
||||
finalVersion,
|
||||
searchResultPage.getResults().get(i).getDocument());
|
||||
Bundle bundle = newDocument.getBundle();
|
||||
Parcel parcel = Parcel.obtain();
|
||||
parcel.writeBundle(bundle);
|
||||
byte[] serializedMessage = parcel.marshall();
|
||||
parcel.recycle();
|
||||
codedOutputStream.writeByteArrayNoTag(serializedMessage);
|
||||
}
|
||||
codedOutputStream.flush();
|
||||
searchResultPage = mAppSearchImpl.getNextPage(searchResultPage.getNextPageToken());
|
||||
outputStream.flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads {@link GenericDocument} from the temperate file and saves them to AppSearch.
|
||||
*
|
||||
* <p>This method should be only called once.
|
||||
*
|
||||
* @return the {@link AppSearchBatchResult} for migration documents.
|
||||
*/
|
||||
@NonNull
|
||||
public SetSchemaResponse readAndPutDocuments(SetSchemaResponse.Builder responseBuilder)
|
||||
throws IOException, AppSearchException {
|
||||
Preconditions.checkState(mFile.exists(), "Internal temp file does not exist.");
|
||||
try (InputStream inputStream = new FileInputStream(mFile)) {
|
||||
CodedInputStream codedInputStream = CodedInputStream.newInstance(inputStream);
|
||||
while (!codedInputStream.isAtEnd()) {
|
||||
GenericDocument document = readDocumentFromInputStream(codedInputStream);
|
||||
try {
|
||||
mAppSearchImpl.putDocument(mPackageName, mDatabaseName, document);
|
||||
} catch (Throwable t) {
|
||||
responseBuilder.setFailure(
|
||||
document.getSchemaType(),
|
||||
document.getNamespace(),
|
||||
document.getUri(),
|
||||
throwableToFailedResult(t));
|
||||
}
|
||||
}
|
||||
mAppSearchImpl.persistToDisk();
|
||||
return responseBuilder.build();
|
||||
} finally {
|
||||
mFile.delete();
|
||||
}
|
||||
}
|
||||
|
||||
void deleteTempFile() {
|
||||
mFile.delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads {@link GenericDocument} from given {@link CodedInputStream}.
|
||||
*
|
||||
* @param codedInputStream The codedInputStream to read from
|
||||
* @throws IOException on File operation error.
|
||||
*/
|
||||
@NonNull
|
||||
private static GenericDocument readDocumentFromInputStream(
|
||||
@NonNull CodedInputStream codedInputStream) throws IOException {
|
||||
byte[] serializedMessage = codedInputStream.readByteArray();
|
||||
|
||||
Parcel parcel = Parcel.obtain();
|
||||
parcel.unmarshall(serializedMessage, 0, serializedMessage.length);
|
||||
parcel.setDataPosition(0);
|
||||
Bundle bundle = parcel.readBundle();
|
||||
parcel.recycle();
|
||||
|
||||
return new GenericDocument(bundle);
|
||||
}
|
||||
}
|
||||
@@ -40,8 +40,8 @@ public final class SearchSpecToProtoConverter {
|
||||
Preconditions.checkNotNull(spec);
|
||||
SearchSpecProto.Builder protoBuilder =
|
||||
SearchSpecProto.newBuilder()
|
||||
.addAllSchemaTypeFilters(spec.getSchemaTypes())
|
||||
.addAllNamespaceFilters(spec.getNamespaces());
|
||||
.addAllSchemaTypeFilters(spec.getFilterSchemas())
|
||||
.addAllNamespaceFilters(spec.getFilterNamespaces());
|
||||
|
||||
@SearchSpec.TermMatch int termMatchCode = spec.getTermMatch();
|
||||
TermMatchType.Code termMatchCodeProto = TermMatchType.Code.forNumber(termMatchCode);
|
||||
|
||||
@@ -1 +1 @@
|
||||
I3fd4c96bf775c2539d744c416cdbf1d3c9544f03
|
||||
Ibe06fb9c574c8718191f833bb042fa10c300e4e2
|
||||
|
||||
@@ -102,10 +102,10 @@ public class AppSearchSessionShimImpl implements AppSearchSessionShim {
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public ListenableFuture<AppSearchBatchResult<String, Void>> putDocuments(
|
||||
public ListenableFuture<AppSearchBatchResult<String, Void>> put(
|
||||
@NonNull PutDocumentsRequest request) {
|
||||
SettableFuture<AppSearchBatchResult<String, Void>> future = SettableFuture.create();
|
||||
mAppSearchSession.putDocuments(
|
||||
mAppSearchSession.put(
|
||||
request, mExecutor, new BatchResultCallbackAdapter<>(future));
|
||||
return future;
|
||||
}
|
||||
@@ -122,10 +122,10 @@ public class AppSearchSessionShimImpl implements AppSearchSessionShim {
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public SearchResultsShim query(
|
||||
public SearchResultsShim search(
|
||||
@NonNull String queryExpression, @NonNull SearchSpec searchSpec) {
|
||||
SearchResults searchResults =
|
||||
mAppSearchSession.query(queryExpression, searchSpec, mExecutor);
|
||||
mAppSearchSession.search(queryExpression, searchSpec, mExecutor);
|
||||
return new SearchResultsShimImpl(searchResults, mExecutor);
|
||||
}
|
||||
|
||||
@@ -139,19 +139,19 @@ public class AppSearchSessionShimImpl implements AppSearchSessionShim {
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public ListenableFuture<AppSearchBatchResult<String, Void>> removeByUri(
|
||||
public ListenableFuture<AppSearchBatchResult<String, Void>> remove(
|
||||
@NonNull RemoveByUriRequest request) {
|
||||
SettableFuture<AppSearchBatchResult<String, Void>> future = SettableFuture.create();
|
||||
mAppSearchSession.removeByUri(request, mExecutor, new BatchResultCallbackAdapter<>(future));
|
||||
mAppSearchSession.remove(request, mExecutor, new BatchResultCallbackAdapter<>(future));
|
||||
return future;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public ListenableFuture<Void> removeByQuery(
|
||||
public ListenableFuture<Void> remove(
|
||||
@NonNull String queryExpression, @NonNull SearchSpec searchSpec) {
|
||||
SettableFuture<AppSearchResult<Void>> future = SettableFuture.create();
|
||||
mAppSearchSession.removeByQuery(queryExpression, searchSpec, mExecutor, future::set);
|
||||
mAppSearchSession.remove(queryExpression, searchSpec, mExecutor, future::set);
|
||||
return Futures.transformAsync(future, this::transformResult, mExecutor);
|
||||
}
|
||||
|
||||
|
||||
@@ -67,10 +67,10 @@ public class GlobalSearchSessionShimImpl implements GlobalSearchSessionShim {
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public SearchResultsShim query(
|
||||
public SearchResultsShim search(
|
||||
@NonNull String queryExpression, @NonNull SearchSpec searchSpec) {
|
||||
SearchResults searchResults =
|
||||
mGlobalSearchSession.query(queryExpression, searchSpec, mExecutor);
|
||||
mGlobalSearchSession.search(queryExpression, searchSpec, mExecutor);
|
||||
return new SearchResultsShimImpl(searchResults, mExecutor);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ import java.util.Set;
|
||||
public interface AppSearchSessionShim extends Closeable {
|
||||
|
||||
/**
|
||||
* Sets the schema that will be used by documents provided to the {@link #putDocuments} method.
|
||||
* Sets the schema that will be used by documents provided to the {@link #put} method.
|
||||
*
|
||||
* <p>The schema provided here is compared to the stored copy of the schema previously supplied
|
||||
* to {@link #setSchema}, if any, to determine how to treat existing documents. The following
|
||||
@@ -143,8 +143,7 @@ public interface AppSearchSessionShim extends Closeable {
|
||||
* they were successfully indexed, or a failed {@link AppSearchResult} otherwise.
|
||||
*/
|
||||
@NonNull
|
||||
ListenableFuture<AppSearchBatchResult<String, Void>> putDocuments(
|
||||
@NonNull PutDocumentsRequest request);
|
||||
ListenableFuture<AppSearchBatchResult<String, Void>> put(@NonNull PutDocumentsRequest request);
|
||||
|
||||
/**
|
||||
* Retrieves {@link GenericDocument}s by URI.
|
||||
@@ -161,7 +160,7 @@ public interface AppSearchSessionShim extends Closeable {
|
||||
@NonNull GetByUriRequest request);
|
||||
|
||||
/**
|
||||
* Searches a document based on a given query string.
|
||||
* Searches for documents based on a given query string.
|
||||
*
|
||||
* <p>Currently we support following features in the raw query format:
|
||||
*
|
||||
@@ -200,7 +199,7 @@ public interface AppSearchSessionShim extends Closeable {
|
||||
* @return The search result of performing this operation.
|
||||
*/
|
||||
@NonNull
|
||||
SearchResultsShim query(@NonNull String queryExpression, @NonNull SearchSpec searchSpec);
|
||||
SearchResultsShim search(@NonNull String queryExpression, @NonNull SearchSpec searchSpec);
|
||||
|
||||
/**
|
||||
* Reports usage of a particular document by URI and namespace.
|
||||
@@ -208,7 +207,7 @@ public interface AppSearchSessionShim extends Closeable {
|
||||
* <p>A usage report represents an event in which a user interacted with or viewed a document.
|
||||
*
|
||||
* <p>For each call to {@link #reportUsage}, AppSearch updates usage count and usage recency
|
||||
* metrics for that particular document. These metrics are used for ordering {@link #query}
|
||||
* metrics for that particular document. These metrics are used for ordering {@link #search}
|
||||
* results by the {@link SearchSpec#RANKING_STRATEGY_USAGE_COUNT} and {@link
|
||||
* SearchSpec#RANKING_STRATEGY_USAGE_LAST_USED_TIMESTAMP} ranking strategies.
|
||||
*
|
||||
@@ -231,13 +230,13 @@ public interface AppSearchSessionShim extends Closeable {
|
||||
* {@link AppSearchResult} with a result code of {@link AppSearchResult#RESULT_NOT_FOUND}.
|
||||
*/
|
||||
@NonNull
|
||||
ListenableFuture<AppSearchBatchResult<String, Void>> removeByUri(
|
||||
ListenableFuture<AppSearchBatchResult<String, Void>> remove(
|
||||
@NonNull RemoveByUriRequest request);
|
||||
|
||||
/**
|
||||
* Removes {@link GenericDocument}s from the index by Query. Documents will be removed if they
|
||||
* match the {@code queryExpression} in given namespaces and schemaTypes which is set via {@link
|
||||
* SearchSpec.Builder#addNamespace} and {@link SearchSpec.Builder#addSchemaType}.
|
||||
* SearchSpec.Builder#addFilterNamespaces} and {@link SearchSpec.Builder#addFilterSchemas}.
|
||||
*
|
||||
* <p>An empty {@code queryExpression} matches all documents.
|
||||
*
|
||||
@@ -251,8 +250,7 @@ public interface AppSearchSessionShim extends Closeable {
|
||||
* @return The pending result of performing this operation.
|
||||
*/
|
||||
@NonNull
|
||||
ListenableFuture<Void> removeByQuery(
|
||||
@NonNull String queryExpression, @NonNull SearchSpec searchSpec);
|
||||
ListenableFuture<Void> remove(@NonNull String queryExpression, @NonNull SearchSpec searchSpec);
|
||||
|
||||
/**
|
||||
* Flush all schema and document updates, additions, and deletes to disk if possible.
|
||||
|
||||
@@ -23,7 +23,7 @@ import java.io.Closeable;
|
||||
/**
|
||||
* This class provides global access to the centralized AppSearch index maintained by the system.
|
||||
*
|
||||
* <p>Apps can retrieve indexed documents through the query API.
|
||||
* <p>Apps can retrieve indexed documents through the {@link #search} API.
|
||||
*/
|
||||
public interface GlobalSearchSessionShim extends Closeable {
|
||||
/**
|
||||
@@ -66,7 +66,7 @@ public interface GlobalSearchSessionShim extends Closeable {
|
||||
* @return The search result of performing this operation.
|
||||
*/
|
||||
@NonNull
|
||||
SearchResultsShim query(@NonNull String queryExpression, @NonNull SearchSpec searchSpec);
|
||||
SearchResultsShim search(@NonNull String queryExpression, @NonNull SearchSpec searchSpec);
|
||||
|
||||
/** Closes the {@link GlobalSearchSessionShim}. */
|
||||
@Override
|
||||
|
||||
65
core/tests/coretests/src/android/app/appsearch/external/app/GenericDocumentTest.java
vendored
Normal file
65
core/tests/coretests/src/android/app/appsearch/external/app/GenericDocumentTest.java
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class GenericDocumentTest {
|
||||
@Test
|
||||
public void testRecreateFromParcel() {
|
||||
GenericDocument inDoc =
|
||||
new GenericDocument.Builder<>("uri1", "schema1")
|
||||
.setScore(42)
|
||||
.setPropertyString("propString", "Hello")
|
||||
.setPropertyBytes("propBytes", new byte[][] {{1, 2}})
|
||||
.setPropertyDocument(
|
||||
"propDocument",
|
||||
new GenericDocument.Builder<>("uri2", "schema2")
|
||||
.setPropertyString("propString", "Goodbye")
|
||||
.setPropertyBytes("propBytes", new byte[][] {{3, 4}})
|
||||
.build())
|
||||
.build();
|
||||
|
||||
// Serialize the document
|
||||
Parcel inParcel = Parcel.obtain();
|
||||
inParcel.writeBundle(inDoc.getBundle());
|
||||
byte[] data = inParcel.marshall();
|
||||
inParcel.recycle();
|
||||
|
||||
// Deserialize the document
|
||||
Parcel outParcel = Parcel.obtain();
|
||||
outParcel.unmarshall(data, 0, data.length);
|
||||
outParcel.setDataPosition(0);
|
||||
Bundle outBundle = outParcel.readBundle();
|
||||
outParcel.recycle();
|
||||
|
||||
// Compare results
|
||||
GenericDocument outDoc = new GenericDocument(outBundle);
|
||||
assertThat(inDoc).isEqualTo(outDoc);
|
||||
assertThat(outDoc.getPropertyString("propString")).isEqualTo("Hello");
|
||||
assertThat(outDoc.getPropertyBytesArray("propBytes")).isEqualTo(new byte[][] {{1, 2}});
|
||||
assertThat(outDoc.getPropertyDocument("propDocument").getPropertyString("propString"))
|
||||
.isEqualTo("Goodbye");
|
||||
assertThat(outDoc.getPropertyDocument("propDocument").getPropertyBytesArray("propBytes"))
|
||||
.isEqualTo(new byte[][] {{3, 4}});
|
||||
}
|
||||
}
|
||||
@@ -34,9 +34,9 @@ public class PutDocumentsRequestTest {
|
||||
new AppSearchEmail.Builder("test1").build(),
|
||||
new AppSearchEmail.Builder("test2").build());
|
||||
PutDocumentsRequest request =
|
||||
new PutDocumentsRequest.Builder().addGenericDocument(emails).build();
|
||||
new PutDocumentsRequest.Builder().addGenericDocuments(emails).build();
|
||||
|
||||
assertThat(request.getDocuments().get(0).getUri()).isEqualTo("test1");
|
||||
assertThat(request.getDocuments().get(1).getUri()).isEqualTo("test2");
|
||||
assertThat(request.getGenericDocuments().get(0).getUri()).isEqualTo("test1");
|
||||
assertThat(request.getGenericDocuments().get(1).getUri()).isEqualTo("test2");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@ public class SearchSpecTest {
|
||||
SearchSpec searchSpec =
|
||||
new SearchSpec.Builder()
|
||||
.setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
|
||||
.addNamespace("namespace1", "namespace2")
|
||||
.addSchemaType("schemaTypes1", "schemaTypes2")
|
||||
.addFilterNamespaces("namespace1", "namespace2")
|
||||
.addFilterSchemas("schemaTypes1", "schemaTypes2")
|
||||
.addFilterPackageNames("package1", "package2")
|
||||
.setSnippetCount(5)
|
||||
.setSnippetCountPerProperty(10)
|
||||
@@ -49,7 +49,7 @@ public class SearchSpecTest {
|
||||
.isEqualTo(SearchSpec.TERM_MATCH_PREFIX);
|
||||
assertThat(bundle.getStringArrayList(SearchSpec.NAMESPACE_FIELD))
|
||||
.containsExactly("namespace1", "namespace2");
|
||||
assertThat(bundle.getStringArrayList(SearchSpec.SCHEMA_TYPE_FIELD))
|
||||
assertThat(bundle.getStringArrayList(SearchSpec.SCHEMA_FIELD))
|
||||
.containsExactly("schemaTypes1", "schemaTypes2");
|
||||
assertThat(bundle.getStringArrayList(SearchSpec.PACKAGE_NAME_FIELD))
|
||||
.containsExactly("package1", "package2");
|
||||
|
||||
@@ -75,12 +75,12 @@ public class SetSchemaRequestTest {
|
||||
AppSearchSchema schema = new AppSearchSchema.Builder("Schema").build();
|
||||
|
||||
// By default, the schema is visible.
|
||||
SetSchemaRequest request = new SetSchemaRequest.Builder().addSchema(schema).build();
|
||||
SetSchemaRequest request = new SetSchemaRequest.Builder().addSchemas(schema).build();
|
||||
assertThat(request.getSchemasNotVisibleToSystemUi()).isEmpty();
|
||||
|
||||
request =
|
||||
new SetSchemaRequest.Builder()
|
||||
.addSchema(schema)
|
||||
.addSchemas(schema)
|
||||
.setSchemaTypeVisibilityForSystemUi("Schema", true)
|
||||
.build();
|
||||
assertThat(request.getSchemasNotVisibleToSystemUi()).isEmpty();
|
||||
@@ -91,7 +91,7 @@ public class SetSchemaRequestTest {
|
||||
AppSearchSchema schema = new AppSearchSchema.Builder("Schema").build();
|
||||
SetSchemaRequest request =
|
||||
new SetSchemaRequest.Builder()
|
||||
.addSchema(schema)
|
||||
.addSchemas(schema)
|
||||
.setSchemaTypeVisibilityForSystemUi("Schema", false)
|
||||
.build();
|
||||
assertThat(request.getSchemasNotVisibleToSystemUi()).containsExactly("Schema");
|
||||
@@ -102,7 +102,7 @@ public class SetSchemaRequestTest {
|
||||
AppSearchSchema schema = new AppSearchSchema.Builder("Schema").build();
|
||||
|
||||
// By default, the schema is not visible.
|
||||
SetSchemaRequest request = new SetSchemaRequest.Builder().addSchema(schema).build();
|
||||
SetSchemaRequest request = new SetSchemaRequest.Builder().addSchemas(schema).build();
|
||||
assertThat(request.getSchemasVisibleToPackages()).isEmpty();
|
||||
|
||||
PackageIdentifier packageIdentifier =
|
||||
@@ -112,7 +112,7 @@ public class SetSchemaRequestTest {
|
||||
|
||||
request =
|
||||
new SetSchemaRequest.Builder()
|
||||
.addSchema(schema)
|
||||
.addSchemas(schema)
|
||||
.setSchemaTypeVisibilityForPackage(
|
||||
"Schema", /*visible=*/ true, packageIdentifier)
|
||||
.build();
|
||||
@@ -126,7 +126,7 @@ public class SetSchemaRequestTest {
|
||||
|
||||
SetSchemaRequest request =
|
||||
new SetSchemaRequest.Builder()
|
||||
.addSchema(schema)
|
||||
.addSchemas(schema)
|
||||
.setSchemaTypeVisibilityForPackage(
|
||||
"Schema",
|
||||
/*visible=*/ false,
|
||||
@@ -147,7 +147,7 @@ public class SetSchemaRequestTest {
|
||||
|
||||
SetSchemaRequest request =
|
||||
new SetSchemaRequest.Builder()
|
||||
.addSchema(schema)
|
||||
.addSchemas(schema)
|
||||
// Set it visible for "Schema"
|
||||
.setSchemaTypeVisibilityForPackage(
|
||||
"Schema", /*visible=*/ true, packageIdentifier)
|
||||
@@ -165,7 +165,7 @@ public class SetSchemaRequestTest {
|
||||
|
||||
SetSchemaRequest request =
|
||||
new SetSchemaRequest.Builder()
|
||||
.addSchema(schema)
|
||||
.addSchemas(schema)
|
||||
// First set it as visible
|
||||
.setSchemaTypeVisibilityForPackage(
|
||||
"Schema",
|
||||
|
||||
@@ -700,14 +700,14 @@ public class AppSearchImplTest {
|
||||
public void testRemoveEmptyDatabase_noExceptionThrown() throws Exception {
|
||||
SearchSpec searchSpec =
|
||||
new SearchSpec.Builder()
|
||||
.addSchemaType("FakeType")
|
||||
.addFilterSchemas("FakeType")
|
||||
.setTermMatch(TermMatchType.Code.PREFIX_VALUE)
|
||||
.build();
|
||||
mAppSearchImpl.removeByQuery("package", "EmptyDatabase", "", searchSpec);
|
||||
|
||||
searchSpec =
|
||||
new SearchSpec.Builder()
|
||||
.addNamespace("FakeNamespace")
|
||||
.addFilterNamespaces("FakeNamespace")
|
||||
.setTermMatch(TermMatchType.Code.PREFIX_VALUE)
|
||||
.build();
|
||||
mAppSearchImpl.removeByQuery("package", "EmptyDatabase", "", searchSpec);
|
||||
|
||||
Reference in New Issue
Block a user