diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java index 2ef4893d59180..33f69a456fb25 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.SearchResultProto; 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 @@ public class AppSearchManager { * * *

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: *

* - *

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. - * - *

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. + *

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}. * *

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 schemas, - boolean force, - @NonNull @CallbackExecutor Executor executor, - @NonNull Consumer 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. + * + *

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 schemas, boolean forceOverride) { // Prepare the merged schema for transmission. SchemaProto.Builder schemaProtoBuilder = SchemaProto.newBuilder(); for (AppSearchSchema schema : schemas) { @@ -130,11 +143,11 @@ public class AppSearchManager { byte[] schemaBytes = schemaProtoBuilder.build().toByteArray(); AndroidFuture 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 @@ public class AppSearchManager { future.completeExceptionally(e); } } + + private static T getFutureOrThrow(@NonNull AndroidFuture 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 6db65a4299a4b..194e43e36e4d6 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 @@ interface IAppSearchManager { * 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}<{@link Void}>. 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 f8e010ddb86f4..5d6d3f0a8406a 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 @@ public class AppSearchManagerService extends SystemService { 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 @@ public class AppSearchManagerService extends SystemService { 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 e69fc8a2af639..177c9108b5062 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 @@ public final class AppSearchImpl { * * @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 6b0f557ad9ed3..34ade818f0620 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 @@ public class AppSearchImplTest { () -> impl.setSchema( /*callingUid=*/Integer.MAX_VALUE, SchemaProto.getDefaultInstance(), - /*force=*/false)); + /*forceOverride=*/false)); assertThat(e).hasMessageThat().contains("Failed to look up package name"); } }