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

Commit c7597038 authored by Terry Wang's avatar Terry Wang Committed by Android (Google) Code Review
Browse files

Merge "Pull upstream changes from AndroidX."

parents 3ce8ab96 a2f580f7
Loading
Loading
Loading
Loading
+8 −40
Original line number Diff line number Diff line
@@ -267,14 +267,14 @@ public class AppSearchManager {
            searchResultsFuture.completeExceptionally(e);
        }

        // Translate the list of Bundle into a list of SearchResult
        AppSearchResult<SearchResults> searchResultsResult = getFutureOrThrow(searchResultsFuture);
        if (!searchResultsResult.isSuccess()) {
            return AppSearchResult.newFailedResult(
                    searchResultsResult.getResultCode(), searchResultsResult.getErrorMessage());
        // Translate the Bundle into a searchResultPage.
        AppSearchResult<Bundle> bundleResult = getFutureOrThrow(searchResultsFuture);
        if (!bundleResult.isSuccess()) {
            return AppSearchResult.newFailedResult(bundleResult.getResultCode(),
                    bundleResult.getErrorMessage());
        }
        SearchResults searchResults = searchResultsResult.getResultValue();
        return AppSearchResult.newSuccessfulResult(searchResults.mResults);
        SearchResultPage searchResultPage = new SearchResultPage(bundleResult.getResultValue());
        return AppSearchResult.newSuccessfulResult(searchResultPage.getResults());
    }

    /**
@@ -294,39 +294,7 @@ public class AppSearchManager {
        List<String> uris = new ArrayList<>(request.getUris());
        AndroidFuture<AppSearchBatchResult> future = new AndroidFuture<>();
        try {
            mService.delete(DEFAULT_DATABASE, request.getNamespace(), uris, future);
        } catch (RemoteException e) {
            future.completeExceptionally(e);
        }
        return getFutureOrThrow(future);
    }

    /**
     * Deletes {@link android.app.appsearch.GenericDocument}s by schema type.
     *
     * <p>You should not call this method directly; instead, use the
     * {@code AppSearch#deleteByType()} API provided by JetPack.
     *
     * @param schemaTypes Schema types whose documents to delete.
     * @return An {@link AppSearchBatchResult} mapping each schema type to a {@code null} success if
     *     deletion was successful, to a {@code null} failure if the type did not exist, or to a
     *     {@code throwable} failure if deletion failed for another reason.
     */
    public AppSearchBatchResult<String, Void> deleteByTypes(@NonNull List<String> schemaTypes) {
        AndroidFuture<AppSearchBatchResult> future = new AndroidFuture<>();
        try {
            mService.deleteByTypes(DEFAULT_DATABASE, schemaTypes, future);
        } catch (RemoteException e) {
            future.completeExceptionally(e);
        }
        return getFutureOrThrow(future);
    }

    /** Deletes all documents owned by the calling app. */
    public AppSearchResult<Void> deleteAll() {
        AndroidFuture<AppSearchResult> future = new AndroidFuture<>();
        try {
            mService.deleteAll(DEFAULT_DATABASE, future);
            mService.removeByUri(DEFAULT_DATABASE, request.getNamespace(), uris, future);
        } catch (RemoteException e) {
            future.completeExceptionally(e);
        }
+11 −24
Original line number Diff line number Diff line
@@ -92,7 +92,7 @@ interface IAppSearchManager {
        in AndroidFuture<AppSearchResult> callback);

    /**
     * Deletes documents by URI.
     * Removes documents by URI.
     *
     * @param databaseName The databaseName the document is in.
     * @param namespace    Namespace of the document to remove.
@@ -105,36 +105,23 @@ interface IAppSearchManager {
     *     where the keys are document URIs. If a document doesn't exist, it will be reported as a
     *     failure where the {@code throwable} is {@code null}.
     */
    void delete(
    void removeByUri(
        in String databaseName,
        in String namespace,
        in List<String> uris,
        in AndroidFuture<AppSearchBatchResult> callback);

    /**
     * Deletes documents by schema type.
     * Removes documents by given query.
     *
     * @param databaseName The databaseName the document is in.
     * @param schemaTypes The schema types of the documents to delete
     * @param callback
     *     {@link AndroidFuture}&lt;{@link AppSearchBatchResult}&lt;{@link String}, {@link Void}&gt;&gt;.
     *     If the call fails to start, {@code callback} will be completed exceptionally. Otherwise,
     *     {@code callback} will be completed with an
     *     {@link AppSearchBatchResult}&lt;{@link String}, {@link Void}&gt;
     *     where the keys are schema types. If a schema type doesn't exist, it will be reported as a
     *     failure where the {@code throwable} is {@code null}.
     * @param databaseName The databaseName this query for.
     * @param queryExpression String to search for
     * @param searchSpecBundle SearchSpec bundle
     * @param callback {@link AndroidFuture}&lt;{@link AppSearchResult}&lt;{@link SearchResults}&gt;&gt;
     */
    void deleteByTypes(
    void removeByQuery(
        in String databaseName,
        in List<String> schemaTypes,
        in AndroidFuture<AppSearchBatchResult> callback);

    /**
     * Deletes all documents belonging to the calling app.
     *
     * @param databaseName The databaseName to remove all documents from.
     * @param callback {@link AndroidFuture}&lt;{@link AppSearchResult}&lt;{@link Void}&gt;&gt;.
     *     Will be completed with the result of the call.
     */
    void deleteAll(in String databaseName, in AndroidFuture<AppSearchResult> callback);
        in String queryExpression,
        in Bundle searchSpecBundle,
        in AndroidFuture<AppSearchResult> callback);
}
+78 −0
Original line number Diff line number Diff line
/*
 * 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 android.os.Bundle;

import android.annotation.NonNull;
import android.annotation.Nullable;

import com.android.internal.util.Preconditions;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * This class represents a page of {@link SearchResult}s
 * @hide
 */

public class SearchResultPage {
    public static final String RESULTS_FIELD = "results";
    public static final String NEXT_PAGE_TOKEN_FIELD = "nextPageToken";
    private final long mNextPageToken;

    @Nullable
    private List<SearchResult> mResults;

    @NonNull
    private final Bundle mBundle;

    public SearchResultPage(@NonNull Bundle bundle) {
        mBundle = Preconditions.checkNotNull(bundle);
        mNextPageToken = mBundle.getLong(NEXT_PAGE_TOKEN_FIELD);
    }

    /** Returns the {@link Bundle} of this class. */
    @NonNull
    public Bundle getBundle() {
        return mBundle;
    }

    /** Returns the Token to get next {@link SearchResultPage}. */
    public long getNextPageToken() {
        return mNextPageToken;
    }

    /** Returns all {@link android.app.appsearch.SearchResult}s of this page */
    @NonNull
    public List<SearchResult> getResults() {
        if (mResults == null) {
            ArrayList<Bundle> resultBundles = mBundle.getParcelableArrayList(RESULTS_FIELD);
            if (resultBundles == null) {
                mResults = Collections.emptyList();
            } else {
                mResults = new ArrayList<>(resultBundles.size());
                for (int i = 0; i < resultBundles.size(); i++) {
                    mResults.add(new SearchResult(resultBundles.get(i)));
                }
            }
        }
        return mResults;
    }
}
+32 −84
Original line number Diff line number Diff line
@@ -21,33 +21,23 @@ import android.app.appsearch.AppSearchResult;
import android.app.appsearch.AppSearchSchema;
import android.app.appsearch.GenericDocument;
import android.app.appsearch.IAppSearchManager;
import android.app.appsearch.SearchResult;
import android.app.appsearch.SearchResults;
import android.app.appsearch.SearchResultPage;
import android.app.appsearch.SearchSpec;
import android.app.appsearch.exceptions.AppSearchException;
import android.content.Context;
import android.os.Binder;
import android.os.Bundle;
import android.os.UserHandle;
import android.util.ArraySet;

import com.android.internal.infra.AndroidFuture;
import com.android.internal.util.Preconditions;
import com.android.server.SystemService;
import com.android.server.appsearch.external.localstorage.AppSearchImpl;
import com.android.server.appsearch.external.localstorage.converter.GenericDocumentToProtoConverter;
import com.android.server.appsearch.external.localstorage.converter.SchemaToProtoConverter;
import com.android.server.appsearch.external.localstorage.converter.SearchResultToProtoConverter;
import com.android.server.appsearch.external.localstorage.converter.SearchSpecToProtoConverter;

import com.google.android.icing.proto.DocumentProto;
import com.google.android.icing.proto.SchemaProto;
import com.google.android.icing.proto.SchemaTypeConfigProto;
import com.google.android.icing.proto.SearchResultProto;
import com.google.android.icing.proto.SearchSpecProto;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * TODO(b/142567528): add comments when implement this class
@@ -72,21 +62,20 @@ public class AppSearchManagerService extends SystemService {
                @NonNull List<Bundle> schemaBundles,
                boolean forceOverride,
                @NonNull AndroidFuture<AppSearchResult> callback) {
            Preconditions.checkNotNull(databaseName);
            Preconditions.checkNotNull(schemaBundles);
            Preconditions.checkNotNull(callback);
            int callingUid = Binder.getCallingUidOrThrow();
            int callingUserId = UserHandle.getUserId(callingUid);
            final long callingIdentity = Binder.clearCallingIdentity();
            try {
                SchemaProto.Builder schemaProtoBuilder = SchemaProto.newBuilder();
                Set<AppSearchSchema> schemas = new ArraySet<>(schemaBundles.size());
                for (int i = 0; i < schemaBundles.size(); i++) {
                    AppSearchSchema schema = new AppSearchSchema(schemaBundles.get(i));
                    SchemaTypeConfigProto schemaTypeProto = SchemaToProtoConverter.convert(schema);
                    schemaProtoBuilder.addTypes(schemaTypeProto);
                    schemas.add(new AppSearchSchema(schemaBundles.get(i)));
                }
                AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
                databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
                impl.setSchema(databaseName, schemaProtoBuilder.build(), forceOverride);
                impl.setSchema(databaseName, schemas, forceOverride);
                callback.complete(AppSearchResult.newSuccessfulResult(/*result=*/ null));
            } catch (Throwable t) {
                callback.complete(throwableToFailedResult(t));
@@ -100,6 +89,7 @@ public class AppSearchManagerService extends SystemService {
                @NonNull String databaseName,
                @NonNull List<Bundle> documentBundles,
                @NonNull AndroidFuture<AppSearchBatchResult> callback) {
            Preconditions.checkNotNull(databaseName);
            Preconditions.checkNotNull(documentBundles);
            Preconditions.checkNotNull(callback);
            int callingUid = Binder.getCallingUidOrThrow();
@@ -112,9 +102,8 @@ public class AppSearchManagerService extends SystemService {
                        new AppSearchBatchResult.Builder<>();
                for (int i = 0; i < documentBundles.size(); i++) {
                    GenericDocument document = new GenericDocument(documentBundles.get(i));
                    DocumentProto documentProto = GenericDocumentToProtoConverter.convert(document);
                    try {
                        impl.putDocument(databaseName, documentProto);
                        impl.putDocument(databaseName, document);
                        resultBuilder.setSuccess(document.getUri(), /*result=*/ null);
                    } catch (Throwable t) {
                        resultBuilder.setResult(document.getUri(), throwableToFailedResult(t));
@@ -131,6 +120,8 @@ public class AppSearchManagerService extends SystemService {
        @Override
        public void getDocuments(@NonNull String databaseName, @NonNull String namespace,
                @NonNull List<String> uris, @NonNull AndroidFuture<AppSearchBatchResult> callback) {
            Preconditions.checkNotNull(databaseName);
            Preconditions.checkNotNull(namespace);
            Preconditions.checkNotNull(uris);
            Preconditions.checkNotNull(callback);
            int callingUid = Binder.getCallingUidOrThrow();
@@ -144,16 +135,8 @@ public class AppSearchManagerService extends SystemService {
                for (int i = 0; i < uris.size(); i++) {
                    String uri = uris.get(i);
                    try {
                        DocumentProto documentProto = impl.getDocument(
                                databaseName, namespace, uri);
                        if (documentProto == null) {
                            resultBuilder.setFailure(
                                    uri, AppSearchResult.RESULT_NOT_FOUND, /*errorMessage=*/ null);
                        } else {
                            GenericDocument genericDocument =
                                    GenericDocumentToProtoConverter.convert(documentProto);
                            resultBuilder.setSuccess(uri, genericDocument.getBundle());
                        }
                        GenericDocument document = impl.getDocument(databaseName, namespace, uri);
                        resultBuilder.setSuccess(uri, document.getBundle());
                    } catch (Throwable t) {
                        resultBuilder.setResult(uri, throwableToFailedResult(t));
                    }
@@ -167,12 +150,14 @@ public class AppSearchManagerService extends SystemService {
        }

        // TODO(sidchhabra): Do this in a threadpool.
        // TODO(b/162450968) handle pagination after getNextPage and SearchResults is ready.
        @Override
        public void query(
                @NonNull String databaseName,
                @NonNull String queryExpression,
                @NonNull Bundle searchSpecBundle,
                @NonNull AndroidFuture<AppSearchResult> callback) {
            Preconditions.checkNotNull(databaseName);
            Preconditions.checkNotNull(queryExpression);
            Preconditions.checkNotNull(searchSpecBundle);
            Preconditions.checkNotNull(callback);
@@ -180,29 +165,14 @@ public class AppSearchManagerService extends SystemService {
            int callingUserId = UserHandle.getUserId(callingUid);
            final long callingIdentity = Binder.clearCallingIdentity();
            try {
                SearchSpec searchSpec = new SearchSpec(searchSpecBundle);
                SearchSpecProto searchSpecProto =
                        SearchSpecToProtoConverter.toSearchSpecProto(searchSpec);
                searchSpecProto = searchSpecProto.toBuilder()
                        .setQuery(queryExpression).build();
                AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
                databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
                // TODO(adorokhine): handle pagination
                SearchResultProto searchResultProto = impl.query(
                SearchResultPage searchResultPage = impl.query(
                        databaseName,
                        searchSpecProto,
                        SearchSpecToProtoConverter.toResultSpecProto(searchSpec),
                        SearchSpecToProtoConverter.toScoringSpecProto(searchSpec));
                List<SearchResult> searchResultList =
                        new ArrayList<>(searchResultProto.getResultsCount());
                for (int i = 0; i < searchResultProto.getResultsCount(); i++) {
                    SearchResult result = SearchResultToProtoConverter.convertSearchResult(
                            searchResultProto.getResults(i));
                    searchResultList.add(result);
                }
                SearchResults searchResults =
                        new SearchResults(searchResultList, searchResultProto.getNextPageToken());
                callback.complete(AppSearchResult.newSuccessfulResult(searchResults));
                        queryExpression,
                        new SearchSpec(searchSpecBundle));
                callback.complete(
                        AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
            } catch (Throwable t) {
                callback.complete(throwableToFailedResult(t));
            } finally {
@@ -211,8 +181,10 @@ public class AppSearchManagerService extends SystemService {
        }

        @Override
        public void delete(@NonNull String databaseName, @NonNull String namespace,
        public void removeByUri(@NonNull String databaseName, @NonNull String namespace,
                List<String> uris, AndroidFuture<AppSearchBatchResult> callback) {
            Preconditions.checkNotNull(databaseName);
            Preconditions.checkNotNull(namespace);
            Preconditions.checkNotNull(uris);
            Preconditions.checkNotNull(callback);
            int callingUid = Binder.getCallingUidOrThrow();
@@ -241,38 +213,14 @@ public class AppSearchManagerService extends SystemService {
        }

        @Override
        public void deleteByTypes(@NonNull String databaseName,
                List<String> schemaTypes, AndroidFuture<AppSearchBatchResult> callback) {
            Preconditions.checkNotNull(schemaTypes);
            Preconditions.checkNotNull(callback);
            int callingUid = Binder.getCallingUidOrThrow();
            int callingUserId = UserHandle.getUserId(callingUid);
            final long callingIdentity = Binder.clearCallingIdentity();
            try {
                AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
                databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
                AppSearchBatchResult.Builder<String, Void> resultBuilder =
                        new AppSearchBatchResult.Builder<>();
                for (int i = 0; i < schemaTypes.size(); i++) {
                    String schemaType = schemaTypes.get(i);
                    try {
                        impl.removeByType(databaseName, schemaType);
                        resultBuilder.setSuccess(schemaType, /*result=*/ null);
                    } catch (Throwable t) {
                        resultBuilder.setResult(schemaType, throwableToFailedResult(t));
                    }
                }
                callback.complete(resultBuilder.build());
            } catch (Throwable t) {
                callback.completeExceptionally(t);
            } finally {
                Binder.restoreCallingIdentity(callingIdentity);
            }
        }

        @Override
        public void deleteAll(@NonNull String databaseName,
        public void removeByQuery(
                @NonNull String databaseName,
                @NonNull String queryExpression,
                @NonNull Bundle searchSpecBundle,
                @NonNull AndroidFuture<AppSearchResult> callback) {
            Preconditions.checkNotNull(databaseName);
            Preconditions.checkNotNull(queryExpression);
            Preconditions.checkNotNull(searchSpecBundle);
            Preconditions.checkNotNull(callback);
            int callingUid = Binder.getCallingUidOrThrow();
            int callingUserId = UserHandle.getUserId(callingUid);
@@ -280,8 +228,8 @@ public class AppSearchManagerService extends SystemService {
            try {
                AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
                databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
                impl.removeAll(databaseName);
                callback.complete(AppSearchResult.newSuccessfulResult(null));
                impl.removeByQuery(databaseName, queryExpression, new SearchSpec(searchSpecBundle));
                callback.complete(AppSearchResult.newSuccessfulResult(/*result= */null));
            } catch (Throwable t) {
                callback.complete(throwableToFailedResult(t));
            } finally {
+220 −194

File changed.

Preview size limit exceeded, changes collapsed.

Loading