Merge "Delete depracated method in AppSearchManager." into sc-dev

This commit is contained in:
Terry Wang
2021-03-12 00:00:37 +00:00
committed by Android (Google) Code Review

View File

@@ -19,19 +19,10 @@ import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.SystemService;
import android.content.Context;
import android.os.Bundle;
import android.os.ParcelableException;
import android.os.RemoteException;
import com.android.internal.infra.AndroidFuture;
import com.android.internal.util.Preconditions;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
@@ -246,349 +237,9 @@ public class AppSearchManager {
mService, mContext.getUserId(), getPackageName(), executor, callback);
}
/**
* Sets the schema being used by documents provided to the {@link #putDocuments} 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
* types of schema modifications are always safe and are made without deleting any existing
* documents:
*
* <ul>
* <li>Addition of new types
* <li>Addition of new {@link
* android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL OPTIONAL} or
* {@link android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_REPEATED
* REPEATED} properties to a type
* <li>Changing the cardinality of a data type to be less restrictive (e.g. changing an {@link
* android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL OPTIONAL}
* property into a {@link
* android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_REPEATED REPEATED}
* property.
* </ul>
*
* <p>The following types of schema changes are not backwards-compatible:
*
* <ul>
* <li>Removal of an existing type
* <li>Removal of a property from a type
* <li>Changing the data type ({@code boolean}, {@code long}, etc.) of an existing property
* <li>For properties of {@code GenericDocument} type, changing the schema type of {@code
* GenericDocument}s of that property
* <li>Changing the cardinality of a data type to be more restrictive (e.g. changing an {@link
* android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL OPTIONAL}
* property into a {@link
* android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_REQUIRED REQUIRED}
* property).
* <li>Adding a {@link
* android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_REQUIRED REQUIRED}
* property.
* </ul>
*
* <p>Supplying a schema with such changes will result in this call returning an {@link
* AppSearchResult} with a code of {@link AppSearchResult#RESULT_INVALID_SCHEMA} and an error
* message describing the incompatibility. In this case the previously set schema will remain
* active.
*
* <p>If you need to make non-backwards-compatible changes as described above, instead use the
* {@link #setSchema(List, boolean)} method with the {@code forceOverride} parameter set to
* {@code true}.
*
* <p>It is a no-op to set the same schema as has been previously set; this is handled
* efficiently.
*
* @param request The schema update request.
* @return the result of performing this operation.
* @hide
* @deprecated use {@link AppSearchSession#setSchema} instead.
*/
@NonNull
public AppSearchResult<Void> setSchema(@NonNull SetSchemaRequest request) {
Preconditions.checkNotNull(request);
// TODO: This should use com.android.internal.infra.RemoteStream or another mechanism to
// avoid binder limits.
List<Bundle> schemaBundles = new ArrayList<>(request.getSchemas().size());
for (AppSearchSchema schema : request.getSchemas()) {
schemaBundles.add(schema.getBundle());
}
AndroidFuture<AppSearchResult> future = new AndroidFuture<>();
try {
mService.setSchema(
getPackageName(),
DEFAULT_DATABASE_NAME,
schemaBundles,
new ArrayList<>(request.getSchemasNotDisplayedBySystem()),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
request.isForceOverride(),
mContext.getUserId(),
new IAppSearchResultCallback.Stub() {
public void onResult(AppSearchResult result) {
future.complete(result);
}
});
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
return getFutureOrThrow(future);
}
/**
* Index {@link GenericDocument}s into AppSearch.
*
* <p>You should not call this method directly; instead, use the {@code
* AppSearch#putDocuments()} API provided by JetPack.
*
* <p>Each {@link GenericDocument}'s {@code schemaType} field must be set to the name of a
* schema type previously registered via the {@link #setSchema} method.
*
* @param request {@link PutDocumentsRequest} containing documents to be indexed
* @return The pending result of performing this operation. The keys of the returned {@link
* AppSearchBatchResult} are the URIs of the input documents. The values are {@code null} if
* they were successfully indexed, or a failed {@link AppSearchResult} otherwise.
* @throws RuntimeException If an error occurred during the execution.
* @hide
* @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.getGenericDocuments();
List<Bundle> documentBundles = new ArrayList<>(documents.size());
for (int i = 0; i < documents.size(); i++) {
documentBundles.add(documents.get(i).getBundle());
}
AndroidFuture<AppSearchBatchResult> future = new AndroidFuture<>();
try {
mService.putDocuments(
getPackageName(),
DEFAULT_DATABASE_NAME,
documentBundles,
mContext.getUserId(),
new IAppSearchBatchResultCallback.Stub() {
public void onResult(AppSearchBatchResult result) {
future.complete(result);
}
public void onSystemError(ParcelableException exception) {
future.completeExceptionally(exception);
}
});
} catch (RemoteException e) {
future.completeExceptionally(e);
}
return getFutureOrThrow(future);
}
/**
* Retrieves {@link GenericDocument}s by URI.
*
* <p>You should not call this method directly; instead, use the {@code
* AppSearch#getDocuments()} API provided by JetPack.
*
* @param request {@link GetByUriRequest} containing URIs to be retrieved.
* @return The pending result of performing this operation. The keys of the returned {@link
* AppSearchBatchResult} are the input URIs. The values are the returned {@link
* GenericDocument}s 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}.
* @throws RuntimeException If an error occurred during the execution.
* @hide
* @deprecated use {@link AppSearchSession#getByUri} instead.
*/
public AppSearchBatchResult<String, GenericDocument> getByUri(
@NonNull GetByUriRequest request) {
// TODO(b/146386470): Transmit the result documents as a RemoteStream instead of sending
// them in one big list.
List<String> uris = new ArrayList<>(request.getUris());
AndroidFuture<AppSearchBatchResult> future = new AndroidFuture<>();
try {
mService.getDocuments(
getPackageName(),
DEFAULT_DATABASE_NAME,
request.getNamespace(),
uris,
request.getProjectionsInternal(),
mContext.getUserId(),
new IAppSearchBatchResultCallback.Stub() {
public void onResult(AppSearchBatchResult result) {
future.complete(result);
}
public void onSystemError(ParcelableException exception) {
future.completeExceptionally(exception);
}
});
} catch (RemoteException e) {
future.completeExceptionally(e);
}
// Translate from document bundles to GenericDocument instances
AppSearchBatchResult<String, Bundle> bundleResult = getFutureOrThrow(future);
AppSearchBatchResult.Builder<String, GenericDocument> documentResultBuilder =
new AppSearchBatchResult.Builder<>();
// Translate successful results
for (Map.Entry<String, Bundle> bundleEntry : bundleResult.getSuccesses().entrySet()) {
GenericDocument document;
try {
document = new GenericDocument(bundleEntry.getValue());
} catch (Throwable t) {
// These documents went through validation, so how could this fail? We must have
// done something wrong.
documentResultBuilder.setFailure(
bundleEntry.getKey(),
AppSearchResult.RESULT_INTERNAL_ERROR,
t.getMessage());
continue;
}
documentResultBuilder.setSuccess(bundleEntry.getKey(), document);
}
// Translate failed results
for (Map.Entry<String, AppSearchResult<Bundle>> bundleEntry :
bundleResult.getFailures().entrySet()) {
documentResultBuilder.setFailure(
bundleEntry.getKey(),
bundleEntry.getValue().getResultCode(),
bundleEntry.getValue().getErrorMessage());
}
return documentResultBuilder.build();
}
/**
* Searches a document based on a given query string.
*
* <p>You should not call this method directly; instead, use the {@code AppSearch#query()} API
* provided by JetPack.
*
* <p>Currently we support following features in the raw query format:
*
* <ul>
* <li>AND
* <p>AND joins (e.g. “match documents that have both the terms ‘dog’ and ‘cat’”).
* Example: hello world matches documents that have both ‘hello’ and ‘world’
* <li>OR
* <p>OR joins (e.g. “match documents that have either the term ‘dog’ or ‘cat’”). Example:
* dog OR puppy
* <li>Exclusion
* <p>Exclude a term (e.g. “match documents that do not have the term ‘dog’”). Example:
* -dog excludes the term ‘dog’
* <li>Grouping terms
* <p>Allow for conceptual grouping of subqueries to enable hierarchical structures (e.g.
* “match documents that have either ‘dog’ or ‘puppy’, and either ‘cat’ or ‘kitten’”).
* Example: (dog puppy) (cat kitten) two one group containing two terms.
* <li>Property restricts
* <p>Specifies which properties of a document to specifically match terms in (e.g. “match
* documents where the ‘subject’ property contains ‘important’”). Example:
* subject:important matches documents with the term ‘important’ in the ‘subject’ property
* <li>Schema type restricts
* <p>This is similar to property restricts, but allows for restricts on top-level
* document fields, such as schema_type. Clients should be able to limit their query to
* documents of a certain schema_type (e.g. “match documents that are of the ‘Email’
* schema_type”). Example: { schema_type_filters: “Email”, “Video”,query: “dog” } will
* match documents that contain the query term ‘dog’ and are of either the ‘Email’ schema
* type or the ‘Video’ schema type.
* </ul>
*
* @param queryExpression Query String to search.
* @param searchSpec Spec for setting filters, raw query etc.
* @throws RuntimeException If an error occurred during the execution.
* @hide
* @deprecated use AppSearchSession#query instead.
*/
@NonNull
public AppSearchResult<List<SearchResult>> query(
@NonNull String queryExpression, @NonNull SearchSpec searchSpec) {
// TODO(b/146386470): Transmit the result documents as a RemoteStream instead of sending
// them in one big list.
AndroidFuture<AppSearchResult> future = new AndroidFuture<>();
try {
mService.query(
getPackageName(),
DEFAULT_DATABASE_NAME,
queryExpression,
searchSpec.getBundle(),
mContext.getUserId(),
new IAppSearchResultCallback.Stub() {
public void onResult(AppSearchResult result) {
future.complete(result);
}
});
AppSearchResult<Bundle> bundleResult = getFutureOrThrow(future);
if (!bundleResult.isSuccess()) {
return AppSearchResult.newFailedResult(
bundleResult.getResultCode(), bundleResult.getErrorMessage());
}
SearchResultPage searchResultPage = new SearchResultPage(bundleResult.getResultValue());
return AppSearchResult.newSuccessfulResult(searchResultPage.getResults());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
} catch (Throwable t) {
return AppSearchResult.throwableToFailedResult(t);
}
}
/**
* Removes {@link GenericDocument}s by URI.
*
* <p>You should not call this method directly; instead, use the {@code AppSearch#delete()} API
* provided by JetPack.
*
* @param request Request containing URIs to be removed.
* @return 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}.
* @throws RuntimeException If an error occurred during the execution.
* @hide
* @deprecated use {@link AppSearchSession#remove} instead.
*/
public AppSearchBatchResult<String, Void> removeByUri(@NonNull RemoveByUriRequest request) {
List<String> uris = new ArrayList<>(request.getUris());
AndroidFuture<AppSearchBatchResult> future = new AndroidFuture<>();
try {
mService.removeByUri(
getPackageName(),
DEFAULT_DATABASE_NAME,
request.getNamespace(),
uris,
mContext.getUserId(),
new IAppSearchBatchResultCallback.Stub() {
public void onResult(AppSearchBatchResult result) {
future.complete(result);
}
public void onSystemError(ParcelableException exception) {
future.completeExceptionally(exception);
}
});
} catch (RemoteException e) {
future.completeExceptionally(e);
}
return getFutureOrThrow(future);
}
/** Returns the package name that should be used for uid verification. */
@NonNull
private String getPackageName() {
return mContext.getOpPackageName();
}
private static <T> T getFutureOrThrow(@NonNull AndroidFuture<T> future) {
try {
return future.get();
} catch (Throwable e) {
if (e instanceof ExecutionException) {
e = e.getCause();
}
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
}
if (e instanceof Error) {
throw (Error) e;
}
throw new RuntimeException(e);
}
}
}