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

Commit cb362c02 authored by Terry Wang's avatar Terry Wang
Browse files

Sync AppSearch from framework.

Included changes:
* 9d1cf52: Supports schema migration in AppSearch
* 1c55f12: Change AppSearch setSchema() to return a SetSchemaRsponse.
* 9d94171: Unhide AppSearchMigrationHelper, Transformer and
           SetSchemaResponse.
* f07132f: add maybeFlush to AppSearchSession.

Bug: 169883602
Bug: 173742929
Test: Presubmit

Change-Id: I9e70ed04014ae3d134defb93c5cb02a5def0c71e
parent a8786df7
Loading
Loading
Loading
Loading
+31 −1
Original line number Diff line number Diff line
@@ -22,6 +22,14 @@ package android.app.appsearch {
    method @NonNull public android.app.appsearch.AppSearchManager.SearchContext.Builder setDatabaseName(@NonNull String);
  }

  public interface AppSearchMigrationHelper {
    method public void queryAndTransform(@NonNull String, @NonNull android.app.appsearch.AppSearchMigrationHelper.Transformer) throws java.lang.Exception;
  }

  public static interface AppSearchMigrationHelper.Transformer {
    method @NonNull public android.app.appsearch.GenericDocument transform(int, int, @NonNull android.app.appsearch.GenericDocument) throws java.lang.Exception;
  }

  public final class AppSearchResult<ValueType> {
    method @Nullable public String getErrorMessage();
    method public int getResultCode();
@@ -99,6 +107,11 @@ package android.app.appsearch {
    method @NonNull public android.app.appsearch.AppSearchSchema.Int64PropertyConfig.Builder setCardinality(int);
  }

  public static interface AppSearchSchema.Migrator {
    method public default void onDowngrade(int, int, @NonNull android.app.appsearch.AppSearchMigrationHelper) throws java.lang.Exception;
    method public default void onUpgrade(int, int, @NonNull android.app.appsearch.AppSearchMigrationHelper) throws java.lang.Exception;
  }

  public abstract static class AppSearchSchema.PropertyConfig {
    method public int getCardinality();
    method public int getDataType();
@@ -135,7 +148,7 @@ package android.app.appsearch {
    method public void removeByQuery(@NonNull String, @NonNull android.app.appsearch.SearchSpec, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<java.lang.Void>>);
    method public void removeByUri(@NonNull android.app.appsearch.RemoveByUriRequest, @NonNull java.util.concurrent.Executor, @NonNull android.app.appsearch.BatchResultCallback<java.lang.String,java.lang.Void>);
    method @NonNull public void reportUsage(@NonNull android.app.appsearch.ReportUsageRequest, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<java.lang.Void>>);
    method public void setSchema(@NonNull android.app.appsearch.SetSchemaRequest, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<java.lang.Void>>);
    method public void setSchema(@NonNull android.app.appsearch.SetSchemaRequest, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<android.app.appsearch.SetSchemaResponse>>);
  }

  public interface BatchResultCallback<KeyType, ValueType> {
@@ -322,6 +335,7 @@ package android.app.appsearch {
  }

  public final class SetSchemaRequest {
    method @NonNull public java.util.Map<java.lang.String,android.app.appsearch.AppSearchSchema.Migrator> getMigrators();
    method @NonNull public java.util.Set<android.app.appsearch.AppSearchSchema> getSchemas();
    method @NonNull public java.util.Set<java.lang.String> getSchemasNotVisibleToSystemUi();
    method @NonNull public java.util.Map<java.lang.String,java.util.Set<android.app.appsearch.PackageIdentifier>> getSchemasVisibleToPackages();
@@ -334,10 +348,26 @@ package android.app.appsearch {
    method @NonNull public android.app.appsearch.SetSchemaRequest.Builder addSchema(@NonNull java.util.Collection<android.app.appsearch.AppSearchSchema>);
    method @NonNull public android.app.appsearch.SetSchemaRequest build();
    method @NonNull public android.app.appsearch.SetSchemaRequest.Builder setForceOverride(boolean);
    method @NonNull public android.app.appsearch.SetSchemaRequest.Builder setMigrator(@NonNull String, @NonNull android.app.appsearch.AppSearchSchema.Migrator);
    method @NonNull public android.app.appsearch.SetSchemaRequest.Builder setSchemaTypeVisibilityForPackage(@NonNull String, boolean, @NonNull android.app.appsearch.PackageIdentifier);
    method @NonNull public android.app.appsearch.SetSchemaRequest.Builder setSchemaTypeVisibilityForSystemUi(@NonNull String, boolean);
  }

  public class SetSchemaResponse {
    method @NonNull public java.util.Set<java.lang.String> getDeletedTypes();
    method @NonNull public java.util.Set<java.lang.String> getIncompatibleTypes();
    method @NonNull public java.util.Set<java.lang.String> getMigratedTypes();
    method @NonNull public java.util.List<android.app.appsearch.SetSchemaResponse.MigrationFailure> getMigrationFailures();
    method public boolean isSuccess();
  }

  public static class SetSchemaResponse.MigrationFailure {
    method @NonNull public android.app.appsearch.AppSearchResult<java.lang.Void> getAppSearchResult();
    method @NonNull public String getNamespace();
    method @NonNull public String getSchemaType();
    method @NonNull public String getUri();
  }

}

package android.app.appsearch.exceptions {
+13 −2
Original line number Diff line number Diff line
@@ -162,7 +162,7 @@ public final class AppSearchSession implements Closeable {
    public void setSchema(
            @NonNull SetSchemaRequest request,
            @NonNull @CallbackExecutor Executor executor,
            @NonNull Consumer<AppSearchResult<Void>> callback) {
            @NonNull Consumer<AppSearchResult<SetSchemaResponse>> callback) {
        Objects.requireNonNull(request);
        Objects.requireNonNull(executor);
        Objects.requireNonNull(callback);
@@ -192,7 +192,18 @@ public final class AppSearchSession implements Closeable {
                    mUserId,
                    new IAppSearchResultCallback.Stub() {
                        public void onResult(AppSearchResult result) {
                            executor.execute(() -> callback.accept(result));
                            executor.execute(() -> {
                                if (result.isSuccess()) {
                                    callback.accept(
                                            // TODO(b/151178558) implement Migration in platform.
                                            AppSearchResult.newSuccessfulResult(
                                                    new SetSchemaResponse.Builder().setResultCode(
                                                            result.getResultCode())
                                                            .build()));
                                } else {
                                    callback.accept(result);
                                }
                            });
                        }
                    });
            mIsMutated = true;
+65 −0
Original line number Diff line number Diff line
/*
 * Copyright 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.app.appsearch;

import android.annotation.NonNull;
import android.annotation.SuppressLint;

/**
 * The helper class for {@link AppSearchSchema} migration.
 *
 * <p>It will query and migrate {@link GenericDocument} in given type to a new version.
 */
public interface AppSearchMigrationHelper {

    /**
     * Queries all documents that need to be migrated to the different version, and transform
     * documents to that version by passing them to the provided {@link Transformer}.
     *
     * @param schemaType The schema that need be updated and migrated {@link GenericDocument} under
     *     this type.
     * @param transformer The {@link Transformer} that will upgrade or downgrade a {@link
     *     GenericDocument} to new version.
     * @see Transformer#transform
     */
    // Rethrow the Generic Exception thrown from the Transformer.
    @SuppressLint("GenericException")
    void queryAndTransform(@NonNull String schemaType, @NonNull Transformer transformer)
            throws Exception;

    /** The class to migrate {@link GenericDocument} between different version. */
    interface Transformer {

        /**
         * Translates a {@link GenericDocument} from a version to a different version.
         *
         * <p>If the uri, schema type or namespace is changed via the transform, it will apply to
         * the new {@link GenericDocument}.
         *
         * @param currentVersion The current version of the document's schema.
         * @param finalVersion The final version that documents need to be migrated to.
         * @param document The {@link GenericDocument} need to be translated to new version.
         * @return A {@link GenericDocument} in new version.
         */
        @NonNull
        // This method will be overridden by users, allow them to throw any customer Exceptions.
        @SuppressLint("GenericException")
        GenericDocument transform(
                int currentVersion, int finalVersion, @NonNull GenericDocument document)
                throws Exception;
    }
}
+45 −5
Original line number Diff line number Diff line
@@ -164,10 +164,10 @@ public final class AppSearchSchema {
         * a {@link AppSearchSchema} type at a time.
         *
         * <p>Setting a version number that is different from the version number of the schema
         * currently stored in AppSearch will result in AppSearch calling the Migrator provided to
         * {@link AppSearchSession#setSchema} to migrate the documents already in AppSearch from the
         * previous version to the one set in this request. The version number can be updated
         * without any other changes to the schema.
         * currently stored in AppSearch will result in AppSearch calling the {@link Migrator}
         * provided to {@link AppSearchSession#setSchema} to migrate the documents already in
         * AppSearch from the previous version to the one set in this request. The version number
         * can be updated without any other changes to the schema.
         *
         * <p>The version number can stay the same, increase, or decrease relative to the current
         * version number of the {@link AppSearchSchema} type that is already stored in the {@link
@@ -182,8 +182,9 @@ public final class AppSearchSchema {
         * @throws IllegalStateException if the version is negative or the builder has already been
         *     used.
         * @see AppSearchSession#setSchema
         * @see AppSearchSchema.Migrator
         * @see SetSchemaRequest.Builder#setMigrator
         */
        // TODO(b/177266929) link to Migrator in once it's ready.
        @NonNull
        public AppSearchSchema.Builder setVersion(@IntRange(from = 0) int version) {
            Preconditions.checkState(!mBuilt, "Builder has already been used");
@@ -859,4 +860,43 @@ public final class AppSearchSchema {
            }
        }
    }

    /**
     * A migrator class to translate {@link GenericDocument} from different version of {@link
     * AppSearchSchema}
     */
    public interface Migrator {

        /**
         * Migrates {@link GenericDocument} to a newer version of {@link AppSearchSchema}.
         *
         * <p>This methods will be invoked only if the {@link SetSchemaRequest} is setting a higher
         * version number than the current {@link AppSearchSchema} saved in AppSearch.
         *
         * @param currentVersion The current version of the document's schema.
         * @param targetVersion The final version that documents need to be migrated to.
         * @param helper The helper class could help to query all documents need to be migrated.
         */
        // This method will be overridden by users, allow them to throw any customer Exceptions.
        @SuppressLint("GenericException")
        default void onUpgrade(
                int currentVersion, int targetVersion, @NonNull AppSearchMigrationHelper helper)
                throws Exception {}

        /**
         * Migrates {@link GenericDocument} to an older version of {@link AppSearchSchema}.
         *
         * <p>The methods will be invoked only if the {@link SetSchemaRequest} is setting a higher
         * version number than the current {@link AppSearchSchema} saved in AppSearch.
         *
         * @param currentVersion The current version of the document's schema.
         * @param targetVersion The final version that documents need to be migrated to.
         * @param helper The helper class could help to query all documents need to be migrated.
         */
        // This method will be overridden by users, allow them to throw any customer Exceptions.
        @SuppressLint("GenericException")
        default void onDowngrade(
                int currentVersion, int targetVersion, @NonNull AppSearchMigrationHelper helper)
                throws Exception {}
    }
}
+28 −0
Original line number Diff line number Diff line
@@ -38,16 +38,19 @@ public final class SetSchemaRequest {
    private final Set<AppSearchSchema> mSchemas;
    private final Set<String> mSchemasNotVisibleToSystemUi;
    private final Map<String, Set<PackageIdentifier>> mSchemasVisibleToPackages;
    private final Map<String, AppSearchSchema.Migrator> mMigrators;
    private final boolean mForceOverride;

    SetSchemaRequest(
            @NonNull Set<AppSearchSchema> schemas,
            @NonNull Set<String> schemasNotVisibleToSystemUi,
            @NonNull Map<String, Set<PackageIdentifier>> schemasVisibleToPackages,
            @NonNull Map<String, AppSearchSchema.Migrator> migrators,
            boolean forceOverride) {
        mSchemas = Preconditions.checkNotNull(schemas);
        mSchemasNotVisibleToSystemUi = Preconditions.checkNotNull(schemasNotVisibleToSystemUi);
        mSchemasVisibleToPackages = Preconditions.checkNotNull(schemasVisibleToPackages);
        mMigrators = Preconditions.checkNotNull(migrators);
        mForceOverride = forceOverride;
    }

@@ -81,6 +84,12 @@ public final class SetSchemaRequest {
        return copy;
    }

    /** Returns the map of {@link android.app.appsearch.AppSearchSchema.Migrator}. */
    @NonNull
    public Map<String, AppSearchSchema.Migrator> getMigrators() {
        return Collections.unmodifiableMap(mMigrators);
    }

    /**
     * Returns a mapping of schema types to the set of packages that have access to that schema
     * type. Each package is represented by a {@link PackageIdentifier}. name and byte[]
@@ -107,6 +116,7 @@ public final class SetSchemaRequest {
        private final Set<String> mSchemasNotVisibleToSystemUi = new ArraySet<>();
        private final Map<String, Set<PackageIdentifier>> mSchemasVisibleToPackages =
                new ArrayMap<>();
        private final Map<String, AppSearchSchema.Migrator> mMigrators = new ArrayMap<>();
        private boolean mForceOverride = false;
        private boolean mBuilt = false;

@@ -196,6 +206,23 @@ public final class SetSchemaRequest {
            return this;
        }

        /**
         * Sets the {@link android.app.appsearch.AppSearchSchema.Migrator}.
         *
         * @param schemaType The schema type to set migrator on.
         * @param migrator The migrator translate a document from it's old version to a new
         *     incompatible version.
         */
        @NonNull
        @SuppressLint("MissingGetterMatchingBuilder") // Getter return plural objects.
        public Builder setMigrator(
                @NonNull String schemaType, @NonNull AppSearchSchema.Migrator migrator) {
            Preconditions.checkNotNull(schemaType);
            Preconditions.checkNotNull(migrator);
            mMigrators.put(schemaType, migrator);
            return this;
        }

        /**
         * Configures the {@link SetSchemaRequest} to delete any existing documents that don't
         * follow the new schema.
@@ -241,6 +268,7 @@ public final class SetSchemaRequest {
                    mSchemas,
                    mSchemasNotVisibleToSystemUi,
                    mSchemasVisibleToPackages,
                    mMigrators,
                    mForceOverride);
        }
    }
Loading