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

Commit e2e63a57 authored by Alexander Dorokhine's avatar Alexander Dorokhine Committed by Android (Google) Code Review
Browse files

Merge "Add forceSetSchema and fix the setSchema API comment."

parents 42b34aef 4079ea1d
Loading
Loading
Loading
Loading
+49 −22
Original line number Original line Diff line number Diff line
@@ -54,6 +54,47 @@ public class AppSearchManager {
    /**
    /**
     * Sets the schema being used by documents provided to the #put method.
     * 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
     * <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
     * called with {@code null}. On failure, the provided callback will be called with a
     * {@link Throwable} describing the failure.
     * {@link Throwable} describing the failure.
@@ -61,36 +102,22 @@ public class AppSearchManager {
     * <p>It is a no-op to set the same schema as has been previously set; this is handled
     * <p>It is a no-op to set the same schema as has been previously set; this is handled
     * efficiently.
     * efficiently.
     *
     *
     * <p>AppSearch automatically handles the following types of schema changes:
     * @param schemas The schema configs for the types used by the calling app.
     * <ul>
     * @param force Whether to force the new schema to be applied even if there are incompatible
     *     <li>Addition of new types (No changes to storage or index)
     *     changes versus the previously set schema. Documents which are incompatible with the new
     *     <li>Removal of an existing type (All documents of the removed type are deleted)
     *     schema will be 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 executor Executor on which to invoke the callback.
     * @param executor Executor on which to invoke the callback.
     * @param callback Callback to receive errors resulting from setting the schema. If the
     * @param callback Callback to receive errors resulting from setting the schema. If the
     *                 operation succeeds, the callback will be invoked with {@code null}.
     *                 operation succeeds, the callback will be invoked with {@code null}.
     * @param schemas The schema configs for the types used by the calling app.
     *
     *
     * @hide
     * @hide
     */
     */
    // TODO(b/143789408): linkify #put after that API is created
    // 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(
    public void setSchema(
            List<AppSearchSchema> schemas,
            boolean force,
            @NonNull @CallbackExecutor Executor executor,
            @NonNull @CallbackExecutor Executor executor,
            @NonNull Consumer<? super Throwable> callback,
            @NonNull Consumer<? super Throwable> callback) {
            @NonNull AppSearchSchema... schemas) {
        // Prepare the merged schema for transmission.
        // Prepare the merged schema for transmission.
        SchemaProto.Builder schemaProtoBuilder = SchemaProto.newBuilder();
        SchemaProto.Builder schemaProtoBuilder = SchemaProto.newBuilder();
        for (AppSearchSchema schema : schemas) {
        for (AppSearchSchema schema : schemas) {
@@ -103,7 +130,7 @@ public class AppSearchManager {
        byte[] schemaBytes = schemaProtoBuilder.build().toByteArray();
        byte[] schemaBytes = schemaProtoBuilder.build().toByteArray();
        AndroidFuture<Void> future = new AndroidFuture<>();
        AndroidFuture<Void> future = new AndroidFuture<>();
        try {
        try {
            mService.setSchema(schemaBytes, future);
            mService.setSchema(schemaBytes, force, future);
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            future.completeExceptionally(e);
            future.completeExceptionally(e);
        }
        }
+4 −2
Original line number Original line Diff line number Diff line
@@ -22,12 +22,14 @@ interface IAppSearchManager {
    /**
    /**
     * Sets the schema.
     * 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
     * @param callback {@link AndroidFuture}&lt;{@link Void}&gt;. Will be completed with
     *     {@code null} upon successful completion of the setSchema call, or completed exceptionally
     *     {@code null} upon successful completion of the setSchema call, or completed exceptionally
     *     if setSchema fails.
     *     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);
    void put(in byte[] documentBytes, in AndroidFuture callback);
    /**
    /**
     * Searches a document based on a given query string.
     * Searches a document based on a given query string.
+2 −2
Original line number Original line Diff line number Diff line
@@ -52,7 +52,7 @@ public class AppSearchManagerService extends SystemService {


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