Loading apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java +8 −40 Original line number Diff line number Diff line Loading @@ -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()); } /** Loading @@ -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); } Loading apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl +11 −24 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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}<{@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 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}<{@link AppSearchResult}<{@link SearchResults}>> */ 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}<{@link AppSearchResult}<{@link Void}>>. * 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); } apex/appsearch/framework/java/android/app/appsearch/SearchResultPage.java 0 → 100644 +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; } } apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java +32 −84 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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)); Loading @@ -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(); Loading @@ -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)); Loading @@ -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(); Loading @@ -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)); } Loading @@ -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); Loading @@ -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 { Loading @@ -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(); Loading Loading @@ -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); Loading @@ -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 { Loading apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java +220 −194 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java +8 −40 Original line number Diff line number Diff line Loading @@ -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()); } /** Loading @@ -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); } Loading
apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl +11 −24 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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}<{@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 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}<{@link AppSearchResult}<{@link SearchResults}>> */ 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}<{@link AppSearchResult}<{@link Void}>>. * 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); }
apex/appsearch/framework/java/android/app/appsearch/SearchResultPage.java 0 → 100644 +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; } }
apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java +32 −84 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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)); Loading @@ -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(); Loading @@ -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)); Loading @@ -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(); Loading @@ -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)); } Loading @@ -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); Loading @@ -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 { Loading @@ -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(); Loading Loading @@ -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); Loading @@ -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 { Loading
apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java +220 −194 File changed.Preview size limit exceeded, changes collapsed. Show changes