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

Commit d43a1263 authored by Alexander Dorokhine's avatar Alexander Dorokhine Committed by Automerger Merge Worker
Browse files

Merge "Update Framework from Jetpack." into sc-dev am: d3e7d8c0

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13555624

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: Iece05680744fe69158f2768c9cf02fb6960c5246
parents 1cd99232 d3e7d8c0
Loading
Loading
Loading
Loading
+34 −8
Original line number Diff line number Diff line
@@ -37,24 +37,36 @@ import java.util.Map;
public final class AppSearchBatchResult<KeyType, ValueType> implements Parcelable {
    @NonNull private final Map<KeyType, ValueType> mSuccesses;
    @NonNull private final Map<KeyType, AppSearchResult<ValueType>> mFailures;
    @NonNull private final Map<KeyType, AppSearchResult<ValueType>> mAll;

    AppSearchBatchResult(
            @NonNull Map<KeyType, ValueType> successes,
            @NonNull Map<KeyType, AppSearchResult<ValueType>> failures) {
            @NonNull Map<KeyType, AppSearchResult<ValueType>> failures,
            @NonNull Map<KeyType, AppSearchResult<ValueType>> all) {
        mSuccesses = successes;
        mFailures = failures;
        mAll = all;
    }

    private AppSearchBatchResult(@NonNull Parcel in) {
        mSuccesses = Collections.unmodifiableMap(in.readHashMap(/*loader=*/ null));
        mFailures = Collections.unmodifiableMap(in.readHashMap(/*loader=*/ null));
        mAll = Collections.unmodifiableMap(in.readHashMap(/*loader=*/ null));
        Map<KeyType, ValueType> successes = new ArrayMap<>();
        Map<KeyType, AppSearchResult<ValueType>> failures = new ArrayMap<>();
        for (Map.Entry<KeyType, AppSearchResult<ValueType>> entry : mAll.entrySet()) {
            if (entry.getValue().isSuccess()) {
                successes.put(entry.getKey(), entry.getValue().getResultValue());
            } else {
                failures.put(entry.getKey(), entry.getValue());
            }
        }
        mSuccesses = Collections.unmodifiableMap(successes);
        mFailures = Collections.unmodifiableMap(failures);
    }

    /** @hide */
    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeMap(mSuccesses);
        dest.writeMap(mFailures);
        dest.writeMap(mAll);
    }

    /** Returns {@code true} if this {@link AppSearchBatchResult} has no failures. */
@@ -63,8 +75,8 @@ 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 all successful keys mapped to the successful {@link
     * AppSearchResult}s they produced.
     *
     * <p>The values of the {@link Map} will not be {@code null}.
     */
@@ -84,8 +96,20 @@ public final class AppSearchBatchResult<KeyType, ValueType> implements Parcelabl
        return mFailures;
    }

    /**
     * Returns a {@link Map} of all keys mapped to the {@link AppSearchResult}s they produced.
     *
     * <p>The values of the {@link Map} will not be {@code null}.
     * @hide
     */
    @NonNull
    public Map<KeyType, AppSearchResult<ValueType>> getAll() {
        return mAll;
    }

    /**
     * Asserts that this {@link AppSearchBatchResult} has no failures.
     *
     * @hide
     */
    public void checkSuccess() {
@@ -133,6 +157,7 @@ public final class AppSearchBatchResult<KeyType, ValueType> implements Parcelabl
    public static final class Builder<KeyType, ValueType> {
        private final Map<KeyType, ValueType> mSuccesses = new ArrayMap<>();
        private final Map<KeyType, AppSearchResult<ValueType>> mFailures = new ArrayMap<>();
        private final Map<KeyType, AppSearchResult<ValueType>> mAll = new ArrayMap<>();
        private boolean mBuilt = false;

        /**
@@ -181,6 +206,7 @@ public final class AppSearchBatchResult<KeyType, ValueType> implements Parcelabl
                mFailures.put(key, result);
                mSuccesses.remove(key);
            }
            mAll.put(key, result);
            return this;
        }

@@ -189,7 +215,7 @@ public final class AppSearchBatchResult<KeyType, ValueType> implements Parcelabl
        public AppSearchBatchResult<KeyType, ValueType> build() {
            Preconditions.checkState(!mBuilt, "Builder has already been used");
            mBuilt = true;
            return new AppSearchBatchResult<>(mSuccesses, mFailures);
            return new AppSearchBatchResult<>(mSuccesses, mFailures, mAll);
        }
    }
}
+25 −18
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.annotation.Nullable;
import android.app.appsearch.exceptions.AppSearchException;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;

import java.io.IOException;
import java.lang.annotation.Retention;
@@ -35,10 +36,12 @@ import java.util.Objects;
 */
public final class AppSearchResult<ValueType> implements Parcelable {
    /**
     * Result codes from {@link AppSearchManager} methods.
     * Result codes from {@link AppSearchSession} methods.
     *
     * @hide
     */
    @IntDef(value = {
    @IntDef(
            value = {
                RESULT_OK,
                RESULT_UNKNOWN_ERROR,
                RESULT_INTERNAL_ERROR,
@@ -60,21 +63,21 @@ public final class AppSearchResult<ValueType> implements Parcelable {
    /**
     * An internal error occurred within AppSearch, which the caller cannot address.
     *
     * This error may be considered similar to {@link IllegalStateException}
     * <p>This error may be considered similar to {@link IllegalStateException}
     */
    public static final int RESULT_INTERNAL_ERROR = 2;

    /**
     * The caller supplied invalid arguments to the call.
     *
     * This error may be considered similar to {@link IllegalArgumentException}.
     * <p>This error may be considered similar to {@link IllegalArgumentException}.
     */
    public static final int RESULT_INVALID_ARGUMENT = 3;

    /**
     * An issue occurred reading or writing to storage. The call might succeed if repeated.
     *
     * This error may be considered similar to {@link java.io.IOException}.
     * <p>This error may be considered similar to {@link java.io.IOException}.
     */
    public static final int RESULT_IO_ERROR = 4;

@@ -127,7 +130,7 @@ public final class AppSearchResult<ValueType> implements Parcelable {
    /**
     * Returns the result value associated with this result, if it was successful.
     *
     * <p>See the documentation of the particular {@link AppSearchManager} call producing this
     * <p>See the documentation of the particular {@link AppSearchSession} call producing this
     * {@link AppSearchResult} for what is placed in the result value by that call.
     *
     * @throws IllegalStateException if this {@link AppSearchResult} is not successful.
@@ -145,8 +148,8 @@ public final class AppSearchResult<ValueType> implements Parcelable {
     *
     * <p>If {@link #isSuccess} is {@code true}, the error message is always {@code null}. The error
     * message may be {@code null} even if {@link #isSuccess} is {@code false}. See the
     * documentation of the particular {@link AppSearchManager} call producing this
     * {@link AppSearchResult} for what is returned by {@link #getErrorMessage}.
     * documentation of the particular {@link AppSearchSession} call producing this {@link
     * AppSearchResult} for what is returned by {@link #getErrorMessage}.
     */
    @Nullable
    public String getErrorMessage() {
@@ -205,6 +208,7 @@ public final class AppSearchResult<ValueType> implements Parcelable {

    /**
     * Creates a new successful {@link AppSearchResult}.
     *
     * @hide
     */
    @NonNull
@@ -215,6 +219,7 @@ public final class AppSearchResult<ValueType> implements Parcelable {

    /**
     * Creates a new failed {@link AppSearchResult}.
     *
     * @hide
     */
    @NonNull
@@ -227,6 +232,8 @@ public final class AppSearchResult<ValueType> implements Parcelable {
    @NonNull
    public static <ValueType> AppSearchResult<ValueType> throwableToFailedResult(
            @NonNull Throwable t) {
        Log.d("AppSearchResult", "Converting throwable to failed result.", t);

        if (t instanceof AppSearchException) {
            return ((AppSearchException) t).toAppSearchResult();
        }
@@ -241,6 +248,6 @@ public final class AppSearchResult<ValueType> implements Parcelable {
        } else {
            resultCode = AppSearchResult.RESULT_UNKNOWN_ERROR;
        }
        return AppSearchResult.newFailedResult(resultCode, t.toString());
        return AppSearchResult.newFailedResult(resultCode, t.getMessage());
    }
}
+142 −88
Original line number Diff line number Diff line
@@ -108,54 +108,85 @@ public final class AppSearchSession implements Closeable {
     * 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 AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL OPTIONAL} or
     *   <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.
     *   <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.
     *   <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 returning an
     * {@link AppSearchResult} with a code of {@link AppSearchResult#RESULT_INVALID_SCHEMA} and an
     * error 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 set the
     * {@link SetSchemaRequest.Builder#setForceOverride} method to {@code true}. In this case,
     * instead of returning an {@link AppSearchResult} 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.
     * <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
     * {@link SetSchemaRequest.Builder#setSchemaTypeVisibilityForSystemUi} with {@code visible} 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 persist across
     * {@link #setSchema} calls.
     * <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 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
     */
    public void setSchema(
            @NonNull SetSchemaRequest request,
@@ -193,11 +224,9 @@ public final class AppSearchSession implements Closeable {
                            executor.execute(() -> {
                                if (result.isSuccess()) {
                                    callback.accept(
                                            // TODO(b/151178558) implement Migration in platform.
                                            // TODO(b/177266929) implement Migration in platform.
                                            AppSearchResult.newSuccessfulResult(
                                                    new SetSchemaResponse.Builder().setResultCode(
                                                            result.getResultCode())
                                                            .build()));
                                                    new SetSchemaResponse.Builder().build()));
                                } else {
                                    callback.accept(result);
                                }
@@ -297,9 +326,10 @@ public final class AppSearchSession implements Closeable {
    }

    /**
     * Retrieves {@link GenericDocument}s by URI.
     * Gets {@link GenericDocument} objects by URIs and namespace from the {@link AppSearchSession}
     * database.
     *
     * @param request  {@link GetByUriRequest} containing URIs to be retrieved.
     * @param request a request containing URIs and namespace to get documents for.
     * @param executor Executor on which to invoke the callback.
     * @param callback Callback to receive the pending result of performing this operation. The keys
     *                 of the returned {@link AppSearchBatchResult} are the input URIs. The values
@@ -377,48 +407,65 @@ public final class AppSearchSession implements Closeable {
    }

    /**
     * Searches a document based on a given query string.
     * Retrieves documents from the open {@link AppSearchSession} that match a given query string
     * and type of search provided.
     *
     * <p>Query strings can be empty, contain one term with no operators, or contain multiple terms
     * and operators.
     *
     * <p>For query strings that are empty, all documents that match the {@link SearchSpec} will be
     * returned.
     *
     * <p>For query strings with a single term and no operators, documents that match the provided
     * query string and {@link SearchSpec} will be returned.
     *
     * <p>The following operators are supported:
     *
     * <p>Currently we support following features in the raw query format:
     * <ul>
     *     <li>AND
     *     <p>AND joins (e.g. “match documents that have both the terms ‘dog’ and
     *     ‘cat’”).
     *     Example: hello world matches documents that have both ‘hello’ and ‘world’
     *   <li>AND (implicit)
     *       <p>AND is an operator that matches documents that contain <i>all</i> provided terms.
     *       <p><b>NOTE:</b> A space between terms is treated as an "AND" operator. Explicitly
     *       including "AND" in a query string will treat "AND" as a term, returning documents that
     *       also contain "AND".
     *       <p>Example: "apple AND banana" matches documents that contain the terms "apple", "and",
     *       "banana".
     *       <p>Example: "apple banana" matches documents that contain both "apple" and "banana".
     *       <p>Example: "apple banana cherry" matches documents that contain "apple", "banana", and
     *       "cherry".
     *   <li>OR
     *     <p>OR joins (e.g. “match documents that have either the term ‘dog’ or
     *     ‘cat’”).
     *     Example: dog OR puppy
     *     <li>Exclusion
     *     <p>Exclude a term (e.g. “match documents that do
     *     not have the term ‘dog’”).
     *     Example: -dog excludes the term ‘dog’
     *     <li>Grouping terms
     *     <p>Allow for conceptual grouping of subqueries to enable hierarchical structures (e.g.
     *     “match documents that have either ‘dog’ or ‘puppy’, and either ‘cat’ or ‘kitten’”).
     *     Example: (dog puppy) (cat kitten) two one group containing two terms.
     *     <li>Property restricts
     *     <p> Specifies which properties of a document to specifically match terms in (e.g.
     *     “match documents where the ‘subject’ property contains ‘important’”).
     *     Example: subject:important matches documents with the term ‘important’ in the
     *     ‘subject’ property
     *     <li>Schema type restricts
     *     <p>This is similar to property restricts, but allows for restricts on top-level document
     *     fields, such as schema_type. Clients should be able to limit their query to documents of
     *     a certain schema_type (e.g. “match documents that are of the ‘Email’ schema_type”).
     *     Example: { schema_type_filters: “Email”, “Video”,query: “dog” } will match documents
     *     that contain the query term ‘dog’ and are of either the ‘Email’ schema type or the
     *     ‘Video’ schema type.
     *       <p>OR is an operator that matches documents that contain <i>any</i> provided term.
     *       <p>Example: "apple OR banana" matches documents that contain either "apple" or
     *       "banana".
     *       <p>Example: "apple OR banana OR cherry" matches documents that contain any of "apple",
     *       "banana", or "cherry".
     *   <li>Exclusion (-)
     *       <p>Exclusion (-) is an operator that matches documents that <i>do not</i> contain the
     *       provided term.
     *       <p>Example: "-apple" matches documents that do not contain "apple".
     *   <li>Grouped Terms
     *       <p>For queries that require multiple operators and terms, terms can be grouped into
     *       subqueries. Subqueries are contained within an open "(" and close ")" parenthesis.
     *       <p>Example: "(donut OR bagel) (coffee OR tea)" matches documents that contain either
     *       "donut" or "bagel" and either "coffee" or "tea".
     *   <li>Property Restricts
     *       <p>For queries that require a term to match a specific {@link AppSearchSchema} property
     *       of a document, a ":" must be included between the property name and the term.
     *       <p>Example: "subject:important" matches documents that contain the term "important" in
     *       the "subject" property.
     * </ul>
     *
     * <p> This method is lightweight. The heavy work will be done in
     * {@link SearchResults#getNextPage}.
     * <p>Additional search specifications, such as filtering by {@link AppSearchSchema} type or
     * adding projection, can be set by calling the corresponding {@link SearchSpec.Builder} setter.
     *
     * @param queryExpression Query String to search.
     * @param searchSpec      Spec for setting filters, raw query etc.
     * <p>This method is lightweight. The heavy work will be done in {@link
     * SearchResults#getNextPage}.
     *
     * @param queryExpression query string to search.
     * @param searchSpec spec for setting document filters, adding projection, setting term match
     *     type, etc.
     * @param executor        Executor on which to invoke the callback of the following request
     *                        {@link SearchResults#getNextPage}.
     * @return The search result of performing this operation.
     * @return a {@link SearchResults} object for retrieved matched documents.
     */
    @NonNull
    public SearchResults search(
@@ -440,8 +487,8 @@ public final class AppSearchSession implements Closeable {
     *
     * <p>For each call to {@link #reportUsage}, AppSearch updates usage count and usage recency
     * metrics for that particular document. These metrics are used for ordering {@link #search}
     * results by the {@link SearchSpec#RANKING_STRATEGY_USAGE_COUNT} and
     * {@link SearchSpec#RANKING_STRATEGY_USAGE_LAST_USED_TIMESTAMP} ranking strategies.
     * results by the {@link SearchSpec#RANKING_STRATEGY_USAGE_COUNT} and {@link
     * SearchSpec#RANKING_STRATEGY_USAGE_LAST_USED_TIMESTAMP} ranking strategies.
     *
     * <p>Reporting usage of a document is optional.
     *
@@ -479,9 +526,17 @@ public final class AppSearchSession implements Closeable {
    }

    /**
     * Removes {@link GenericDocument}s from the index by URI.
     * Removes {@link GenericDocument} objects by URIs and namespace from the {@link
     * AppSearchSession} database.
     *
     * <p>Removed documents will no longer be surfaced by {@link #search} or {@link #getByUri}
     * calls.
     *
     * <p><b>NOTE:</b>By default, documents are removed via a soft delete operation. Once the
     * document crosses the count threshold or byte usage threshold, the documents will be removed
     * from disk.
     *
     * @param request  Request containing URIs to be removed.
     * @param request {@link RemoveByUriRequest} with URIs and namespace to remove from the index.
     * @param executor Executor on which to invoke the callback.
     * @param callback Callback to receive the pending result of performing this operation. The keys
     *                 of the returned {@link AppSearchBatchResult} are the input URIs. The values
@@ -520,19 +575,18 @@ public final class AppSearchSession implements Closeable {

    /**
     * Removes {@link GenericDocument}s from the index by Query. Documents will be removed if they
     * match the {@code queryExpression} in given namespaces and schemaTypes which is set via
     * {@link SearchSpec.Builder#addFilterNamespaces} and
     * {@link SearchSpec.Builder#addFilterSchemas}.
     * match the {@code queryExpression} in given namespaces and schemaTypes which is set via {@link
     * SearchSpec.Builder#addFilterNamespaces} and {@link SearchSpec.Builder#addFilterSchemas}.
     *
     * <p>An empty {@code queryExpression} matches all documents.
     *
     * <p> An empty set of namespaces or schemaTypes matches all namespaces or schemaTypes in
     * the current database.
     * <p>An empty set of namespaces or schemaTypes matches all namespaces or schemaTypes in the
     * current database.
     *
     * @param queryExpression Query String to search.
     * @param searchSpec      Spec containing schemaTypes, namespaces and query expression indicates
     *                        how document will be removed. All specific about how to scoring,
     *                        ordering, snippeting and resulting will be ignored.
     * @param searchSpec Spec containing schemaTypes, namespaces and query expression indicates how
     *     document will be removed. All specific about how to scoring, ordering, snippeting and
     *     resulting will be ignored.
     * @param executor        Executor on which to invoke the callback.
     * @param callback        Callback to receive errors resulting from removing the documents. If
     *                        the operation succeeds, the callback will be invoked with
+17 −39

File changed.

Preview size limit exceeded, changes collapsed.

+4 −4

File changed.

Preview size limit exceeded, changes collapsed.

Loading