Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4079ea1d authored by Alexander Dorokhine's avatar Alexander Dorokhine
Browse files

Add forceSetSchema and fix the setSchema API comment.

Bug: 145635424
Test: atest CtsAppSearchTestCases FrameworksCoreTests:android.app.appsearch FrameworksServicesTests:com.android.server.appsearch.impl
Change-Id: Ibf7f7f33226115a94efbc659c1366edd3ccb4a3c
parent 0a26313a
Loading
Loading
Loading
Loading
+49 −22
Original line number Diff line number Diff line
@@ -50,6 +50,47 @@ public class AppSearchManager {
    /**
     * Sets the schema being used by documents provided to the #put 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
     * types of schema modifications are always safe and are made without deleting any existing
     * documents:
     * <ul>
     *     <li>Addition of new types
     *     <li>Addition of new
     *         {@link android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL
     *             OPTIONAL} or
     *         {@link android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_REPEATED
     *             REPEATED} properties to a type
     *     <li>Changing the cardinality of a data type to be less restrictive (e.g. changing an
     *         {@link android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL
     *             OPTIONAL} property into a
     *         {@link android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_REPEATED
     *             REPEATED} property.
     * </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}
     * describing the incompatibility, and the previously set schema will remain active:
     * <ul>
     *     <li>Removal of an existing type
     *     <li>Removal of a property from a type
     *     <li>Changing the data type ({@code boolean}, {@code long}, etc.) of an existing property
     *     <li>For properties of {@code Document} type, changing the schema type of
     *         {@code Document Documents} of that property
     *     <li>Changing the cardinality of a data type to be more restrictive (e.g. changing an
     *         {@link android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL
     *             OPTIONAL} property into a
     *         {@link android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_REQUIRED
     *             REQUIRED} property).
     *     <li>Adding a
     *         {@link android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_REQUIRED
     *             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.
@@ -57,36 +98,22 @@ public class AppSearchManager {
     * <p>It is a no-op to set the same schema as has been previously set; this is handled
     * efficiently.
     *
     * <p>AppSearch automatically handles the following types of schema changes:
     * <ul>
     *     <li>Addition of new types (No changes to storage or index)
     *     <li>Removal of an existing type (All documents of the removed type are deleted)
     *     <li>Addition of new 'optional' property to a type (No changes to storage or index)
     *     <li>Removal of existing property of any cardinality (All documents reindexed)
     * </ul>
     *
     * <p>This method will return an error when attempting to make the following types of changes:
     * <ul>
     *     <li>Changing the type of an existing property
     *     <li>Adding a 'required' property
     * </ul>
     *
     * @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}.
     * @param schemas The schema configs for the types used by the calling app.
     *
     * @hide
     */
    // TODO(b/143789408): linkify #put after that API is created
    // TODO(b/145635424): add a 'force' param to setSchema after the corresponding API is finalized
    //     in Icing Library
    // TODO(b/145635424): Update the documentation above once the Schema mutation APIs of Icing
    //     Library are finalized
    public void setSchema(
            List<AppSearchSchema> schemas,
            boolean force,
            @NonNull @CallbackExecutor Executor executor,
            @NonNull Consumer<? super Throwable> callback,
            @NonNull AppSearchSchema... schemas) {
            @NonNull Consumer<? super Throwable> callback) {
        // Prepare the merged schema for transmission.
        SchemaProto.Builder schemaProtoBuilder = SchemaProto.newBuilder();
        for (AppSearchSchema schema : schemas) {
@@ -99,7 +126,7 @@ public class AppSearchManager {
        byte[] schemaBytes = schemaProtoBuilder.build().toByteArray();
        AndroidFuture<Void> future = new AndroidFuture<>();
        try {
            mService.setSchema(schemaBytes, future);
            mService.setSchema(schemaBytes, force, future);
        } catch (RemoteException e) {
            future.completeExceptionally(e);
        }
+4 −2
Original line number Diff line number Diff line
@@ -22,11 +22,13 @@ interface IAppSearchManager {
    /**
     * Sets the schema.
     *
     * @param schemaProto serialized SchemaProto
     * @param schemaProto Serialized SchemaProto.
     * @param force 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.
     */
    void setSchema(in byte[] schemaProto, in AndroidFuture callback);
    void setSchema(in byte[] schemaProto, boolean force, in AndroidFuture callback);
    void put(in byte[] documentBytes, in AndroidFuture callback);
}
+2 −2
Original line number Diff line number Diff line
@@ -44,7 +44,7 @@ public class AppSearchManagerService extends SystemService {

    private class Stub extends IAppSearchManager.Stub {
        @Override
        public void setSchema(byte[] schemaBytes, AndroidFuture callback) {
        public void setSchema(byte[] schemaBytes, boolean force, AndroidFuture callback) {
            Preconditions.checkNotNull(schemaBytes);
            Preconditions.checkNotNull(callback);
            int callingUid = Binder.getCallingUidOrThrow();
@@ -53,7 +53,7 @@ public class AppSearchManagerService extends SystemService {
            try {
                SchemaProto schema = SchemaProto.parseFrom(schemaBytes);
                AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
                impl.setSchema(callingUid, schema);
                impl.setSchema(callingUid, schema, force);
                callback.complete(null);
            } catch (Throwable t) {
                callback.completeExceptionally(t);
+3 −1
Original line number Diff line number Diff line
@@ -45,8 +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.
     */
    public void setSchema(int callingUid, @NonNull SchemaProto origSchema) {
    public void setSchema(int callingUid, @NonNull SchemaProto origSchema, boolean force) {
        // Rewrite schema type names to include the calling app's package and uid.
        String typePrefix = getTypePrefix(callingUid);
        SchemaProto.Builder schemaBuilder = origSchema.toBuilder();
+3 −1
Original line number Diff line number Diff line
@@ -101,7 +101,9 @@ public class AppSearchImplTest {
        IllegalStateException e = expectThrows(
                IllegalStateException.class,
                () -> impl.setSchema(
                        /*callingUid=*/Integer.MAX_VALUE, SchemaProto.getDefaultInstance()));
                        /*callingUid=*/Integer.MAX_VALUE,
                        SchemaProto.getDefaultInstance(),
                        /*force=*/false));
        assertThat(e).hasMessageThat().contains("Failed to look up package name");
    }
}