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

Commit efc87673 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Implement the AppSearch.delete API."

parents b74c142d ed02dd83
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -333,6 +333,27 @@ public class AppSearchManager {
        return AppSearchResult.newSuccessfulResult(new SearchResults(searchResultProto));
    }

    /**
     * Deletes {@link AppSearchDocument}s by URI.
     *
     * <p>You should not call this method directly; instead, use the {@code AppSearch#delete()} API
     * provided by JetPack.
     *
     * @param uris URIs of the documents to delete
     * @return An {@link AppSearchBatchResult} mapping each URI to a {@code null} success if
     *     deletion was successful, to a {@code null} failure if the document did not exist, or to a
     *     {@code throwable} failure if deletion failed for another reason.
     */
    public AppSearchBatchResult<String, Void> delete(@NonNull List<String> uris) {
        AndroidFuture<AppSearchBatchResult> future = new AndroidFuture<>();
        try {
            mService.delete(uris, 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<>();
+14 −0
Original line number Diff line number Diff line
@@ -73,6 +73,20 @@ interface IAppSearchManager {
        in byte[] searchSpecBytes, in byte[] resultSpecBytes, in byte[] scoringSpecBytes,
        in AndroidFuture<AppSearchResult> callback);

    /**
     * Deletes documents by URI.
     *
     * @param uris The URIs 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 document URIs. If a document doesn't exist, it will be reported as a
     *     failure where the {@code throwable} is {@code null}.
     */
    void delete(in List<String> uris, in AndroidFuture<AppSearchBatchResult> callback);

    /**
     * Deletes all documents belonging to the calling app.
     *
+32 −0
Original line number Diff line number Diff line
@@ -181,6 +181,38 @@ public class AppSearchManagerService extends SystemService {
            }
        }

        @Override
        public void delete(List<String> uris, AndroidFuture<AppSearchBatchResult> callback) {
            Preconditions.checkNotNull(uris);
            Preconditions.checkNotNull(callback);
            int callingUid = Binder.getCallingUidOrThrow();
            int callingUserId = UserHandle.getUserId(callingUid);
            long callingIdentity = Binder.clearCallingIdentity();
            try {
                AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
                AppSearchBatchResult.Builder<String, Void> resultBuilder =
                        new AppSearchBatchResult.Builder<>();
                for (int i = 0; i < uris.size(); i++) {
                    String uri = uris.get(i);
                    try {
                        if (!impl.delete(callingUid, uri)) {
                            resultBuilder.setFailure(
                                    uri, AppSearchResult.RESULT_NOT_FOUND, /*errorMessage=*/ null);
                        } else {
                            resultBuilder.setSuccess(uri, /*value= */null);
                        }
                    } catch (Throwable t) {
                        resultBuilder.setResult(uri, throwableToFailedResult(t));
                    }
                }
                callback.complete(resultBuilder.build());
            } catch (Throwable t) {
                callback.completeExceptionally(t);
            } finally {
                Binder.restoreCallingIdentity(callingIdentity);
            }
        }

        @Override
        public void deleteAll(@NonNull AndroidFuture<AppSearchResult> callback) {
            Preconditions.checkNotNull(callback);
+22 −0
Original line number Diff line number Diff line
@@ -129,6 +129,9 @@ public final class AppSearchImpl {
    public DocumentProto getDocument(int callingUid, @NonNull String uri) {
        String typePrefix = getTypePrefix(callingUid);
        DocumentProto document = mFakeIcing.get(uri);
        if (document == null) {
            return null;
        }

        // TODO(b/146526096): Since FakeIcing doesn't currently handle namespaces, we perform a
        //  post-filter to make sure we don't return documents we shouldn't. This should be removed
@@ -208,6 +211,25 @@ public final class AppSearchImpl {
        return searchResultsBuilder.build();
    }

    /** Deletes the given document by URI */
    public boolean delete(int callingUid, @NonNull String uri) {
        DocumentProto document = mFakeIcing.get(uri);
        if (document == null) {
            return false;
        }

        // TODO(b/146526096): Since FakeIcing doesn't currently handle namespaces, we perform a
        //     post-filter to make sure we don't delete documents we shouldn't. This should be
        //     removed once the real Icing Lib is implemented.
        String typePrefix = getTypePrefix(callingUid);
        if (!typePrefix.equals(document.getNamespace())) {
            throw new SecurityException(
                    "Failed to delete document " + uri + "; URI collision in FakeIcing");
        }

        return mFakeIcing.delete(uri);
    }

    /**
     * Deletes all documents owned by the calling app.
     *
+5 −2
Original line number Diff line number Diff line
@@ -131,18 +131,21 @@ public class FakeIcing {
     * Deletes a document by its URI.
     *
     * @param uri The URI of the document to be deleted.
     * @return Whether deletion was successful.
     */
    public void delete(@NonNull String uri) {
    public boolean delete(@NonNull String uri) {
        // Update mDocIdMap
        Integer docId = mUriToDocIdMap.get(uri);
        if (docId != null) {
            // Delete the old doc
            mDocStore.remove(docId);
            mUriToDocIdMap.remove(uri);
            return true;
        }
        return false;
    }

    /** Deletes all documents belonging to the given namespace. */
    /** Deletes all documents having the given namespace. */
    public void deleteByNamespace(@NonNull String namespace) {
        for (int i = 0; i < mDocStore.size(); i++) {
            DocumentProto document = mDocStore.valueAt(i);