Switch setSchema API to be synchronous, based on discussion with API council.

Bug: 145635424
Test: Presubmit
Change-Id: I1419ca809eacea38bb8efd272771c0853d91efec
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java
index 2ef4893..33f69a4 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java
@@ -29,7 +29,9 @@
 import com.google.android.icing.proto.StatusProto;
 import com.google.android.icing.protobuf.InvalidProtocolBufferException;
 
+import java.util.Arrays;
 import java.util.List;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executor;
 import java.util.function.BiConsumer;
 import java.util.function.Consumer;
@@ -73,7 +75,7 @@
      * </ul>
      *
      * <p>The following types of schema changes are not backwards-compatible. Supplying a schema
-     * with such changes will result in the provided callback being called with a {@link Throwable}
+     * with such changes will result in this call throwing an {@link IllegalSchemaException}
      * describing the incompatibility, and the previously set schema will remain active:
      * <ul>
      *     <li>Removal of an existing type
@@ -91,33 +93,44 @@
      *             REQUIRED} property.
      * </ul>
      *
-     * <p>If you need to make non-backwards-compatible changes as described above, you may set the
-     * {@code force} parameter to {@code true}. In this case, all documents which are not compatible
-     * with the new schema will be deleted.
-     *
-     * <p>This operation is performed asynchronously. On success, the provided callback will be
-     * called with {@code null}. On failure, the provided callback will be called with a
-     * {@link Throwable} describing the failure.
+     * <p>If you need to make non-backwards-compatible changes as described above, instead use the
+     * {@link #setSchema(List, boolean)} method with the {@code forceOverride} parameter set to
+     * {@code true}.
      *
      * <p>It is a no-op to set the same schema as has been previously set; this is handled
      * efficiently.
      *
      * @param schemas The schema configs for the types used by the calling app.
-     * @param force Whether to force the new schema to be applied even if there are incompatible
-     *     changes versus the previously set schema. Documents which are incompatible with the new
-     *     schema will be deleted.
-     * @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}.
+     * @throws IllegalSchemaException If the provided schema is invalid, or is incompatible with the
+     *     previous schema.
      *
      * @hide
      */
     // TODO(b/143789408): linkify #put after that API is created
-    public void setSchema(
-            List<AppSearchSchema> schemas,
-            boolean force,
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull Consumer<? super Throwable> callback) {
+    public void setSchema(@NonNull AppSearchSchema... schemas) {
+        setSchema(Arrays.asList(schemas), /*forceOverride=*/false);
+    }
+
+    /**
+     * Sets the schema being used by documents provided to the #put method.
+     *
+     * <p>This method is similar to {@link #setSchema(AppSearchSchema...)}, except for the
+     * {@code forceOverride} parameter. If a backwards-incompatible schema is specified but the
+     * {@code forceOverride} parameter is set to {@code true}, instead of throwing an
+     * {@link IllegalSchemaException}, all documents which are not compatible with the new schema
+     * will be deleted and the incompatible schema will be applied.
+     *
+     * @param schemas The schema configs for the types used by the calling app.
+     * @param forceOverride Whether to force the new schema to be applied even if there are
+     *     incompatible changes versus the previously set schema. Documents which are incompatible
+     *     with the new schema will be deleted.
+     * @throws IllegalSchemaException If the provided schema is invalid, or is incompatible with the
+     *     previous schema and the {@code forceOverride} parameter is set to {@code false}.
+     *
+     * @hide
+     */
+    // TODO(b/143789408): linkify #put after that API is created
+    public void setSchema(@NonNull List<AppSearchSchema> schemas, boolean forceOverride) {
         // Prepare the merged schema for transmission.
         SchemaProto.Builder schemaProtoBuilder = SchemaProto.newBuilder();
         for (AppSearchSchema schema : schemas) {
@@ -130,11 +143,11 @@
         byte[] schemaBytes = schemaProtoBuilder.build().toByteArray();
         AndroidFuture<Void> future = new AndroidFuture<>();
         try {
-            mService.setSchema(schemaBytes, force, future);
+            mService.setSchema(schemaBytes, forceOverride, future);
         } catch (RemoteException e) {
             future.completeExceptionally(e);
         }
-        future.whenCompleteAsync((noop, err) -> callback.accept(err), executor);
+        getFutureOrThrow(future);
     }
 
     /**
@@ -256,4 +269,21 @@
             future.completeExceptionally(e);
         }
     }
+
+    private static <T> T getFutureOrThrow(@NonNull AndroidFuture<T> future) {
+        try {
+            return future.get();
+        } catch (Throwable e) {
+            if (e instanceof ExecutionException) {
+                e = e.getCause();
+            }
+            if (e instanceof RuntimeException) {
+                throw (RuntimeException) e;
+            }
+            if (e instanceof Error) {
+                throw (Error) e;
+            }
+            throw new RuntimeException(e);
+        }
+    }
 }
diff --git a/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl b/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl
index 6db65a4..194e43e 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl
+++ b/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl
@@ -23,13 +23,13 @@
      * Sets the schema.
      *
      * @param schemaProto Serialized SchemaProto.
-     * @param force Whether to apply the new schema even if it is incompatible. All incompatible
-           documents will be deleted.
+     * @param forceOverride Whether to apply the new schema even if it is incompatible. All
+     *     incompatible documents will be deleted.
      * @param callback {@link AndroidFuture}&lt;{@link Void}&gt;. Will be completed with
-     *     {@code null} upon successful completion of the setSchema call, or completed exceptionally
-     *     if setSchema fails.
+     *     {@code null} upon successful completion of the setSchema call, or completed
+     *     exceptionally if setSchema fails.
      */
-    void setSchema(in byte[] schemaProto, boolean force, in AndroidFuture callback);
+    void setSchema(in byte[] schemaProto, boolean forceOverride, in AndroidFuture callback);
     void put(in byte[] documentBytes, in AndroidFuture callback);
     /**
      * Searches a document based on a given query string.
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
index f8e010d..5d6d3f0 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
@@ -52,7 +52,7 @@
 
     private class Stub extends IAppSearchManager.Stub {
         @Override
-        public void setSchema(byte[] schemaBytes, boolean force, AndroidFuture callback) {
+        public void setSchema(byte[] schemaBytes, boolean forceOverride, AndroidFuture callback) {
             Preconditions.checkNotNull(schemaBytes);
             Preconditions.checkNotNull(callback);
             int callingUid = Binder.getCallingUidOrThrow();
@@ -61,7 +61,7 @@
             try {
                 SchemaProto schema = SchemaProto.parseFrom(schemaBytes);
                 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
-                impl.setSchema(callingUid, schema, force);
+                impl.setSchema(callingUid, schema, forceOverride);
                 callback.complete(null);
             } catch (Throwable t) {
                 callback.completeExceptionally(t);
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/impl/AppSearchImpl.java b/apex/appsearch/service/java/com/android/server/appsearch/impl/AppSearchImpl.java
index e69fc8a..177c910 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/impl/AppSearchImpl.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/impl/AppSearchImpl.java
@@ -45,10 +45,10 @@
      *
      * @param callingUid The uid of the app calling AppSearch.
      * @param origSchema The schema to set for this app.
-     * @param force Whether to force-apply the schema even if it is incompatible. Documents which do
-     *     not comply with the new schema will be deleted.
+     * @param forceOverride Whether to force-apply the schema even if it is incompatible. Documents
+     *     which do not comply with the new schema will be deleted.
      */
-    public void setSchema(int callingUid, @NonNull SchemaProto origSchema, boolean force) {
+    public void setSchema(int callingUid, @NonNull SchemaProto origSchema, boolean forceOverride) {
         // Rewrite schema type names to include the calling app's package and uid.
         String typePrefix = getTypePrefix(callingUid);
         SchemaProto.Builder schemaBuilder = origSchema.toBuilder();
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/impl/AppSearchImplTest.java b/services/tests/servicestests/src/com/android/server/appsearch/impl/AppSearchImplTest.java
index 6b0f557..34ade81 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/impl/AppSearchImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/impl/AppSearchImplTest.java
@@ -103,7 +103,7 @@
                 () -> impl.setSchema(
                         /*callingUid=*/Integer.MAX_VALUE,
                         SchemaProto.getDefaultInstance(),
-                        /*force=*/false));
+                        /*forceOverride=*/false));
         assertThat(e).hasMessageThat().contains("Failed to look up package name");
     }
 }