Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cfba1031 authored by Terry Wang's avatar Terry Wang
Browse files

Delete depracated method in AppSearchManager.

Test: presubmit
Bug: 162450968
Change-Id: I423e3a25bb986ca6cc0a87c74ce97becb59ed25b
parent b28ad521
Loading
Loading
Loading
Loading
+0 −349
Original line number Diff line number Diff line
@@ -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);
        }
    }
}