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

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

Merge "Merge GenericDocument and SearchResult work from Jetpack."

parents 4688072c bd6bcf6a
Loading
Loading
Loading
Loading
+21 −37
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 * Copyright 2020 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.
@@ -16,20 +16,26 @@

package android.app.appsearch;


import android.annotation.NonNull;
import android.annotation.Nullable;

import android.app.appsearch.AppSearchSchema.PropertyConfig;

/**
 * Encapsulates a {@link AppSearchDocument} that represent an email.
 * Encapsulates a {@link GenericDocument} that represent an email.
 *
 * <p>This class is a higher level implement of {@link AppSearchDocument}.
 * <p>This class is a higher level implement of {@link GenericDocument}.
 *
 * <p>This class will eventually migrate to Jetpack, where it will become public API.
 *
 * @hide
 */
public class AppSearchEmail extends AppSearchDocument {

public class AppSearchEmail extends GenericDocument {
    /** The name of the schema type for {@link AppSearchEmail} documents.*/
    public static final String SCHEMA_TYPE = "builtin:Email";

    private static final String KEY_FROM = "from";
    private static final String KEY_TO = "to";
    private static final String KEY_CC = "cc";
@@ -37,46 +43,43 @@ public class AppSearchEmail extends AppSearchDocument {
    private static final String KEY_SUBJECT = "subject";
    private static final String KEY_BODY = "body";

    /** The name of the schema type for {@link AppSearchEmail} documents.*/
    public static final String SCHEMA_TYPE = "builtin:Email";

    public static final AppSearchSchema SCHEMA = new AppSearchSchema.Builder(SCHEMA_TYPE)
            .addProperty(new AppSearchSchema.PropertyConfig.Builder(KEY_FROM)
            .addProperty(new PropertyConfig.Builder(KEY_FROM)
                    .setDataType(PropertyConfig.DATA_TYPE_STRING)
                    .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
                    .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
                    .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
                    .build()

            ).addProperty(new AppSearchSchema.PropertyConfig.Builder(KEY_TO)
            ).addProperty(new PropertyConfig.Builder(KEY_TO)
                    .setDataType(PropertyConfig.DATA_TYPE_STRING)
                    .setCardinality(PropertyConfig.CARDINALITY_REPEATED)
                    .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
                    .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
                    .build()

            ).addProperty(new AppSearchSchema.PropertyConfig.Builder(KEY_CC)
            ).addProperty(new PropertyConfig.Builder(KEY_CC)
                    .setDataType(PropertyConfig.DATA_TYPE_STRING)
                    .setCardinality(PropertyConfig.CARDINALITY_REPEATED)
                    .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
                    .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
                    .build()

            ).addProperty(new AppSearchSchema.PropertyConfig.Builder(KEY_BCC)
            ).addProperty(new PropertyConfig.Builder(KEY_BCC)
                    .setDataType(PropertyConfig.DATA_TYPE_STRING)
                    .setCardinality(PropertyConfig.CARDINALITY_REPEATED)
                    .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
                    .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
                    .build()

            ).addProperty(new AppSearchSchema.PropertyConfig.Builder(KEY_SUBJECT)
            ).addProperty(new PropertyConfig.Builder(KEY_SUBJECT)
                    .setDataType(PropertyConfig.DATA_TYPE_STRING)
                    .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
                    .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
                    .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
                    .build()

            ).addProperty(new AppSearchSchema.PropertyConfig.Builder(KEY_BODY)
            ).addProperty(new PropertyConfig.Builder(KEY_BODY)
                    .setDataType(PropertyConfig.DATA_TYPE_STRING)
                    .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
                    .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
@@ -87,12 +90,11 @@ public class AppSearchEmail extends AppSearchDocument {

    /**
     * Creates a new {@link AppSearchEmail} from the contents of an existing
     * {@link AppSearchDocument}.
     * {@link GenericDocument}.
     *
     * @param document The {@link AppSearchDocument} containing the email content.
     * @hide
     * @param document The {@link GenericDocument} containing the email content.
     */
    public AppSearchEmail(@NonNull AppSearchDocument document) {
    public AppSearchEmail(@NonNull GenericDocument document) {
        super(document);
    }

@@ -101,7 +103,6 @@ public class AppSearchEmail extends AppSearchDocument {
     *
     * @return Returns the subject of {@link AppSearchEmail} or {@code null} if it's not been set
     *         yet.
     * @hide
     */
    @Nullable
    public String getFrom() {
@@ -113,7 +114,6 @@ public class AppSearchEmail extends AppSearchDocument {
     *
     * @return Returns the destination addresses of {@link AppSearchEmail} or {@code null} if it's
     *         not been set yet.
     * @hide
     */
    @Nullable
    public String[] getTo() {
@@ -125,7 +125,6 @@ public class AppSearchEmail extends AppSearchDocument {
     *
     * @return Returns the CC list of {@link AppSearchEmail} or {@code null} if it's not been set
     *         yet.
     * @hide
     */
    @Nullable
    public String[] getCc() {
@@ -137,7 +136,6 @@ public class AppSearchEmail extends AppSearchDocument {
     *
     * @return Returns the BCC list of {@link AppSearchEmail} or {@code null} if it's not been set
     *         yet.
     * @hide
     */
    @Nullable
    public String[] getBcc() {
@@ -149,7 +147,6 @@ public class AppSearchEmail extends AppSearchDocument {
     *
     * @return Returns the value subject of {@link AppSearchEmail} or {@code null} if it's not been
     *         set yet.
     * @hide
     */
    @Nullable
    public String getSubject() {
@@ -160,7 +157,6 @@ public class AppSearchEmail extends AppSearchDocument {
     * Get the body of {@link AppSearchEmail}.
     *
     * @return Returns the body of {@link AppSearchEmail} or {@code null} if it's not been set yet.
     * @hide
     */
    @Nullable
    public String getBody() {
@@ -169,14 +165,12 @@ public class AppSearchEmail extends AppSearchDocument {

    /**
     * The builder class for {@link AppSearchEmail}.
     * @hide
     */
    public static class Builder extends AppSearchDocument.Builder<AppSearchEmail.Builder> {
    public static class Builder extends GenericDocument.Builder<AppSearchEmail.Builder> {

        /**
         * Create a new {@link AppSearchEmail.Builder}
         * @param uri The Uri of the Email.
         * @hide
         */
        public Builder(@NonNull String uri) {
            super(uri, SCHEMA_TYPE);
@@ -184,7 +178,6 @@ public class AppSearchEmail extends AppSearchDocument {

        /**
         * Set the from address of {@link AppSearchEmail}
         * @hide
         */
        @NonNull
        public AppSearchEmail.Builder setFrom(@NonNull String from) {
@@ -194,7 +187,6 @@ public class AppSearchEmail extends AppSearchDocument {

        /**
         * Set the destination address of {@link AppSearchEmail}
         * @hide
         */
        @NonNull
        public AppSearchEmail.Builder setTo(@NonNull String... to) {
@@ -204,7 +196,6 @@ public class AppSearchEmail extends AppSearchDocument {

        /**
         * Set the CC list of {@link AppSearchEmail}
         * @hide
         */
        @NonNull
        public AppSearchEmail.Builder setCc(@NonNull String... cc) {
@@ -214,7 +205,6 @@ public class AppSearchEmail extends AppSearchDocument {

        /**
         * Set the BCC list of {@link AppSearchEmail}
         * @hide
         */
        @NonNull
        public AppSearchEmail.Builder setBcc(@NonNull String... bcc) {
@@ -224,7 +214,6 @@ public class AppSearchEmail extends AppSearchDocument {

        /**
         * Set the subject of {@link AppSearchEmail}
         * @hide
         */
        @NonNull
        public AppSearchEmail.Builder setSubject(@NonNull String subject) {
@@ -234,7 +223,6 @@ public class AppSearchEmail extends AppSearchDocument {

        /**
         * Set the body of {@link AppSearchEmail}
         * @hide
         */
        @NonNull
        public AppSearchEmail.Builder setBody(@NonNull String body) {
@@ -242,11 +230,7 @@ public class AppSearchEmail extends AppSearchDocument {
            return this;
        }

        /**
         * Builds the {@link AppSearchEmail} object.
         *
         * @hide
         */
        /** Builds the {@link AppSearchEmail} object. */
        @NonNull
        @Override
        public AppSearchEmail build() {
+37 −65
Original line number Diff line number Diff line
@@ -23,11 +23,6 @@ import android.os.RemoteException;

import com.android.internal.infra.AndroidFuture;

import com.google.android.icing.proto.DocumentProto;
import com.google.android.icing.proto.SearchResultProto;
import com.google.android.icing.proto.StatusProto;
import com.google.protobuf.InvalidProtocolBufferException;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -78,8 +73,8 @@ public class AppSearchManager {
     *     <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 AppSearchDocument} type, changing the schema type of
     *         {@code AppSearchDocument}s of that property
     *     <li>For properties of {@code GenericDocument} type, changing the schema type of
     *         {@code GenericDocument}s 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
@@ -148,31 +143,31 @@ public class AppSearchManager {
    }

    /**
     * Index {@link AppSearchDocument}s into AppSearch.
     * Index {@link GenericDocument}s into AppSearch.
     *
     * <p>You should not call this method directly; instead, use the
     * {@code AppSearch#putDocuments()} API provided by JetPack.
     *
     * <p>Each {@link AppSearchDocument}'s {@code schemaType} field must be set to the name of a
     * <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.
     *
     * @param documents {@link AppSearchDocument}s that need to be indexed.
     * @param documents {@link GenericDocument}s that need to be indexed.
     * @return An {@link AppSearchBatchResult} mapping the document URIs to {@link Void} if they
     *     were successfully indexed, or a {@link Throwable} describing the failure if they could
     *     not be indexed.
     * @hide
     */
    public AppSearchBatchResult<String, Void> putDocuments(
            @NonNull List<AppSearchDocument> documents) {
            @NonNull List<GenericDocument> documents) {
        // TODO(b/146386470): Transmit these documents as a RemoteStream instead of sending them in
        // one big list.
        List<byte[]> documentsBytes = new ArrayList<>(documents.size());
        for (AppSearchDocument document : documents) {
            documentsBytes.add(document.getProto().toByteArray());
        List<Bundle> documentBundles = new ArrayList<>(documents.size());
        for (GenericDocument document : documents) {
            documentBundles.add(document.getBundle());
        }
        AndroidFuture<AppSearchBatchResult> future = new AndroidFuture<>();
        try {
            mService.putDocuments(documentsBytes, future);
            mService.putDocuments(documentBundles, future);
        } catch (RemoteException e) {
            future.completeExceptionally(e);
        }
@@ -180,19 +175,18 @@ public class AppSearchManager {
    }

    /**
     * Retrieves {@link AppSearchDocument}s by URI.
     * Retrieves {@link GenericDocument}s by URI.
     *
     * <p>You should not call this method directly; instead, use the
     * {@code AppSearch#getDocuments()} API provided by JetPack.
     *
     * @param uris URIs of the documents to look up.
     * @return An {@link AppSearchBatchResult} mapping the document URIs to
     *     {@link AppSearchDocument} values if they were successfully retrieved, a {@code null}
     *     {@link GenericDocument} values if they were successfully retrieved, a {@code null}
     *     failure if they were not found, or a {@link Throwable} failure describing the problem if
     *     an error occurred.
     */
    public AppSearchBatchResult<String, AppSearchDocument> getDocuments(
            @NonNull List<String> uris) {
    public AppSearchBatchResult<String, GenericDocument> getDocuments(@NonNull List<String> uris) {
        // TODO(b/146386470): Transmit the result documents as a RemoteStream instead of sending
        //     them in one big list.
        AndroidFuture<AppSearchBatchResult> future = new AndroidFuture<>();
@@ -202,43 +196,35 @@ public class AppSearchManager {
            future.completeExceptionally(e);
        }

        // Deserialize the protos into Document objects
        AppSearchBatchResult<String, byte[]> protoResults = getFutureOrThrow(future);
        AppSearchBatchResult.Builder<String, AppSearchDocument> documentResultBuilder =
        // Translate from document bundles to GenericDocument instances
        AppSearchBatchResult<String, Bundle> bundleResult = getFutureOrThrow(future);
        AppSearchBatchResult.Builder<String, GenericDocument> documentResultBuilder =
                new AppSearchBatchResult.Builder<>();

        // Translate successful results
        for (Map.Entry<String, byte[]> protoResult : protoResults.getSuccesses().entrySet()) {
            DocumentProto documentProto;
            try {
                documentProto = DocumentProto.parseFrom(protoResult.getValue());
            } catch (InvalidProtocolBufferException e) {
                documentResultBuilder.setFailure(
                        protoResult.getKey(), AppSearchResult.RESULT_IO_ERROR, e.getMessage());
                continue;
            }
            AppSearchDocument document;
        for (Map.Entry<String, Bundle> bundleEntry : bundleResult.getSuccesses().entrySet()) {
            GenericDocument document;
            try {
                document = new AppSearchDocument(documentProto);
                document = new GenericDocument(bundleEntry.getValue());
            } catch (Throwable t) {
                // These documents went through validation, so how could this fail? We must have
                // done something wrong.
                documentResultBuilder.setFailure(
                        protoResult.getKey(),
                        bundleEntry.getKey(),
                        AppSearchResult.RESULT_INTERNAL_ERROR,
                        t.getMessage());
                continue;
            }
            documentResultBuilder.setSuccess(protoResult.getKey(), document);
            documentResultBuilder.setSuccess(bundleEntry.getKey(), document);
        }

        // Translate failed results
        for (Map.Entry<String, AppSearchResult<byte[]>> protoResult :
                protoResults.getFailures().entrySet()) {
        for (Map.Entry<String, AppSearchResult<Bundle>> bundleEntry :
                bundleResult.getFailures().entrySet()) {
            documentResultBuilder.setFailure(
                    protoResult.getKey(),
                    protoResult.getValue().getResultCode(),
                    protoResult.getValue().getErrorMessage());
                    bundleEntry.getKey(),
                    bundleEntry.getValue().getResultCode(),
                    bundleEntry.getValue().getErrorMessage());
        }

        return documentResultBuilder.build();
@@ -287,43 +273,29 @@ public class AppSearchManager {
     * @hide
     */
    @NonNull
    public AppSearchResult<SearchResults> query(
    public AppSearchResult<List<SearchResult>> query(
            @NonNull String queryExpression, @NonNull SearchSpec searchSpec) {
        // TODO(b/146386470): Transmit the result documents as a RemoteStream instead of sending
        //     them in one big list.
        AndroidFuture<AppSearchResult> searchResultFuture = new AndroidFuture<>();
        AndroidFuture<AppSearchResult> searchResultsFuture = new AndroidFuture<>();
        try {
            mService.query(queryExpression, searchSpec.getBundle(), searchResultFuture);
            mService.query(queryExpression, searchSpec.getBundle(), searchResultsFuture);
        } catch (RemoteException e) {
            searchResultFuture.completeExceptionally(e);
            searchResultsFuture.completeExceptionally(e);
        }

        // Deserialize the protos into Document objects
        AppSearchResult<byte[]> searchResultBytes = getFutureOrThrow(searchResultFuture);
        if (!searchResultBytes.isSuccess()) {
            return AppSearchResult.newFailedResult(
                    searchResultBytes.getResultCode(), searchResultBytes.getErrorMessage());
        }
        SearchResultProto searchResultProto;
        try {
            searchResultProto = SearchResultProto.parseFrom(searchResultBytes.getResultValue());
        } catch (InvalidProtocolBufferException e) {
            return AppSearchResult.newFailedResult(
                    AppSearchResult.RESULT_INTERNAL_ERROR, e.getMessage());
        }
        if (searchResultProto.getStatus().getCode() != StatusProto.Code.OK) {
            // This should never happen; AppSearchManagerService should catch failed searchResults
            // entries and transmit them as a failed AppSearchResult.
        // Translate the list of Bundle into a list of SearchResult
        AppSearchResult<SearchResults> searchResultsResult = getFutureOrThrow(searchResultsFuture);
        if (!searchResultsResult.isSuccess()) {
            return AppSearchResult.newFailedResult(
                    AppSearchResult.RESULT_INTERNAL_ERROR,
                    searchResultProto.getStatus().getMessage());
                    searchResultsResult.getResultCode(), searchResultsResult.getErrorMessage());
        }

        return AppSearchResult.newSuccessfulResult(new SearchResults(searchResultProto));
        SearchResults searchResults = searchResultsResult.getResultValue();
        return AppSearchResult.newSuccessfulResult(searchResults.mResults);
    }

    /**
     * Deletes {@link AppSearchDocument}s by URI.
     * Deletes {@link GenericDocument}s by URI.
     *
     * <p>You should not call this method directly; instead, use the {@code AppSearch#delete()} API
     * provided by JetPack.
+923 −0

File changed and moved.

Preview size limit exceeded, changes collapsed.

+8 −7
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import com.android.internal.infra.AndroidFuture;

parcelable AppSearchResult;
parcelable AppSearchBatchResult;
parcelable SearchResults;

/** {@hide} */
interface IAppSearchManager {
@@ -41,7 +42,7 @@ interface IAppSearchManager {
    /**
     * Inserts documents into the index.
     *
     * @param documentsBytes {@link List}&lt;byte[]&gt; of serialized DocumentProtos.
     * @param documentBundes List of GenericDocument bundles.
     * @param callback
     *     {@link AndroidFuture}&lt;{@link AppSearchBatchResult}&lt;{@link String}, {@link Void}&gt;&gt;.
     *     If the call fails to start, {@code callback} will be completed exceptionally. Otherwise,
@@ -49,18 +50,19 @@ interface IAppSearchManager {
     *     {@link AppSearchBatchResult}&lt;{@link String}, {@link Void}&gt;
     *     where the keys are document URIs, and the values are {@code null}.
     */
    void putDocuments(in List documentsBytes, in AndroidFuture<AppSearchBatchResult> callback);
    void putDocuments(
        in List<Bundle> documentBundles, in AndroidFuture<AppSearchBatchResult> callback);

    /**
     * Retrieves documents from the index.
     *
     * @param uris The URIs of the documents to retrieve
     * @param callback
     *     {@link AndroidFuture}&lt;{@link AppSearchBatchResult}&lt;{@link String}, {@link byte[]}&gt;&gt;.
     *     {@link AndroidFuture}&lt;{@link AppSearchBatchResult}&lt;{@link String}, {@link Bundle}&gt;&gt;.
     *     If the call fails to start, {@code callback} will be completed exceptionally. Otherwise,
     *     {@code callback} will be completed with an
     *     {@link AppSearchBatchResult}&lt;{@link String}, {@link byte[]}&gt;
     *     where the keys are document URIs, and the values are serialized Document protos.
     *     {@link AppSearchBatchResult}&lt;{@link String}, {@link Bundle}&gt;
     *     where the keys are document URIs, and the values are Document bundles.
     */
    void getDocuments(in List<String> uris, in AndroidFuture<AppSearchBatchResult> callback);

@@ -69,8 +71,7 @@ interface IAppSearchManager {
     *
     * @param queryExpression String to search for
     * @param searchSpecBundle SearchSpec bundle
     * @param callback {@link AndroidFuture}&lt;{@link AppSearchResult}&lt;{@link byte[]}&gt;&gt;
     *     Will be completed with a serialized {@link SearchResultsProto}.
     * @param callback {@link AndroidFuture}&lt;{@link AppSearchResult}&lt;{@link SearchResults}&gt;&gt;
     */
    void query(
        in String queryExpression,
+0 −182

File deleted.

Preview size limit exceeded, changes collapsed.

Loading