1 /*
2  * Copyright 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.appsearch.external.localstorage.usagereporting;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.app.appsearch.AppSearchResult;
22 import android.app.appsearch.AppSearchSchema;
23 import android.app.appsearch.AppSearchSession;
24 import android.app.appsearch.GenericDocument;
25 import android.app.appsearch.annotation.CanIgnoreReturnValue;
26 import android.app.appsearch.usagereporting.ActionConstants;
27 
28 import com.android.internal.util.Preconditions;
29 
30 import java.util.Objects;
31 
32 /**
33  * Wrapper class for
34  *
35  * <p>search action
36  *
37  * <p>{@link GenericDocument}, which contains getters for search action properties.
38  *
39  * @hide
40  */
41 public class SearchActionGenericDocument extends TakenActionGenericDocument {
42     private static final String PROPERTY_PATH_QUERY = "query";
43     private static final String PROPERTY_PATH_FETCHED_RESULT_COUNT = "fetchedResultCount";
44 
SearchActionGenericDocument(@onNull GenericDocument document)45     SearchActionGenericDocument(@NonNull GenericDocument document) {
46         super(Objects.requireNonNull(document));
47     }
48 
49     /** Returns the string value of property {@code query}. */
50     @Nullable
getQuery()51     public String getQuery() {
52         return getPropertyString(PROPERTY_PATH_QUERY);
53     }
54 
55     /** Returns the integer value of property {@code fetchedResultCount}. */
getFetchedResultCount()56     public int getFetchedResultCount() {
57         return (int) getPropertyLong(PROPERTY_PATH_FETCHED_RESULT_COUNT);
58     }
59 
60     /** Builder for {@link SearchActionGenericDocument}. */
61     public static final class Builder extends TakenActionGenericDocument.Builder<Builder> {
62         /**
63          * Creates a new {@link SearchActionGenericDocument.Builder}.
64          *
65          * <p>Document IDs are unique within a namespace.
66          *
67          * <p>The number of namespaces per app should be kept small for efficiency reasons.
68          *
69          * @param namespace the namespace to set for the {@link GenericDocument}.
70          * @param id the unique identifier for the {@link GenericDocument} in its namespace.
71          * @param schemaType the {@link AppSearchSchema} type of the {@link GenericDocument}. The
72          *     provided {@code schemaType} must be defined using {@link AppSearchSession#setSchema}
73          *     prior to inserting a document of this {@code schemaType} into the AppSearch index
74          *     using {@link AppSearchSession#put}. Otherwise, the document will be rejected by
75          *     {@link AppSearchSession#put} with result code {@link
76          *     AppSearchResult#RESULT_NOT_FOUND}.
77          */
Builder(@onNull String namespace, @NonNull String id, @NonNull String schemaType)78         public Builder(@NonNull String namespace, @NonNull String id, @NonNull String schemaType) {
79             super(
80                     Objects.requireNonNull(namespace),
81                     Objects.requireNonNull(id),
82                     Objects.requireNonNull(schemaType),
83                     ActionConstants.ACTION_TYPE_SEARCH);
84         }
85 
86         /**
87          * Creates a new {@link SearchActionGenericDocument.Builder} from an existing {@link
88          * GenericDocument}.
89          *
90          * @param document a generic document object.
91          * @throws IllegalArgumentException if the integer value of property {@code actionType} is
92          *     not {@link ActionConstants#ACTION_TYPE_SEARCH}.
93          */
Builder(@onNull GenericDocument document)94         public Builder(@NonNull GenericDocument document) {
95             super(Objects.requireNonNull(document));
96 
97             if (document.getPropertyLong(PROPERTY_PATH_ACTION_TYPE)
98                     != ActionConstants.ACTION_TYPE_SEARCH) {
99                 throw new IllegalArgumentException(
100                         "Invalid action type for SearchActionGenericDocument");
101             }
102         }
103 
104         /**
105          * Sets the string value of property {@code query} by the user-entered search input (without
106          * any operators or rewriting).
107          */
108         @CanIgnoreReturnValue
109         @NonNull
setQuery(@onNull String query)110         public Builder setQuery(@NonNull String query) {
111             Objects.requireNonNull(query);
112             setPropertyString(PROPERTY_PATH_QUERY, query);
113             return this;
114         }
115 
116         /**
117          * Sets the integer value of property {@code fetchedResultCount} by total number of results
118          * fetched from AppSearch by the client in this search action.
119          */
120         @CanIgnoreReturnValue
121         @NonNull
setFetchedResultCount(int fetchedResultCount)122         public Builder setFetchedResultCount(int fetchedResultCount) {
123             Preconditions.checkArgumentNonnegative(fetchedResultCount);
124             setPropertyLong(PROPERTY_PATH_FETCHED_RESULT_COUNT, fetchedResultCount);
125             return this;
126         }
127 
128         /** Builds a {@link SearchActionGenericDocument}. */
129         @Override
130         @NonNull
build()131         public SearchActionGenericDocument build() {
132             return new SearchActionGenericDocument(super.build());
133         }
134     }
135 }
136