Porting AppSearch jetpack upstream changes to platform

Changes included:
#af6646e : Support retrieving the current database's schema
#2696e50 : Unhide the createGlobalSearchSession API.

Bug: 162450968
Test: presubmit
Change-Id: I8e97304fedd446b88393eb6ca5b42c2e210e3271
diff --git a/framework/java/android/app/appsearch/AppSearchSession.java b/framework/java/android/app/appsearch/AppSearchSession.java
index b7cd4f5..1918070 100644
--- a/framework/java/android/app/appsearch/AppSearchSession.java
+++ b/framework/java/android/app/appsearch/AppSearchSession.java
@@ -22,6 +22,7 @@
 import android.os.Bundle;
 import android.os.ParcelableException;
 import android.os.RemoteException;
+import android.util.ArraySet;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -34,6 +35,8 @@
 /**
  * Represents a connection to an AppSearch storage system where {@link GenericDocument}s can be
  * placed and queried.
+ *
+ * This class is thread safe.
  * @hide
  */
 public final class AppSearchSession {
@@ -79,7 +82,7 @@
     }
 
     /**
-     * Sets the schema will be used by documents provided to the {@link #putDocuments} method.
+     * Sets the schema that will be used by documents provided to the {@link #putDocuments} method.
      *
      * <p>The schema provided here is compared to the stored copy of the schema previously supplied
      * to {@link #setSchema}, if any, to determine how to treat existing documents. The following
@@ -123,11 +126,19 @@
      * <p>It is a no-op to set the same schema as has been previously set; this is handled
      * efficiently.
      *
+     * <p>By default, documents are visible on platform surfaces. To opt out, call {@code
+     * SetSchemaRequest.Builder#setPlatformSurfaceable} with {@code surfaceable} as false. Any
+     * visibility settings apply only to the schemas that are included in the {@code request}.
+     * Visibility settings for a schema type do not apply or persist across
+     * {@link SetSchemaRequest}s.
+     *
      * @param request The schema update request.
      * @param executor Executor on which to invoke the callback.
      * @param callback Callback to receive errors resulting from setting the schema. If the
      *                 operation succeeds, the callback will be invoked with {@code null}.
      */
+    // TODO(b/169883602): Change @code references to @link when setPlatformSurfaceable APIs are
+    //  exposed.
     public void setSchema(
             @NonNull SetSchemaRequest request,
             @NonNull @CallbackExecutor Executor executor,
@@ -156,6 +167,43 @@
     }
 
     /**
+     * Retrieves the schema most recently successfully provided to {@link #setSchema}.
+     *
+     * @param executor Executor on which to invoke the callback.
+     * @param callback Callback to receive the pending results of schema.
+     */
+    public void getSchema(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull Consumer<AppSearchResult<Set<AppSearchSchema>>> callback) {
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(callback);
+        try {
+            mService.getSchema(
+                    mDatabaseName,
+                    new IAppSearchResultCallback.Stub() {
+                        public void onResult(AppSearchResult result) {
+                            executor.execute(() -> {
+                                if (result.isSuccess()) {
+                                    List<Bundle> schemaBundles =
+                                            (List<Bundle>) result.getResultValue();
+                                    Set<AppSearchSchema> schemas = new ArraySet<>(
+                                            schemaBundles.size());
+                                    for (int i = 0; i < schemaBundles.size(); i++) {
+                                        schemas.add(new AppSearchSchema(schemaBundles.get(i)));
+                                    }
+                                    callback.accept(AppSearchResult.newSuccessfulResult(schemas));
+                                } else {
+                                    callback.accept(result);
+                                }
+                            });
+                        }
+                    });
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Indexes documents into AppSearch.
      *
      * <p>Each {@link GenericDocument}'s {@code schemaType} field must be set to the name of a
@@ -369,7 +417,7 @@
     /**
      * Removes {@link GenericDocument}s from the index by Query. Documents will be removed if they
      * match the {@code queryExpression} in given namespaces and schemaTypes which is set via
-     * {@link SearchSpec.Builder#addNamespace} and {@link SearchSpec.Builder#addSchema}.
+     * {@link SearchSpec.Builder#addNamespace} and {@link SearchSpec.Builder#addSchemaType}.
      *
      * <p> An empty {@code queryExpression} matches all documents.
      *
@@ -377,10 +425,13 @@
      * the current database.
      *
      * @param queryExpression Query String to search.
-     * @param searchSpec Defines what and how to remove
-     * @param executor Executor on which to invoke the callback.
-     * @param callback Callback to receive errors resulting from removing the documents. If the
-     *                 operation succeeds, the callback will be invoked with {@code null}.
+     * @param searchSpec      Spec containing schemaTypes, namespaces and query expression indicates
+     *                        how document will be removed. All specific about how to scoring,
+     *                        ordering, snippeting and resulting will be ignored.
+     * @param executor        Executor on which to invoke the callback.
+     * @param callback        Callback to receive errors resulting from removing the documents. If
+     *                        the operation succeeds, the callback will be invoked with
+     *                        {@code null}.
      */
     public void removeByQuery(@NonNull String queryExpression,
             @NonNull SearchSpec searchSpec,
diff --git a/framework/java/android/app/appsearch/GlobalSearchSession.java b/framework/java/android/app/appsearch/GlobalSearchSession.java
index d2aa8ea..07938b7 100644
--- a/framework/java/android/app/appsearch/GlobalSearchSession.java
+++ b/framework/java/android/app/appsearch/GlobalSearchSession.java
@@ -115,7 +115,7 @@
      * @return The search result of performing this operation.
      */
     @NonNull
-    public SearchResults globalQuery(
+    public SearchResults query(
             @NonNull String queryExpression,
             @NonNull SearchSpec searchSpec,
             @NonNull @CallbackExecutor Executor executor) {
diff --git a/framework/java/android/app/appsearch/IAppSearchManager.aidl b/framework/java/android/app/appsearch/IAppSearchManager.aidl
index 1d7cb87..7883046 100644
--- a/framework/java/android/app/appsearch/IAppSearchManager.aidl
+++ b/framework/java/android/app/appsearch/IAppSearchManager.aidl
@@ -28,10 +28,10 @@
 /** {@hide} */
 interface IAppSearchManager {
     /**
-     * Sets the schema.
+     * Updates the AppSearch schema for this database.
      *
-     * @param databaseName  The databaseName this document resides in.
-     * @param schemaBundles List of AppSearchSchema bundles.
+     * @param databaseName  The name of the database where this schema lives.
+     * @param schemaBundles List of {@link AppSearchSchema} bundles.
      * @param schemasNotPlatformSurfaceable Schema types that should not be surfaced on platform
      *     surfaces.
      * @param forceOverride Whether to apply the new schema even if it is incompatible. All
@@ -46,6 +46,17 @@
         boolean forceOverride,
         in IAppSearchResultCallback callback);
 
+
+    /**
+     * Retrieves the AppSearch schema for this database.
+     *
+     * @param databaseName  The name of the database to retrieve.
+     * @param callback {@link IAppSearchResultCallback#onResult} will be called with an
+     *     {@link AppSearchResult}&lt;{@link List}&lt;{@link Bundle}&gt;&gt;, where the value are
+     *     AppSearchSchema bundle.
+     */
+    void getSchema(in String databaseName, in IAppSearchResultCallback callback);
+
     /**
      * Inserts documents into the index.
      *
diff --git a/framework/java/android/app/appsearch/SearchResults.java b/framework/java/android/app/appsearch/SearchResults.java
index 8548d20..7d3ea8b 100644
--- a/framework/java/android/app/appsearch/SearchResults.java
+++ b/framework/java/android/app/appsearch/SearchResults.java
@@ -77,7 +77,7 @@
      * <p>Re-call this method to get next page of {@link SearchResult}, until it returns an
      * empty list.
      *
-     * <p>The page size is set by {@link SearchSpec.Builder#setNumPerPage}.
+     * <p>The page size is set by {@link SearchSpec.Builder#setResultCountPerPage}.
      *
      * @param callback Callback to receive the pending result of performing this operation.
      */
diff --git a/service/java/com/android/server/appsearch/AppSearchManagerService.java b/service/java/com/android/server/appsearch/AppSearchManagerService.java
index 551347c..1512825 100644
--- a/service/java/com/android/server/appsearch/AppSearchManagerService.java
+++ b/service/java/com/android/server/appsearch/AppSearchManagerService.java
@@ -90,6 +90,32 @@
         }
 
         @Override
+        public void getSchema(
+                @NonNull String databaseName,
+                @NonNull IAppSearchResultCallback callback) {
+            Preconditions.checkNotNull(databaseName);
+            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);
+                List<AppSearchSchema> schemas = impl.getSchema(databaseName);
+                List<Bundle> schemaBundles = new ArrayList<>(schemas.size());
+                for (int i = 0; i < schemas.size(); i++) {
+                    schemaBundles.add(schemas.get(i).getBundle());
+                }
+                invokeCallbackOnResult(callback,
+                        AppSearchResult.newSuccessfulResult(schemaBundles));
+            } catch (Throwable t) {
+                invokeCallbackOnError(callback, t);
+            } finally {
+                Binder.restoreCallingIdentity(callingIdentity);
+            }
+        }
+
+        @Override
         public void putDocuments(
                 @NonNull String databaseName,
                 @NonNull List<Bundle> documentBundles,