Merge "Update framework from jetpack." into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
b97100acaa
@@ -28,11 +28,19 @@ import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Provides access to multiple {@link AppSearchResult}s from a batch operation accepting multiple
|
||||
* inputs.
|
||||
* Provides results for AppSearch batch operations which encompass multiple documents.
|
||||
*
|
||||
* @param <KeyType> The type of the keys for {@link #getSuccesses} and {@link #getFailures}.
|
||||
* @param <ValueType> The type of result objects associated with the keys.
|
||||
* <p>Individual results of a batch operation are separated into two maps: one for successes and one
|
||||
* for failures. For successes, {@link #getSuccesses()} will return a map of keys to instances of
|
||||
* the value type. For failures, {@link #getFailures()} will return a map of keys to {@link
|
||||
* AppSearchResult} objects.
|
||||
*
|
||||
* <p>Alternatively, {@link #getAll()} returns a map of keys to {@link AppSearchResult} objects for
|
||||
* both successes and failures.
|
||||
*
|
||||
* @see AppSearchSession#put
|
||||
* @see AppSearchSession#getByUri
|
||||
* @see AppSearchSession#remove
|
||||
*/
|
||||
public final class AppSearchBatchResult<KeyType, ValueType> implements Parcelable {
|
||||
@NonNull private final Map<KeyType, ValueType> mSuccesses;
|
||||
@@ -75,8 +83,11 @@ public final class AppSearchBatchResult<KeyType, ValueType> implements Parcelabl
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link Map} of all successful keys mapped to the successful {@link
|
||||
* AppSearchResult}s they produced.
|
||||
* Returns a {@link Map} of keys mapped to instances of the value type for all successful
|
||||
* individual results.
|
||||
*
|
||||
* <p>Example: {@link AppSearchSession#getByUri} returns an {@link AppSearchBatchResult}. Each
|
||||
* key (a URI of {@code String} type) will map to a {@link GenericDocument} object.
|
||||
*
|
||||
* <p>The values of the {@link Map} will not be {@code null}.
|
||||
*/
|
||||
@@ -86,8 +97,8 @@ public final class AppSearchBatchResult<KeyType, ValueType> implements Parcelabl
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link Map} of all failed keys mapped to the failed {@link AppSearchResult}s they
|
||||
* produced.
|
||||
* Returns a {@link Map} of keys mapped to instances of {@link AppSearchResult} for all failed
|
||||
* individual results.
|
||||
*
|
||||
* <p>The values of the {@link Map} will not be {@code null}.
|
||||
*/
|
||||
@@ -97,7 +108,8 @@ public final class AppSearchBatchResult<KeyType, ValueType> implements Parcelabl
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link Map} of all keys mapped to the {@link AppSearchResult}s they produced.
|
||||
* Returns a {@link Map} of keys mapped to instances of {@link AppSearchResult} for all
|
||||
* individual results.
|
||||
*
|
||||
* <p>The values of the {@link Map} will not be {@code null}.
|
||||
*/
|
||||
@@ -149,8 +161,8 @@ public final class AppSearchBatchResult<KeyType, ValueType> implements Parcelabl
|
||||
/**
|
||||
* Builder for {@link AppSearchBatchResult} objects.
|
||||
*
|
||||
* @param <KeyType> The type of keys.
|
||||
* @param <ValueType> The type of result objects associated with the keys.
|
||||
* <p>Once {@link #build} is called, the instance can no longer be used.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final class Builder<KeyType, ValueType> {
|
||||
@@ -160,9 +172,11 @@ public final class AppSearchBatchResult<KeyType, ValueType> implements Parcelabl
|
||||
private boolean mBuilt = false;
|
||||
|
||||
/**
|
||||
* Associates the {@code key} with the given successful return value.
|
||||
* Associates the {@code key} with the provided successful return value.
|
||||
*
|
||||
* <p>Any previous mapping for a key, whether success or failure, is deleted.
|
||||
*
|
||||
* @throws IllegalStateException if the builder has already been used.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder<KeyType, ValueType> setSuccess(
|
||||
@@ -173,9 +187,11 @@ public final class AppSearchBatchResult<KeyType, ValueType> implements Parcelabl
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates the {@code key} with the given failure code and error message.
|
||||
* Associates the {@code key} with the provided failure code and error message.
|
||||
*
|
||||
* <p>Any previous mapping for a key, whether success or failure, is deleted.
|
||||
*
|
||||
* @throws IllegalStateException if the builder has already been used.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder<KeyType, ValueType> setFailure(
|
||||
@@ -188,9 +204,11 @@ public final class AppSearchBatchResult<KeyType, ValueType> implements Parcelabl
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates the {@code key} with the given {@code result}.
|
||||
* Associates the {@code key} with the provided {@code result}.
|
||||
*
|
||||
* <p>Any previous mapping for a key, whether success or failure, is deleted.
|
||||
*
|
||||
* @throws IllegalStateException if the builder has already been used.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder<KeyType, ValueType> setResult(
|
||||
@@ -209,7 +227,11 @@ public final class AppSearchBatchResult<KeyType, ValueType> implements Parcelabl
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Builds an {@link AppSearchBatchResult} from the contents of this {@link Builder}. */
|
||||
/**
|
||||
* Builds an {@link AppSearchBatchResult} object from the contents of this {@link Builder}.
|
||||
*
|
||||
* @throws IllegalStateException if the builder has already been used.
|
||||
*/
|
||||
@NonNull
|
||||
public AppSearchBatchResult<KeyType, ValueType> build() {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
|
||||
@@ -41,7 +41,7 @@ import java.util.function.Consumer;
|
||||
* Represents a connection to an AppSearch storage system where {@link GenericDocument}s can be
|
||||
* placed and queried.
|
||||
*
|
||||
* This class is thread safe.
|
||||
* <p>This class is thread safe.
|
||||
*/
|
||||
public final class AppSearchSession implements Closeable {
|
||||
private static final String TAG = "AppSearchSession";
|
||||
@@ -102,92 +102,23 @@ public final class AppSearchSession implements Closeable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the schema that will be used by documents provided to the {@link #put} method.
|
||||
* Sets the schema that represents the organizational structure of data within the AppSearch
|
||||
* database.
|
||||
*
|
||||
* <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:
|
||||
* <p>Upon creating an {@link AppSearchSession}, {@link #setSchema} should be called. If the
|
||||
* schema needs to be updated, or it has not been previously set, then the provided schema will
|
||||
* be saved and persisted to disk. Otherwise, {@link #setSchema} is handled efficiently as a
|
||||
* no-op call.
|
||||
*
|
||||
* <ul>
|
||||
* <li>Addition of new types
|
||||
* <li>Addition of new {@link AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL OPTIONAL} or
|
||||
* {@link 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
|
||||
* AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL OPTIONAL} property into a {@link
|
||||
* AppSearchSchema.PropertyConfig#CARDINALITY_REPEATED REPEATED} property.
|
||||
* </ul>
|
||||
*
|
||||
* <p>The following types of schema changes are not backwards-compatible:
|
||||
*
|
||||
* <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}s
|
||||
* of that property
|
||||
* <li>Changing the cardinality of a data type to be more restrictive (e.g. changing an {@link
|
||||
* AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL OPTIONAL} property into a {@link
|
||||
* AppSearchSchema.PropertyConfig#CARDINALITY_REQUIRED REQUIRED} property).
|
||||
* <li>Adding a {@link AppSearchSchema.PropertyConfig#CARDINALITY_REQUIRED REQUIRED} property.
|
||||
* </ul>
|
||||
*
|
||||
* <p>Supplying a schema with such changes will, by default, result in this call completing its
|
||||
* future with an {@link android.app.appsearch.exceptions.AppSearchException} with a code of
|
||||
* {@link AppSearchResult#RESULT_INVALID_SCHEMA} and a message describing the incompatibility.
|
||||
* In this case the previously set schema will remain active.
|
||||
*
|
||||
* <p>If you need to make non-backwards-compatible changes as described above, you can either:
|
||||
*
|
||||
* <ul>
|
||||
* <li>Set the {@link SetSchemaRequest.Builder#setForceOverride} method to {@code true}. In
|
||||
* this case, instead of completing its future with an {@link
|
||||
* android.app.appsearch.exceptions.AppSearchException} with the {@link
|
||||
* AppSearchResult#RESULT_INVALID_SCHEMA} error code, all documents which are not
|
||||
* compatible with the new schema will be deleted and the incompatible schema will be
|
||||
* applied. Incompatible types and deleted types will be set into {@link
|
||||
* SetSchemaResponse#getIncompatibleTypes()} and {@link
|
||||
* SetSchemaResponse#getDeletedTypes()}, respectively.
|
||||
* <li>Add a {@link android.app.appsearch.AppSearchSchema.Migrator} for each incompatible type
|
||||
* and make no deletion. The migrator will migrate documents from it's old schema version
|
||||
* to the new version. Migrated types will be set into both {@link
|
||||
* SetSchemaResponse#getIncompatibleTypes()} and {@link
|
||||
* SetSchemaResponse#getMigratedTypes()}. See the migration section below.
|
||||
* </ul>
|
||||
*
|
||||
* <p>It is a no-op to set the same schema as has been previously set; this is handled
|
||||
* efficiently.
|
||||
*
|
||||
* <p>By default, documents are visible on platform surfaces. To opt out, call {@code
|
||||
* SetSchemaRequest.Builder#setPlatformSurfaceable} with {@code surfaceable} as false. Any
|
||||
* visibility settings apply only to the schemas that are included in the {@code request}.
|
||||
* Visibility settings for a schema type do not apply or persist across {@link
|
||||
* SetSchemaRequest}s.
|
||||
*
|
||||
* <p>Migration: make non-backwards-compatible changes will delete all stored documents in old
|
||||
* schema. You can save your documents by setting {@link
|
||||
* android.app.appsearch.AppSearchSchema.Migrator} via the {@link
|
||||
* SetSchemaRequest.Builder#setMigrator} for each type you want to save.
|
||||
*
|
||||
* <p>{@link android.app.appsearch.AppSearchSchema.Migrator#onDowngrade} or {@link
|
||||
* android.app.appsearch.AppSearchSchema.Migrator#onUpgrade} will be triggered if the version
|
||||
* number of the schema stored in AppSearch is different with the version in the request.
|
||||
*
|
||||
* <p>If any error or Exception occurred in the {@link
|
||||
* android.app.appsearch.AppSearchSchema.Migrator#onDowngrade}, {@link
|
||||
* android.app.appsearch.AppSearchSchema.Migrator#onUpgrade} or {@link
|
||||
* android.app.appsearch.AppSearchMigrationHelper.Transformer#transform}, the migration will be
|
||||
* terminated, the setSchema request will be rejected unless the schema changes are
|
||||
* backwards-compatible, and stored documents won't have any observable changes.
|
||||
*
|
||||
* @param request The schema update request.
|
||||
* @param request the schema to set or update the AppSearch database to.
|
||||
* @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}.
|
||||
* @see android.app.appsearch.AppSearchSchema.Migrator
|
||||
* @see android.app.appsearch.AppSearchMigrationHelper.Transformer
|
||||
*/
|
||||
// TODO(b/169883602): Change @code references to @link when setPlatformSurfaceable APIs are
|
||||
// exposed.
|
||||
public void setSchema(
|
||||
@NonNull SetSchemaRequest request,
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@@ -280,12 +211,13 @@ public final class AppSearchSession implements Closeable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indexes documents into AppSearch.
|
||||
* Indexes documents into the {@link AppSearchSession} database.
|
||||
*
|
||||
* <p>Each {@link GenericDocument}'s {@code schemaType} field must be set to the name of a
|
||||
* schema type previously registered via the {@link #setSchema} method.
|
||||
* <p>Each {@link GenericDocument} object must have a {@code schemaType} field set to an {@link
|
||||
* AppSearchSchema} type that has been previously registered by calling the {@link #setSchema}
|
||||
* method.
|
||||
*
|
||||
* @param request {@link PutDocumentsRequest} containing documents to be indexed
|
||||
* @param request containing documents to be indexed.
|
||||
* @param executor Executor on which to invoke the callback.
|
||||
* @param callback Callback to receive pending result of performing this operation. The keys
|
||||
* of the returned {@link AppSearchBatchResult} are the URIs of the input
|
||||
|
||||
@@ -98,8 +98,7 @@ public class GlobalSearchSession implements Closeable {
|
||||
* <p>Document access can also be granted to system UIs by specifying {@link
|
||||
* SetSchemaRequest.Builder#setSchemaTypeVisibilityForSystemUi} when building a schema.
|
||||
*
|
||||
* <p>See {@link AppSearchSession#search} for a detailed explanation on
|
||||
* forming a query string.
|
||||
* <p>See {@link AppSearchSession#search} for a detailed explanation on forming a query string.
|
||||
*
|
||||
* <p>This method is lightweight. The heavy work will be done in {@link
|
||||
* SearchResults#getNextPage}.
|
||||
|
||||
@@ -33,12 +33,16 @@ import java.util.concurrent.Executor;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* SearchResults are a returned object from a query API.
|
||||
* Encapsulates results of a search operation.
|
||||
*
|
||||
* <p>Each {@link SearchResult} contains a document and may contain other fields like snippets based
|
||||
* on request.
|
||||
* <p>Each {@link AppSearchSession#search} operation returns a list of {@link SearchResult} objects,
|
||||
* referred to as a "page", limited by the size configured by {@link
|
||||
* SearchSpec.Builder#setResultCountPerPage}.
|
||||
*
|
||||
* <p>Should close this object after finish fetching results.
|
||||
* <p>To fetch a page of results, call {@link #getNextPage}.
|
||||
*
|
||||
* <p>All instances of {@link SearchResults} must call {@link SearchResults#close()} after the
|
||||
* results are fetched.
|
||||
*
|
||||
* <p>This class is not thread safe.
|
||||
*/
|
||||
@@ -87,12 +91,12 @@ public class SearchResults implements Closeable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a whole page of {@link SearchResult}s.
|
||||
* Retrieves the next page of {@link SearchResult} objects.
|
||||
*
|
||||
* <p>Re-call this method to get next page of {@link SearchResult}, until it returns an empty
|
||||
* list.
|
||||
* <p>The page size is configured by {@link SearchSpec.Builder#setResultCountPerPage}.
|
||||
*
|
||||
* <p>The page size is set by {@link SearchSpec.Builder#setResultCountPerPage}.
|
||||
* <p>Continue calling this method to access results until it returns an empty list, signifying
|
||||
* there are no more results.
|
||||
*
|
||||
* @param callback Callback to receive the pending result of performing this operation.
|
||||
*/
|
||||
|
||||
@@ -30,8 +30,6 @@ import java.util.List;
|
||||
/**
|
||||
* Encapsulates a request to index documents into an {@link AppSearchSession} database.
|
||||
*
|
||||
* <p>@see AppSearchSession#putDocuments
|
||||
*
|
||||
* @see AppSearchSession#put
|
||||
*/
|
||||
public final class PutDocumentsRequest {
|
||||
|
||||
@@ -32,6 +32,41 @@ import java.util.Set;
|
||||
/**
|
||||
* Encapsulates a request to update the schema of an {@link AppSearchSession} database.
|
||||
*
|
||||
* <p>The schema is composed of a collection of {@link AppSearchSchema} objects, each of which
|
||||
* defines a unique type of data.
|
||||
*
|
||||
* <p>The first call to SetSchemaRequest will set the provided schema and store it within the {@link
|
||||
* AppSearchSession} database.
|
||||
*
|
||||
* <p>Subsequent calls will compare the provided schema to the previously saved schema, to determine
|
||||
* how to treat existing documents.
|
||||
*
|
||||
* <p>The following types of schema modifications are always safe and are made without deleting any
|
||||
* existing documents:
|
||||
*
|
||||
* <ul>
|
||||
* <li>Addition of new {@link AppSearchSchema} types
|
||||
* <li>Addition of new properties to an existing {@link AppSearchSchema} type
|
||||
* <li>Changing the cardinality of a property to be less restrictive
|
||||
* </ul>
|
||||
*
|
||||
* <p>The following types of schema changes are not backwards compatible:
|
||||
*
|
||||
* <ul>
|
||||
* <li>Removal of an existing {@link AppSearchSchema} type
|
||||
* <li>Removal of a property from an existing {@link AppSearchSchema} type
|
||||
* <li>Changing the data type of an existing property
|
||||
* <li>Changing the cardinality of a property to be more restrictive
|
||||
* </ul>
|
||||
*
|
||||
* <p>Providing a schema with incompatible changes, will throw an {@link
|
||||
* android.app.appsearch.exceptions.AppSearchException}, with a message describing the
|
||||
* incompatibility. As a result, the previously set schema will remain unchanged.
|
||||
*
|
||||
* <p>Backward incompatible changes can be made by setting {@link
|
||||
* SetSchemaRequest.Builder#setForceOverride} method to {@code true}. This deletes all documents
|
||||
* that are incompatible with the new schema. The new schema is then saved and persisted to disk.
|
||||
*
|
||||
* @see AppSearchSession#setSchema
|
||||
*/
|
||||
public final class SetSchemaRequest {
|
||||
@@ -54,14 +89,15 @@ public final class SetSchemaRequest {
|
||||
mForceOverride = forceOverride;
|
||||
}
|
||||
|
||||
/** Returns the schemas that are part of this request. */
|
||||
/** Returns the {@link AppSearchSchema} types that are part of this request. */
|
||||
@NonNull
|
||||
public Set<AppSearchSchema> getSchemas() {
|
||||
return Collections.unmodifiableSet(mSchemas);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set of schema types that have opted out of being visible on system UI surfaces.
|
||||
* Returns all the schema types that are opted out of being displayed and visible on any system
|
||||
* UI surface.
|
||||
*/
|
||||
@NonNull
|
||||
public Set<String> getSchemasNotVisibleToSystemUi() {
|
||||
@@ -70,10 +106,9 @@ public final class SetSchemaRequest {
|
||||
|
||||
/**
|
||||
* 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[]
|
||||
* certificate.
|
||||
* type.
|
||||
*
|
||||
* <p>This method is inefficient to call repeatedly.
|
||||
* <p>It’s inefficient to call this method repeatedly.
|
||||
*/
|
||||
@NonNull
|
||||
public Map<String, Set<PackageIdentifier>> getSchemasVisibleToPackages() {
|
||||
@@ -91,9 +126,8 @@ public final class SetSchemaRequest {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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[]
|
||||
* certificate.
|
||||
* Returns a mapping of {@link AppSearchSchema} types to the set of packages that have access to
|
||||
* that schema type.
|
||||
*
|
||||
* <p>A more efficient version of {@link #getSchemasVisibleToPackages}, but it returns a
|
||||
* modifiable map. This is not meant to be unhidden and should only be used by internal classes.
|
||||
@@ -110,7 +144,11 @@ public final class SetSchemaRequest {
|
||||
return mForceOverride;
|
||||
}
|
||||
|
||||
/** Builder for {@link SetSchemaRequest} objects. */
|
||||
/**
|
||||
* Builder for {@link SetSchemaRequest} objects.
|
||||
*
|
||||
* <p>Once {@link #build} is called, the instance can no longer be used.
|
||||
*/
|
||||
public static final class Builder {
|
||||
private final Set<AppSearchSchema> mSchemas = new ArraySet<>();
|
||||
private final Set<String> mSchemasNotVisibleToSystemUi = new ArraySet<>();
|
||||
@@ -121,9 +159,11 @@ public final class SetSchemaRequest {
|
||||
private boolean mBuilt = false;
|
||||
|
||||
/**
|
||||
* Adds one or more types to the schema.
|
||||
* Adds one or more {@link AppSearchSchema} types to the schema.
|
||||
*
|
||||
* <p>Any documents of these types will be visible on system UI surfaces by default.
|
||||
* <p>An {@link AppSearchSchema} object represents one type of structured data.
|
||||
*
|
||||
* @throws IllegalStateException if the builder has already been used.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder addSchemas(@NonNull AppSearchSchema... schemas) {
|
||||
@@ -132,9 +172,11 @@ public final class SetSchemaRequest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds one or more types to the schema.
|
||||
* Adds a collection of {@link AppSearchSchema} objects to the schema.
|
||||
*
|
||||
* <p>Any documents of these types will be visible on system UI surfaces by default.
|
||||
* <p>An {@link AppSearchSchema} object represents one type of structured data.
|
||||
*
|
||||
* @throws IllegalStateException if the builder has already been used.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder addSchemas(@NonNull Collection<AppSearchSchema> schemas) {
|
||||
@@ -145,10 +187,17 @@ public final class SetSchemaRequest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets visibility on system UI surfaces for the given {@code schemaType}.
|
||||
* Sets whether or not documents from the provided {@code schemaType} will be displayed and
|
||||
* visible on any system UI surface.
|
||||
*
|
||||
* <p>This setting applies to the provided {@code schemaType} only, and does not persist
|
||||
* across {@link AppSearchSession#setSchema} calls.
|
||||
*
|
||||
* <p>By default, documents are displayed and visible on system UI surfaces.
|
||||
*
|
||||
* @param schemaType The schema type to set visibility on.
|
||||
* @param visible Whether the {@code schemaType} will be visible or not.
|
||||
* @throws IllegalStateException if the builder has already been used.
|
||||
*/
|
||||
// Merged list available from getSchemasNotVisibleToSystemUi
|
||||
@SuppressLint("MissingGetterMatchingBuilder")
|
||||
@@ -167,11 +216,25 @@ public final class SetSchemaRequest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets visibility for a package for the given {@code schemaType}.
|
||||
* Sets whether or not documents from the provided {@code schemaType} can be read by the
|
||||
* specified package.
|
||||
*
|
||||
* <p>Each package is represented by a {@link PackageIdentifier}, containing a package name
|
||||
* and a byte array of type {@link android.content.pm.PackageManager#CERT_INPUT_SHA256}.
|
||||
*
|
||||
* <p>To opt into one-way data sharing with another application, the developer will need to
|
||||
* explicitly grant the other application’s package name and certificate Read access to its
|
||||
* data.
|
||||
*
|
||||
* <p>For two-way data sharing, both applications need to explicitly grant Read access to
|
||||
* one another.
|
||||
*
|
||||
* <p>By default, data sharing between applications is disabled.
|
||||
*
|
||||
* @param schemaType The schema type to set visibility on.
|
||||
* @param visible Whether the {@code schemaType} will be visible or not.
|
||||
* @param packageIdentifier Represents the package that will be granted visibility.
|
||||
* @throws IllegalStateException if the builder has already been used.
|
||||
*/
|
||||
// Merged list available from getSchemasVisibleToPackages
|
||||
@SuppressLint("MissingGetterMatchingBuilder")
|
||||
@@ -224,13 +287,15 @@ public final class SetSchemaRequest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the {@link SetSchemaRequest} to delete any existing documents that don't
|
||||
* follow the new schema.
|
||||
* Sets whether or not to override the current schema in the {@link AppSearchSession}
|
||||
* database.
|
||||
*
|
||||
* <p>By default, this is {@code false} and schema incompatibility causes the {@link
|
||||
* AppSearchSession#setSchema} call to fail.
|
||||
* <p>Call this method whenever backward incompatible changes need to be made by setting
|
||||
* {@code forceOverride} to {@code true}. As a result, during execution of the setSchema
|
||||
* operation, all documents that are incompatible with the new schema will be deleted and
|
||||
* the new schema will be saved and persisted.
|
||||
*
|
||||
* @see AppSearchSession#setSchema
|
||||
* <p>By default, this is {@code false}.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setForceOverride(boolean forceOverride) {
|
||||
@@ -239,10 +304,11 @@ public final class SetSchemaRequest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a new {@link SetSchemaRequest}.
|
||||
* Builds a new {@link SetSchemaRequest} object.
|
||||
*
|
||||
* @throws IllegalArgumentException If schema types were referenced, but the corresponding
|
||||
* {@link AppSearchSchema} was never added.
|
||||
* @throws IllegalArgumentException if schema types were referenced, but the corresponding
|
||||
* {@link AppSearchSchema} type was never added.
|
||||
* @throws IllegalStateException if the builder has already been used.
|
||||
*/
|
||||
@NonNull
|
||||
public SetSchemaRequest build() {
|
||||
|
||||
@@ -654,6 +654,35 @@ public final class AppSearchImpl implements Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a mapping of package names to all the databases owned by that package.
|
||||
*
|
||||
* <p>This method is inefficient to call repeatedly.
|
||||
*/
|
||||
@NonNull
|
||||
public Map<String, Set<String>> getPackageToDatabases() {
|
||||
mReadWriteLock.readLock().lock();
|
||||
try {
|
||||
Map<String, Set<String>> packageToDatabases = new ArrayMap<>();
|
||||
for (String prefix : mSchemaMapLocked.keySet()) {
|
||||
String packageName = getPackageName(prefix);
|
||||
|
||||
Set<String> databases = packageToDatabases.get(packageName);
|
||||
if (databases == null) {
|
||||
databases = new ArraySet<>();
|
||||
packageToDatabases.put(packageName, databases);
|
||||
}
|
||||
|
||||
String databaseName = getDatabaseName(prefix);
|
||||
databases.add(databaseName);
|
||||
}
|
||||
|
||||
return packageToDatabases;
|
||||
} finally {
|
||||
mReadWriteLock.readLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@GuardedBy("mReadWriteLock")
|
||||
private SearchResultPage doQueryLocked(
|
||||
@NonNull Set<String> prefixes,
|
||||
@@ -1211,26 +1240,8 @@ public final class AppSearchImpl implements Closeable {
|
||||
return schemaProto.getSchema();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the {@code packageName} and {@code databaseName} has the {@code schemaType}
|
||||
*/
|
||||
@GuardedBy("mReadWriteLock")
|
||||
boolean hasSchemaTypeLocked(
|
||||
@NonNull String packageName, @NonNull String databaseName, @NonNull String schemaType) {
|
||||
Preconditions.checkNotNull(packageName);
|
||||
Preconditions.checkNotNull(databaseName);
|
||||
Preconditions.checkNotNull(schemaType);
|
||||
|
||||
String prefix = createPrefix(packageName, databaseName);
|
||||
Set<String> schemaTypes = mSchemaMapLocked.get(prefix);
|
||||
if (schemaTypes == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return schemaTypes.contains(prefix + schemaType);
|
||||
}
|
||||
|
||||
/** Returns a set of all prefixes AppSearchImpl knows about. */
|
||||
// TODO(b/180058203): Remove this method once platform has switched away from using this method.
|
||||
@GuardedBy("mReadWriteLock")
|
||||
@NonNull
|
||||
Set<String> getPrefixesLocked() {
|
||||
|
||||
@@ -1 +1 @@
|
||||
I895f5fb3bcb4be0642c6193000e57d80aafe2166
|
||||
I593dfd22279739e5f578e07d36a55cf02ee942c5
|
||||
|
||||
@@ -33,90 +33,16 @@ import java.util.Set;
|
||||
public interface AppSearchSessionShim extends Closeable {
|
||||
|
||||
/**
|
||||
* Sets the schema that will be used by documents provided to the {@link #put} method.
|
||||
* Sets the schema that represents the organizational structure of data within the AppSearch
|
||||
* database.
|
||||
*
|
||||
* <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:
|
||||
* <p>Upon creating an {@link AppSearchSessionShim}, {@link #setSchema} should be called. If the
|
||||
* schema needs to be updated, or it has not been previously set, then the provided schema will
|
||||
* be saved and persisted to disk. Otherwise, {@link #setSchema} is handled efficiently as a
|
||||
* no-op call.
|
||||
*
|
||||
* <ul>
|
||||
* <li>Addition of new types
|
||||
* <li>Addition of new {@link AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL OPTIONAL} or
|
||||
* {@link 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
|
||||
* AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL OPTIONAL} property into a {@link
|
||||
* AppSearchSchema.PropertyConfig#CARDINALITY_REPEATED REPEATED} property.
|
||||
* </ul>
|
||||
*
|
||||
* <p>The following types of schema changes are not backwards-compatible:
|
||||
*
|
||||
* <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}s
|
||||
* of that property
|
||||
* <li>Changing the cardinality of a data type to be more restrictive (e.g. changing an {@link
|
||||
* AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL OPTIONAL} property into a {@link
|
||||
* AppSearchSchema.PropertyConfig#CARDINALITY_REQUIRED REQUIRED} property).
|
||||
* <li>Adding a {@link AppSearchSchema.PropertyConfig#CARDINALITY_REQUIRED REQUIRED} property.
|
||||
* </ul>
|
||||
*
|
||||
* <p>Supplying a schema with such changes will, by default, result in this call completing its
|
||||
* future with an {@link android.app.appsearch.exceptions.AppSearchException} with a code of
|
||||
* {@link AppSearchResult#RESULT_INVALID_SCHEMA} and a message describing the incompatibility.
|
||||
* In this case the previously set schema will remain active.
|
||||
*
|
||||
* <p>If you need to make non-backwards-compatible changes as described above, you can either:
|
||||
*
|
||||
* <ul>
|
||||
* <li>Set the {@link SetSchemaRequest.Builder#setForceOverride} method to {@code true}. In
|
||||
* this case, instead of completing its future with an {@link
|
||||
* android.app.appsearch.exceptions.AppSearchException} with the {@link
|
||||
* AppSearchResult#RESULT_INVALID_SCHEMA} error code, all documents which are not
|
||||
* compatible with the new schema will be deleted and the incompatible schema will be
|
||||
* applied. Incompatible types and deleted types will be set into {@link
|
||||
* SetSchemaResponse#getIncompatibleTypes()} and {@link
|
||||
* SetSchemaResponse#getDeletedTypes()}, respectively.
|
||||
* <li>Add a {@link android.app.appsearch.AppSearchSchema.Migrator} for each incompatible type
|
||||
* and make no deletion. The migrator will migrate documents from it's old schema version
|
||||
* to the new version. Migrated types will be set into both {@link
|
||||
* SetSchemaResponse#getIncompatibleTypes()} and {@link
|
||||
* SetSchemaResponse#getMigratedTypes()}. See the migration section below.
|
||||
* </ul>
|
||||
*
|
||||
* <p>It is a no-op to set the same schema as has been previously set; this is handled
|
||||
* efficiently.
|
||||
*
|
||||
* <p>By default, documents are visible on platform surfaces. To opt out, call {@code
|
||||
* SetSchemaRequest.Builder#setPlatformSurfaceable} with {@code surfaceable} as false. Any
|
||||
* visibility settings apply only to the schemas that are included in the {@code request}.
|
||||
* Visibility settings for a schema type do not apply or persist across {@link
|
||||
* SetSchemaRequest}s.
|
||||
*
|
||||
* <p>Migration: make non-backwards-compatible changes will delete all stored documents in old
|
||||
* schema. You can save your documents by setting {@link
|
||||
* android.app.appsearch.AppSearchSchema.Migrator} via the {@link
|
||||
* SetSchemaRequest.Builder#setMigrator} for each type you want to save.
|
||||
*
|
||||
* <p>{@link android.app.appsearch.AppSearchSchema.Migrator#onDowngrade} or {@link
|
||||
* android.app.appsearch.AppSearchSchema.Migrator#onUpgrade} will be triggered if the version
|
||||
* number of the schema stored in AppSearch is different with the version in the request.
|
||||
*
|
||||
* <p>If any error or Exception occurred in the {@link
|
||||
* android.app.appsearch.AppSearchSchema.Migrator#onDowngrade}, {@link
|
||||
* android.app.appsearch.AppSearchSchema.Migrator#onUpgrade} or {@link
|
||||
* android.app.appsearch.AppSearchMigrationHelper.Transformer#transform}, the migration will be
|
||||
* terminated, the setSchema request will be rejected unless the schema changes are
|
||||
* backwards-compatible, and stored documents won't have any observable changes.
|
||||
*
|
||||
* @param request The schema update request.
|
||||
* @return A {@link ListenableFuture} with exception if we hit any error. Or the pending {@link
|
||||
* SetSchemaResponse} of performing this operation, if the schema has been successfully set.
|
||||
* @see android.app.appsearch.AppSearchSchema.Migrator
|
||||
* @see android.app.appsearch.AppSearchMigrationHelper.Transformer
|
||||
* @param request the schema to set or update the AppSearch database to.
|
||||
* @return a {@link ListenableFuture} which resolves to a {@link SetSchemaResponse} object.
|
||||
*/
|
||||
// TODO(b/169883602): Change @code references to @link when setPlatformSurfaceable APIs are
|
||||
// exposed.
|
||||
|
||||
@@ -28,6 +28,7 @@ import android.app.appsearch.SearchSpec;
|
||||
import android.app.appsearch.SetSchemaResponse;
|
||||
import android.app.appsearch.exceptions.AppSearchException;
|
||||
import android.content.Context;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
@@ -55,6 +56,7 @@ import org.junit.rules.TemporaryFolder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class AppSearchImplTest {
|
||||
@@ -971,21 +973,46 @@ public class AppSearchImplTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHasSchemaType() throws Exception {
|
||||
// Nothing exists yet
|
||||
assertThat(mAppSearchImpl.hasSchemaTypeLocked("package", "database", "Schema")).isFalse();
|
||||
public void testGetPackageToDatabases() throws Exception {
|
||||
Map<String, Set<String>> existingMapping = mAppSearchImpl.getPackageToDatabases();
|
||||
Map<String, Set<String>> expectedMapping = new ArrayMap<>();
|
||||
expectedMapping.putAll(existingMapping);
|
||||
|
||||
// Has database1
|
||||
expectedMapping.put("package1", ImmutableSet.of("database1"));
|
||||
mAppSearchImpl.setSchema(
|
||||
"package",
|
||||
"database",
|
||||
Collections.singletonList(new AppSearchSchema.Builder("Schema").build()),
|
||||
"package1",
|
||||
"database1",
|
||||
Collections.singletonList(new AppSearchSchema.Builder("schema").build()),
|
||||
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
|
||||
/*schemasPackageAccessible=*/ Collections.emptyMap(),
|
||||
/*forceOverride=*/ false);
|
||||
assertThat(mAppSearchImpl.hasSchemaTypeLocked("package", "database", "Schema")).isTrue();
|
||||
assertThat(mAppSearchImpl.getPackageToDatabases())
|
||||
.containsExactlyEntriesIn(expectedMapping);
|
||||
|
||||
assertThat(mAppSearchImpl.hasSchemaTypeLocked("package", "database", "UnknownSchema"))
|
||||
.isFalse();
|
||||
// Has both databases
|
||||
expectedMapping.put("package1", ImmutableSet.of("database1", "database2"));
|
||||
mAppSearchImpl.setSchema(
|
||||
"package1",
|
||||
"database2",
|
||||
Collections.singletonList(new AppSearchSchema.Builder("schema").build()),
|
||||
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
|
||||
/*schemasPackageAccessible=*/ Collections.emptyMap(),
|
||||
/*forceOverride=*/ false);
|
||||
assertThat(mAppSearchImpl.getPackageToDatabases())
|
||||
.containsExactlyEntriesIn(expectedMapping);
|
||||
|
||||
// Has both packages
|
||||
expectedMapping.put("package2", ImmutableSet.of("database1"));
|
||||
mAppSearchImpl.setSchema(
|
||||
"package2",
|
||||
"database1",
|
||||
Collections.singletonList(new AppSearchSchema.Builder("schema").build()),
|
||||
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
|
||||
/*schemasPackageAccessible=*/ Collections.emptyMap(),
|
||||
/*forceOverride=*/ false);
|
||||
assertThat(mAppSearchImpl.getPackageToDatabases())
|
||||
.containsExactlyEntriesIn(expectedMapping);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user