Loading apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java +21 −0 Original line number Diff line number Diff line Loading @@ -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<>(); Loading apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl +14 −0 Original line number Diff line number Diff line Loading @@ -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}<{@link AppSearchBatchResult}<{@link String}, {@link Void}>>. * If the call fails to start, {@code callback} will be completed exceptionally. Otherwise, * {@code callback} will be completed with an * {@link AppSearchBatchResult}<{@link String}, {@link Void}> * 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. * Loading apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java +32 −0 Original line number Diff line number Diff line Loading @@ -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); Loading apex/appsearch/service/java/com/android/server/appsearch/impl/AppSearchImpl.java +22 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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. * Loading apex/appsearch/service/java/com/android/server/appsearch/impl/FakeIcing.java +5 −2 Original line number Diff line number Diff line Loading @@ -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); Loading Loading
apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java +21 −0 Original line number Diff line number Diff line Loading @@ -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<>(); Loading
apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl +14 −0 Original line number Diff line number Diff line Loading @@ -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}<{@link AppSearchBatchResult}<{@link String}, {@link Void}>>. * If the call fails to start, {@code callback} will be completed exceptionally. Otherwise, * {@code callback} will be completed with an * {@link AppSearchBatchResult}<{@link String}, {@link Void}> * 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. * Loading
apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java +32 −0 Original line number Diff line number Diff line Loading @@ -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); Loading
apex/appsearch/service/java/com/android/server/appsearch/impl/AppSearchImpl.java +22 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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. * Loading
apex/appsearch/service/java/com/android/server/appsearch/impl/FakeIcing.java +5 −2 Original line number Diff line number Diff line Loading @@ -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); Loading