Loading apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java +3 −48 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import android.os.RemoteException; import com.android.internal.infra.AndroidFuture; import com.google.android.icing.proto.DocumentProto; import com.google.android.icing.proto.SchemaProto; import com.google.android.icing.proto.SearchResultProto; import com.google.android.icing.proto.SearchSpecProto; Loading Loading @@ -181,53 +180,6 @@ public class AppSearchManager { return getFutureOrThrow(future); } /** * Retrieves {@link android.app.appsearch.AppSearch.Document}s by URI. * * <p>You should not call this method directly; instead, use the * {@code AppSearch#getDocuments()} API provided by JetPack. * * @param uris URIs of the documents to look up. * @param executor Executor on which to invoke the callback. * @param callback Callback to receive the documents or error. */ public void getDocuments( @NonNull List<String> uris, @NonNull @CallbackExecutor Executor executor, @NonNull BiConsumer<List<AppSearch.Document>, ? super Throwable> callback) { AndroidFuture<List<byte[]>> future = new AndroidFuture<>(); future.whenCompleteAsync((documentProtos, err) -> { if (err != null) { callback.accept(null, err); return; } if (documentProtos != null) { List<AppSearch.Document> results = new ArrayList<>(documentProtos.size()); for (int i = 0; i < documentProtos.size(); i++) { DocumentProto documentProto; try { documentProto = DocumentProto.parseFrom(documentProtos.get(i)); } catch (InvalidProtocolBufferException e) { callback.accept(null, e); return; } results.add(new AppSearch.Document(documentProto)); } callback.accept(results, null); return; } // Nothing was supplied in the future at all callback.accept(null, new IllegalStateException( "Unknown failure occurred while retrieving documents")); }, executor); // TODO(b/146386470) stream uris? try { mService.getDocuments(uris.toArray(new String[uris.size()]), future); } catch (RemoteException e) { future.completeExceptionally(e); } } /** * This method searches for documents based on a given query string. It also accepts * specifications regarding how to search and format the results. Loading Loading @@ -285,6 +237,7 @@ public class AppSearchManager { callback.accept(null, err); return; } if (searchResultBytes != null) { SearchResultProto searchResultProto; try { Loading @@ -304,10 +257,12 @@ public class AppSearchManager { callback.accept(searchResults, null); return; } // Nothing was supplied in the future at all callback.accept( null, new IllegalStateException("Unknown failure occurred while querying")); }, executor); try { SearchSpecProto searchSpecProto = searchSpec.getSearchSpecProto(); searchSpecProto = searchSpecProto.toBuilder().setQuery(queryExpression).build(); Loading apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl +0 −10 Original line number Diff line number Diff line Loading @@ -46,16 +46,6 @@ interface IAppSearchManager { */ void putDocuments(in List documentsBytes, in AndroidFuture<AppSearchBatchResult> callback); /** * Retrieves documents from the index. * * @param uris The URIs of the documents to retrieve * @param callback {@link AndroidFuture}<{@link List}<byte[]>>. Will be completed * with a {@link List} containing serialized DocumentProtos, or completed exceptionally if * get fails. */ void getDocuments(in String[] uris, in AndroidFuture callback); /** * Searches a document based on a given specifications. * Loading apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java +0 −25 Original line number Diff line number Diff line Loading @@ -35,7 +35,6 @@ import com.google.android.icing.proto.SearchResultProto; import com.google.android.icing.proto.SearchSpecProto; import com.google.android.icing.protobuf.InvalidProtocolBufferException; import java.util.ArrayList; import java.util.List; /** Loading Loading @@ -104,30 +103,6 @@ public class AppSearchManagerService extends SystemService { Binder.restoreCallingIdentity(callingIdentity); } } @Override public void getDocuments(String[] uris, AndroidFuture 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); // Contains serialized DocumentProto. byte[][] is not transmissible via Binder. List<byte[]> results = new ArrayList<>(uris.length); for (String uri : uris) { DocumentProto result = impl.getDocument(callingUid, uri); results.add(result.toByteArray()); } callback.complete(results); } catch (Throwable t) { callback.completeExceptionally(t); } finally { Binder.restoreCallingIdentity(callingIdentity); } } // TODO(sidchhabra):Init FakeIcing properly. // TODO(sidchhabra): Do this in a threadpool. @Override Loading apex/appsearch/service/java/com/android/server/appsearch/impl/AppSearchImpl.java +9 −54 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ package com.android.server.appsearch.impl; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.content.Context; Loading Loading @@ -107,65 +106,30 @@ public final class AppSearchImpl { // Rewrite the type names to include the app's prefix String typePrefix = getTypePrefix(callingUid); DocumentProto.Builder documentBuilder = origDocument.toBuilder(); rewriteDocumentTypes(typePrefix, documentBuilder, /*add=*/ true); rewriteDocumentTypes(typePrefix, documentBuilder); mFakeIcing.put(documentBuilder.build()); } /** * Retrieves a document from the AppSearch index by URI. * * @param callingUid The uid of the app calling AppSearch. * @param uri The URI of the document to get. * @return The Document contents, or {@code null} if no such URI exists in the system. */ @Nullable public DocumentProto getDocument(int callingUid, @NonNull String uri) { String typePrefix = getTypePrefix(callingUid); DocumentProto document = mFakeIcing.get(uri); // Rewrite the type names to remove the app's prefix DocumentProto.Builder documentBuilder = document.toBuilder(); rewriteDocumentTypes(typePrefix, documentBuilder, /*add=*/ false); return documentBuilder.build(); } /** * Rewrites all types mentioned anywhere in {@code documentBuilder} to prepend or remove * Rewrites all types mentioned anywhere in {@code documentBuilder} to prepend * {@code typePrefix}. * * @param typePrefix The prefix to add or remove * @param typePrefix The prefix to add * @param documentBuilder The document to mutate * @param add Whether to add typePrefix to the types. If {@code false}, typePrefix will be * removed from the types. * @throws IllegalArgumentException If {@code add=false} and the document has a type that * doesn't start with {@code typePrefix}. */ @VisibleForTesting void rewriteDocumentTypes( @NonNull String typePrefix, @NonNull DocumentProto.Builder documentBuilder, boolean add) { // Rewrite the type name to include/remove the app's prefix String newSchema; if (add) { newSchema = typePrefix + documentBuilder.getSchema(); } else { newSchema = removePrefix(typePrefix, documentBuilder.getSchema()); } @NonNull DocumentProto.Builder documentBuilder) { // Rewrite the type name to include the app's prefix String newSchema = typePrefix + documentBuilder.getSchema(); documentBuilder.setSchema(newSchema); // Add/remove namespace. If we ever allow users to set their own namespaces, this will have // Add namespace. If we ever allow users to set their own namespaces, this will have // to change to prepend the prefix instead of setting the whole namespace. We will also have // to store the namespaces in a map similar to the type map so we can rewrite queries with // empty namespaces. if (add) { documentBuilder.setNamespace(typePrefix); } else if (!documentBuilder.getNamespace().equals(typePrefix)) { throw new IllegalStateException( "Unexpected namespace \"" + documentBuilder.getNamespace() + "\" (expected \"" + typePrefix + "\")"); } else { documentBuilder.clearNamespace(); } // Recurse into derived documents for (int propertyIdx = 0; Loading @@ -178,7 +142,7 @@ public final class AppSearchImpl { for (int documentIdx = 0; documentIdx < documentCount; documentIdx++) { DocumentProto.Builder derivedDocumentBuilder = propertyBuilder.getDocumentValues(documentIdx).toBuilder(); rewriteDocumentTypes(typePrefix, derivedDocumentBuilder, add); rewriteDocumentTypes(typePrefix, derivedDocumentBuilder); propertyBuilder.setDocumentValues(documentIdx, derivedDocumentBuilder); } documentBuilder.setProperties(propertyIdx, propertyBuilder); Loading @@ -201,13 +165,4 @@ public final class AppSearchImpl { } return callingUidName + "@" + mUserId + "/"; } @NonNull private static String removePrefix(@NonNull String prefix, @NonNull String input) { if (!input.startsWith(prefix)) { throw new IllegalArgumentException( "Input \"" + input + "\" does not start with \"" + prefix + "\""); } return input.substring(prefix.length()); } } Loading
apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java +3 −48 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import android.os.RemoteException; import com.android.internal.infra.AndroidFuture; import com.google.android.icing.proto.DocumentProto; import com.google.android.icing.proto.SchemaProto; import com.google.android.icing.proto.SearchResultProto; import com.google.android.icing.proto.SearchSpecProto; Loading Loading @@ -181,53 +180,6 @@ public class AppSearchManager { return getFutureOrThrow(future); } /** * Retrieves {@link android.app.appsearch.AppSearch.Document}s by URI. * * <p>You should not call this method directly; instead, use the * {@code AppSearch#getDocuments()} API provided by JetPack. * * @param uris URIs of the documents to look up. * @param executor Executor on which to invoke the callback. * @param callback Callback to receive the documents or error. */ public void getDocuments( @NonNull List<String> uris, @NonNull @CallbackExecutor Executor executor, @NonNull BiConsumer<List<AppSearch.Document>, ? super Throwable> callback) { AndroidFuture<List<byte[]>> future = new AndroidFuture<>(); future.whenCompleteAsync((documentProtos, err) -> { if (err != null) { callback.accept(null, err); return; } if (documentProtos != null) { List<AppSearch.Document> results = new ArrayList<>(documentProtos.size()); for (int i = 0; i < documentProtos.size(); i++) { DocumentProto documentProto; try { documentProto = DocumentProto.parseFrom(documentProtos.get(i)); } catch (InvalidProtocolBufferException e) { callback.accept(null, e); return; } results.add(new AppSearch.Document(documentProto)); } callback.accept(results, null); return; } // Nothing was supplied in the future at all callback.accept(null, new IllegalStateException( "Unknown failure occurred while retrieving documents")); }, executor); // TODO(b/146386470) stream uris? try { mService.getDocuments(uris.toArray(new String[uris.size()]), future); } catch (RemoteException e) { future.completeExceptionally(e); } } /** * This method searches for documents based on a given query string. It also accepts * specifications regarding how to search and format the results. Loading Loading @@ -285,6 +237,7 @@ public class AppSearchManager { callback.accept(null, err); return; } if (searchResultBytes != null) { SearchResultProto searchResultProto; try { Loading @@ -304,10 +257,12 @@ public class AppSearchManager { callback.accept(searchResults, null); return; } // Nothing was supplied in the future at all callback.accept( null, new IllegalStateException("Unknown failure occurred while querying")); }, executor); try { SearchSpecProto searchSpecProto = searchSpec.getSearchSpecProto(); searchSpecProto = searchSpecProto.toBuilder().setQuery(queryExpression).build(); Loading
apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl +0 −10 Original line number Diff line number Diff line Loading @@ -46,16 +46,6 @@ interface IAppSearchManager { */ void putDocuments(in List documentsBytes, in AndroidFuture<AppSearchBatchResult> callback); /** * Retrieves documents from the index. * * @param uris The URIs of the documents to retrieve * @param callback {@link AndroidFuture}<{@link List}<byte[]>>. Will be completed * with a {@link List} containing serialized DocumentProtos, or completed exceptionally if * get fails. */ void getDocuments(in String[] uris, in AndroidFuture callback); /** * Searches a document based on a given specifications. * Loading
apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java +0 −25 Original line number Diff line number Diff line Loading @@ -35,7 +35,6 @@ import com.google.android.icing.proto.SearchResultProto; import com.google.android.icing.proto.SearchSpecProto; import com.google.android.icing.protobuf.InvalidProtocolBufferException; import java.util.ArrayList; import java.util.List; /** Loading Loading @@ -104,30 +103,6 @@ public class AppSearchManagerService extends SystemService { Binder.restoreCallingIdentity(callingIdentity); } } @Override public void getDocuments(String[] uris, AndroidFuture 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); // Contains serialized DocumentProto. byte[][] is not transmissible via Binder. List<byte[]> results = new ArrayList<>(uris.length); for (String uri : uris) { DocumentProto result = impl.getDocument(callingUid, uri); results.add(result.toByteArray()); } callback.complete(results); } catch (Throwable t) { callback.completeExceptionally(t); } finally { Binder.restoreCallingIdentity(callingIdentity); } } // TODO(sidchhabra):Init FakeIcing properly. // TODO(sidchhabra): Do this in a threadpool. @Override Loading
apex/appsearch/service/java/com/android/server/appsearch/impl/AppSearchImpl.java +9 −54 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ package com.android.server.appsearch.impl; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.content.Context; Loading Loading @@ -107,65 +106,30 @@ public final class AppSearchImpl { // Rewrite the type names to include the app's prefix String typePrefix = getTypePrefix(callingUid); DocumentProto.Builder documentBuilder = origDocument.toBuilder(); rewriteDocumentTypes(typePrefix, documentBuilder, /*add=*/ true); rewriteDocumentTypes(typePrefix, documentBuilder); mFakeIcing.put(documentBuilder.build()); } /** * Retrieves a document from the AppSearch index by URI. * * @param callingUid The uid of the app calling AppSearch. * @param uri The URI of the document to get. * @return The Document contents, or {@code null} if no such URI exists in the system. */ @Nullable public DocumentProto getDocument(int callingUid, @NonNull String uri) { String typePrefix = getTypePrefix(callingUid); DocumentProto document = mFakeIcing.get(uri); // Rewrite the type names to remove the app's prefix DocumentProto.Builder documentBuilder = document.toBuilder(); rewriteDocumentTypes(typePrefix, documentBuilder, /*add=*/ false); return documentBuilder.build(); } /** * Rewrites all types mentioned anywhere in {@code documentBuilder} to prepend or remove * Rewrites all types mentioned anywhere in {@code documentBuilder} to prepend * {@code typePrefix}. * * @param typePrefix The prefix to add or remove * @param typePrefix The prefix to add * @param documentBuilder The document to mutate * @param add Whether to add typePrefix to the types. If {@code false}, typePrefix will be * removed from the types. * @throws IllegalArgumentException If {@code add=false} and the document has a type that * doesn't start with {@code typePrefix}. */ @VisibleForTesting void rewriteDocumentTypes( @NonNull String typePrefix, @NonNull DocumentProto.Builder documentBuilder, boolean add) { // Rewrite the type name to include/remove the app's prefix String newSchema; if (add) { newSchema = typePrefix + documentBuilder.getSchema(); } else { newSchema = removePrefix(typePrefix, documentBuilder.getSchema()); } @NonNull DocumentProto.Builder documentBuilder) { // Rewrite the type name to include the app's prefix String newSchema = typePrefix + documentBuilder.getSchema(); documentBuilder.setSchema(newSchema); // Add/remove namespace. If we ever allow users to set their own namespaces, this will have // Add namespace. If we ever allow users to set their own namespaces, this will have // to change to prepend the prefix instead of setting the whole namespace. We will also have // to store the namespaces in a map similar to the type map so we can rewrite queries with // empty namespaces. if (add) { documentBuilder.setNamespace(typePrefix); } else if (!documentBuilder.getNamespace().equals(typePrefix)) { throw new IllegalStateException( "Unexpected namespace \"" + documentBuilder.getNamespace() + "\" (expected \"" + typePrefix + "\")"); } else { documentBuilder.clearNamespace(); } // Recurse into derived documents for (int propertyIdx = 0; Loading @@ -178,7 +142,7 @@ public final class AppSearchImpl { for (int documentIdx = 0; documentIdx < documentCount; documentIdx++) { DocumentProto.Builder derivedDocumentBuilder = propertyBuilder.getDocumentValues(documentIdx).toBuilder(); rewriteDocumentTypes(typePrefix, derivedDocumentBuilder, add); rewriteDocumentTypes(typePrefix, derivedDocumentBuilder); propertyBuilder.setDocumentValues(documentIdx, derivedDocumentBuilder); } documentBuilder.setProperties(propertyIdx, propertyBuilder); Loading @@ -201,13 +165,4 @@ public final class AppSearchImpl { } return callingUidName + "@" + mUserId + "/"; } @NonNull private static String removePrefix(@NonNull String prefix, @NonNull String input) { if (!input.startsWith(prefix)) { throw new IllegalArgumentException( "Input \"" + input + "\" does not start with \"" + prefix + "\""); } return input.substring(prefix.length()); } }