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

Commit 7a6d550b authored by Alexander Dorokhine's avatar Alexander Dorokhine
Browse files

Implement AppSearch.deleteByTypes()

Bug: 147636343
Test: atest CtsAppSearchTestCases FrameworksCoreTests:android.app.appsearch FrameworksServicesTests:com.android.server.appsearch.impl
Change-Id: I053b33744c1cec8f307ca975314c3b9415d48b68
parent ed02dd83
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -354,6 +354,27 @@ public class AppSearchManager {
        return getFutureOrThrow(future);
    }

    /**
     * Deletes {@link android.app.appsearch.AppSearch.Document}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(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<>();
+15 −0
Original line number Diff line number Diff line
@@ -87,6 +87,21 @@ interface IAppSearchManager {
     */
    void delete(in List<String> uris, in AndroidFuture<AppSearchBatchResult> callback);

    /**
     * Deletes documents by schema type.
     *
     * @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}.
     */
    void deleteByTypes(
        in List<String> schemaTypes, in AndroidFuture<AppSearchBatchResult> callback);

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

        @Override
        public void deleteByTypes(
                List<String> schemaTypes, AndroidFuture<AppSearchBatchResult> callback) {
            Preconditions.checkNotNull(schemaTypes);
            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 < schemaTypes.size(); i++) {
                    String schemaType = schemaTypes.get(i);
                    try {
                        if (!impl.deleteByType(callingUid, schemaType)) {
                            resultBuilder.setFailure(
                                    schemaType,
                                    AppSearchResult.RESULT_NOT_FOUND,
                                    /*errorMessage=*/ null);
                        } else {
                            resultBuilder.setSuccess(schemaType, /*value=*/ 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 AndroidFuture<AppSearchResult> callback) {
            Preconditions.checkNotNull(callback);
+7 −0
Original line number Diff line number Diff line
@@ -230,6 +230,13 @@ public final class AppSearchImpl {
        return mFakeIcing.delete(uri);
    }

    /** Deletes all documents having the given {@code schemaType}. */
    public boolean deleteByType(int callingUid, @NonNull String schemaType) {
        String typePrefix = getTypePrefix(callingUid);
        String qualifiedType = typePrefix + schemaType;
        return mFakeIcing.deleteByType(qualifiedType);
    }

    /**
     * Deletes all documents owned by the calling app.
     *
+19 −0
Original line number Diff line number Diff line
@@ -157,6 +157,25 @@ public class FakeIcing {
        }
    }

    /**
     * Deletes all documents having the given type.
     *
     * @return true if any documents were deleted.
     */
    public boolean deleteByType(@NonNull String type) {
        boolean deletedAny = false;
        for (int i = 0; i < mDocStore.size(); i++) {
            DocumentProto document = mDocStore.valueAt(i);
            if (type.equals(document.getSchema())) {
                mDocStore.removeAt(i);
                mUriToDocIdMap.remove(document.getUri());
                i--;
                deletedAny = true;
            }
        }
        return deletedAny;
    }

    private void indexDocument(int docId, DocumentProto document) {
        for (PropertyProto property : document.getPropertiesList()) {
            for (String stringValue : property.getStringValuesList()) {