• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 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 package com.android.server.appsearch.external.localstorage.stats;
17 
18 import android.annotation.IntDef;
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.app.appsearch.AppSearchResult;
22 import android.app.appsearch.SearchSpec;
23 
24 import com.android.internal.util.Preconditions;
25 
26 import java.lang.annotation.Retention;
27 import java.lang.annotation.RetentionPolicy;
28 import java.util.Objects;
29 
30 /**
31  * Class holds detailed stats for {@link android.app.appsearch.AppSearchSession#search(String,
32  * SearchSpec)}
33  *
34  * @hide
35  */
36 public final class SearchStats {
37     @IntDef(
38             value = {
39                 // Searches apps' own documents.
40                 VISIBILITY_SCOPE_LOCAL,
41                 // Searches the global documents. Including platform surfaceable and 3p-access.
42                 VISIBILITY_SCOPE_GLOBAL,
43                 // TODO(b/173532925) Add THIRD_PARTY_ACCESS once we can distinguish platform
44                 //  surfaceable from 3p access(right both of them are categorized as
45                 //  VISIBILITY_SCOPE_GLOBAL)
46             })
47     @Retention(RetentionPolicy.SOURCE)
48     public @interface VisibilityScope {}
49 
50     // Searches apps' own documents.
51     public static final int VISIBILITY_SCOPE_LOCAL = 1;
52     // Searches the global documents. Including platform surfaceable and 3p-access.
53     public static final int VISIBILITY_SCOPE_GLOBAL = 2;
54 
55     // TODO(b/173532925): Add a field searchType to indicate where the search is used(normal
56     //  query vs in removeByQuery vs during migration)
57 
58     @NonNull private final String mPackageName;
59     @Nullable private final String mDatabase;
60     /**
61      * The status code returned by {@link AppSearchResult#getResultCode()} for the call or internal
62      * state.
63      */
64     @AppSearchResult.ResultCode private final int mStatusCode;
65 
66     private final int mTotalLatencyMillis;
67     /** Time used to rewrite the search spec. */
68     private final int mRewriteSearchSpecLatencyMillis;
69     /** Time used to rewrite the search results. */
70     private final int mRewriteSearchResultLatencyMillis;
71     /** Defines the scope the query is searching over */
72     @VisibilityScope private final int mVisibilityScope;
73     /** Overall time used for the native function call. */
74     private final int mNativeLatencyMillis;
75     /** Number of terms in the query string. */
76     private final int mNativeNumTerms;
77     /** Length of the query string. */
78     private final int mNativeQueryLength;
79     /** Number of namespaces filtered. */
80     private final int mNativeNumNamespacesFiltered;
81     /** Number of schema types filtered. */
82     private final int mNativeNumSchemaTypesFiltered;
83     /** The requested number of results in one page. */
84     private final int mNativeRequestedPageSize;
85     /** The actual number of results returned in the current page. */
86     private final int mNativeNumResultsReturnedCurrentPage;
87     /**
88      * Whether the function call is querying the first page. If it's not, Icing will fetch the
89      * results from cache so that some steps may be skipped.
90      */
91     private final boolean mNativeIsFirstPage;
92     /**
93      * Time used to parse the query, including 2 parts: tokenizing and transforming tokens into an
94      * iterator tree.
95      */
96     private final int mNativeParseQueryLatencyMillis;
97     /** Strategy of scoring and ranking. */
98     @SearchSpec.RankingStrategy private final int mNativeRankingStrategy;
99     /** Number of documents scored. */
100     private final int mNativeNumDocumentsScored;
101     /** Time used to score the raw results. */
102     private final int mNativeScoringLatencyMillis;
103     /** Time used to rank the scored results. */
104     private final int mNativeRankingLatencyMillis;
105     /**
106      * Time used to fetch the document protos. Note that it includes the time to snippet if {@link
107      * SearchStats#mNativeNumResultsWithSnippets} is greater than 0.
108      */
109     private final int mNativeDocumentRetrievingLatencyMillis;
110     /** How many snippets are calculated. */
111     private final int mNativeNumResultsWithSnippets;
112 
SearchStats(@onNull Builder builder)113     SearchStats(@NonNull Builder builder) {
114         Objects.requireNonNull(builder);
115         mPackageName = builder.mPackageName;
116         mDatabase = builder.mDatabase;
117         mStatusCode = builder.mStatusCode;
118         mTotalLatencyMillis = builder.mTotalLatencyMillis;
119         mRewriteSearchSpecLatencyMillis = builder.mRewriteSearchSpecLatencyMillis;
120         mRewriteSearchResultLatencyMillis = builder.mRewriteSearchResultLatencyMillis;
121         mVisibilityScope = builder.mVisibilityScope;
122         mNativeLatencyMillis = builder.mNativeLatencyMillis;
123         mNativeNumTerms = builder.mNativeNumTerms;
124         mNativeQueryLength = builder.mNativeQueryLength;
125         mNativeNumNamespacesFiltered = builder.mNativeNumNamespacesFiltered;
126         mNativeNumSchemaTypesFiltered = builder.mNativeNumSchemaTypesFiltered;
127         mNativeRequestedPageSize = builder.mNativeRequestedPageSize;
128         mNativeNumResultsReturnedCurrentPage = builder.mNativeNumResultsReturnedCurrentPage;
129         mNativeIsFirstPage = builder.mNativeIsFirstPage;
130         mNativeParseQueryLatencyMillis = builder.mNativeParseQueryLatencyMillis;
131         mNativeRankingStrategy = builder.mNativeRankingStrategy;
132         mNativeNumDocumentsScored = builder.mNativeNumDocumentsScored;
133         mNativeScoringLatencyMillis = builder.mNativeScoringLatencyMillis;
134         mNativeRankingLatencyMillis = builder.mNativeRankingLatencyMillis;
135         mNativeNumResultsWithSnippets = builder.mNativeNumResultsWithSnippets;
136         mNativeDocumentRetrievingLatencyMillis = builder.mNativeDocumentRetrievingLatencyMillis;
137     }
138 
139     /** Returns the package name of the session. */
140     @NonNull
getPackageName()141     public String getPackageName() {
142         return mPackageName;
143     }
144 
145     /**
146      * Returns the database name of the session.
147      *
148      * @return database name used by the session. {@code null} if and only if it is a global
149      *     search(visibilityScope is {@link SearchStats#VISIBILITY_SCOPE_GLOBAL}).
150      */
151     @Nullable
getDatabase()152     public String getDatabase() {
153         return mDatabase;
154     }
155 
156     /** Returns status of the search. */
157     @AppSearchResult.ResultCode
getStatusCode()158     public int getStatusCode() {
159         return mStatusCode;
160     }
161 
162     /** Returns the total latency of the search. */
getTotalLatencyMillis()163     public int getTotalLatencyMillis() {
164         return mTotalLatencyMillis;
165     }
166 
167     /** Returns how much time spent on rewriting the {@link SearchSpec}. */
getRewriteSearchSpecLatencyMillis()168     public int getRewriteSearchSpecLatencyMillis() {
169         return mRewriteSearchSpecLatencyMillis;
170     }
171 
172     /** Returns how much time spent on rewriting the {@link android.app.appsearch.SearchResult}. */
getRewriteSearchResultLatencyMillis()173     public int getRewriteSearchResultLatencyMillis() {
174         return mRewriteSearchResultLatencyMillis;
175     }
176 
177     /** Returns the visibility scope of the search. */
178     @VisibilityScope
getVisibilityScope()179     public int getVisibilityScope() {
180         return mVisibilityScope;
181     }
182 
183     /** Returns how much time spent on the native calls. */
getNativeLatencyMillis()184     public int getNativeLatencyMillis() {
185         return mNativeLatencyMillis;
186     }
187 
188     /** Returns number of terms in the search string. */
getTermCount()189     public int getTermCount() {
190         return mNativeNumTerms;
191     }
192 
193     /** Returns the length of the search string. */
getQueryLength()194     public int getQueryLength() {
195         return mNativeQueryLength;
196     }
197 
198     /** Returns number of namespaces filtered. */
getFilteredNamespaceCount()199     public int getFilteredNamespaceCount() {
200         return mNativeNumNamespacesFiltered;
201     }
202 
203     /** Returns number of schema types filtered. */
getFilteredSchemaTypeCount()204     public int getFilteredSchemaTypeCount() {
205         return mNativeNumSchemaTypesFiltered;
206     }
207 
208     /** Returns the requested number of results in one page. */
getRequestedPageSize()209     public int getRequestedPageSize() {
210         return mNativeRequestedPageSize;
211     }
212 
213     /** Returns the actual number of results returned in the current page. */
getCurrentPageReturnedResultCount()214     public int getCurrentPageReturnedResultCount() {
215         return mNativeNumResultsReturnedCurrentPage;
216     }
217 
218     // TODO(b/185184738) Make it an integer to show how many pages having been returned.
219     /** Returns whether the function call is querying the first page. */
isFirstPage()220     public boolean isFirstPage() {
221         return mNativeIsFirstPage;
222     }
223 
224     /**
225      * Returns time used to parse the query, including 2 parts: tokenizing and transforming tokens
226      * into an iterator tree.
227      */
getParseQueryLatencyMillis()228     public int getParseQueryLatencyMillis() {
229         return mNativeParseQueryLatencyMillis;
230     }
231 
232     /** Returns strategy of scoring and ranking. */
233     @SearchSpec.RankingStrategy
getRankingStrategy()234     public int getRankingStrategy() {
235         return mNativeRankingStrategy;
236     }
237 
238     /** Returns number of documents scored. */
getScoredDocumentCount()239     public int getScoredDocumentCount() {
240         return mNativeNumDocumentsScored;
241     }
242 
243     /** Returns time used to score the raw results. */
getScoringLatencyMillis()244     public int getScoringLatencyMillis() {
245         return mNativeScoringLatencyMillis;
246     }
247 
248     /** Returns time used to rank the scored results. */
getRankingLatencyMillis()249     public int getRankingLatencyMillis() {
250         return mNativeRankingLatencyMillis;
251     }
252 
253     /**
254      * Returns time used to fetch the document protos. Note that it includes the time to snippet if
255      * {@link SearchStats#mNativeNumResultsWithSnippets} is not zero.
256      */
getDocumentRetrievingLatencyMillis()257     public int getDocumentRetrievingLatencyMillis() {
258         return mNativeDocumentRetrievingLatencyMillis;
259     }
260 
261     /** Returns the number of the results in the page returned were snippeted. */
getResultWithSnippetsCount()262     public int getResultWithSnippetsCount() {
263         return mNativeNumResultsWithSnippets;
264     }
265 
266     /** Builder for {@link SearchStats} */
267     public static class Builder {
268         @NonNull final String mPackageName;
269         @Nullable String mDatabase;
270         @AppSearchResult.ResultCode int mStatusCode;
271         int mTotalLatencyMillis;
272         int mRewriteSearchSpecLatencyMillis;
273         int mRewriteSearchResultLatencyMillis;
274         int mVisibilityScope;
275         int mNativeLatencyMillis;
276         int mNativeNumTerms;
277         int mNativeQueryLength;
278         int mNativeNumNamespacesFiltered;
279         int mNativeNumSchemaTypesFiltered;
280         int mNativeRequestedPageSize;
281         int mNativeNumResultsReturnedCurrentPage;
282         boolean mNativeIsFirstPage;
283         int mNativeParseQueryLatencyMillis;
284         int mNativeRankingStrategy;
285         int mNativeNumDocumentsScored;
286         int mNativeScoringLatencyMillis;
287         int mNativeRankingLatencyMillis;
288         int mNativeNumResultsWithSnippets;
289         int mNativeDocumentRetrievingLatencyMillis;
290 
291         /**
292          * Constructor
293          *
294          * @param visibilityScope scope for the corresponding search.
295          * @param packageName name of the calling package.
296          */
Builder(@isibilityScope int visibilityScope, @NonNull String packageName)297         public Builder(@VisibilityScope int visibilityScope, @NonNull String packageName) {
298             mVisibilityScope = visibilityScope;
299             mPackageName = Objects.requireNonNull(packageName);
300         }
301 
302         /** Sets the database used by the session. */
303         @NonNull
setDatabase(@onNull String database)304         public Builder setDatabase(@NonNull String database) {
305             mDatabase = Objects.requireNonNull(database);
306             return this;
307         }
308 
309         /** Sets the status of the search. */
310         @NonNull
setStatusCode(@ppSearchResult.ResultCode int statusCode)311         public Builder setStatusCode(@AppSearchResult.ResultCode int statusCode) {
312             mStatusCode = statusCode;
313             return this;
314         }
315 
316         /** Sets total latency for the search. */
317         @NonNull
setTotalLatencyMillis(int totalLatencyMillis)318         public Builder setTotalLatencyMillis(int totalLatencyMillis) {
319             mTotalLatencyMillis = totalLatencyMillis;
320             return this;
321         }
322 
323         /** Sets time used to rewrite the search spec. */
324         @NonNull
setRewriteSearchSpecLatencyMillis(int rewriteSearchSpecLatencyMillis)325         public Builder setRewriteSearchSpecLatencyMillis(int rewriteSearchSpecLatencyMillis) {
326             mRewriteSearchSpecLatencyMillis = rewriteSearchSpecLatencyMillis;
327             return this;
328         }
329 
330         /** Sets time used to rewrite the search results. */
331         @NonNull
setRewriteSearchResultLatencyMillis(int rewriteSearchResultLatencyMillis)332         public Builder setRewriteSearchResultLatencyMillis(int rewriteSearchResultLatencyMillis) {
333             mRewriteSearchResultLatencyMillis = rewriteSearchResultLatencyMillis;
334             return this;
335         }
336 
337         /** Sets overall time used for the native function calls. */
338         @NonNull
setNativeLatencyMillis(int nativeLatencyMillis)339         public Builder setNativeLatencyMillis(int nativeLatencyMillis) {
340             mNativeLatencyMillis = nativeLatencyMillis;
341             return this;
342         }
343 
344         /** Sets number of terms in the search string. */
345         @NonNull
setTermCount(int termCount)346         public Builder setTermCount(int termCount) {
347             mNativeNumTerms = termCount;
348             return this;
349         }
350 
351         /** Sets length of the search string. */
352         @NonNull
setQueryLength(int queryLength)353         public Builder setQueryLength(int queryLength) {
354             mNativeQueryLength = queryLength;
355             return this;
356         }
357 
358         /** Sets number of namespaces filtered. */
359         @NonNull
setFilteredNamespaceCount(int filteredNamespaceCount)360         public Builder setFilteredNamespaceCount(int filteredNamespaceCount) {
361             mNativeNumNamespacesFiltered = filteredNamespaceCount;
362             return this;
363         }
364 
365         /** Sets number of schema types filtered. */
366         @NonNull
setFilteredSchemaTypeCount(int filteredSchemaTypeCount)367         public Builder setFilteredSchemaTypeCount(int filteredSchemaTypeCount) {
368             mNativeNumSchemaTypesFiltered = filteredSchemaTypeCount;
369             return this;
370         }
371 
372         /** Sets the requested number of results in one page. */
373         @NonNull
setRequestedPageSize(int requestedPageSize)374         public Builder setRequestedPageSize(int requestedPageSize) {
375             mNativeRequestedPageSize = requestedPageSize;
376             return this;
377         }
378 
379         /** Sets the actual number of results returned in the current page. */
380         @NonNull
setCurrentPageReturnedResultCount(int currentPageReturnedResultCount)381         public Builder setCurrentPageReturnedResultCount(int currentPageReturnedResultCount) {
382             mNativeNumResultsReturnedCurrentPage = currentPageReturnedResultCount;
383             return this;
384         }
385 
386         /**
387          * Sets whether the function call is querying the first page. If it's not, Icing will fetch
388          * the results from cache so that some steps may be skipped.
389          */
390         @NonNull
setIsFirstPage(boolean nativeIsFirstPage)391         public Builder setIsFirstPage(boolean nativeIsFirstPage) {
392             mNativeIsFirstPage = nativeIsFirstPage;
393             return this;
394         }
395 
396         /**
397          * Sets time used to parse the query, including 2 parts: tokenizing and transforming tokens
398          * into an iterator tree.
399          */
400         @NonNull
setParseQueryLatencyMillis(int parseQueryLatencyMillis)401         public Builder setParseQueryLatencyMillis(int parseQueryLatencyMillis) {
402             mNativeParseQueryLatencyMillis = parseQueryLatencyMillis;
403             return this;
404         }
405 
406         /** Sets strategy of scoring and ranking. */
407         @NonNull
setRankingStrategy(@earchSpec.RankingStrategy int rankingStrategy)408         public Builder setRankingStrategy(@SearchSpec.RankingStrategy int rankingStrategy) {
409             mNativeRankingStrategy = rankingStrategy;
410             return this;
411         }
412 
413         /** Sets number of documents scored. */
414         @NonNull
setScoredDocumentCount(int scoredDocumentCount)415         public Builder setScoredDocumentCount(int scoredDocumentCount) {
416             mNativeNumDocumentsScored = scoredDocumentCount;
417             return this;
418         }
419 
420         /** Sets time used to score the raw results. */
421         @NonNull
setScoringLatencyMillis(int scoringLatencyMillis)422         public Builder setScoringLatencyMillis(int scoringLatencyMillis) {
423             mNativeScoringLatencyMillis = scoringLatencyMillis;
424             return this;
425         }
426 
427         /** Sets time used to rank the scored results. */
428         @NonNull
setRankingLatencyMillis(int rankingLatencyMillis)429         public Builder setRankingLatencyMillis(int rankingLatencyMillis) {
430             mNativeRankingLatencyMillis = rankingLatencyMillis;
431             return this;
432         }
433 
434         /** Sets time used to fetch the document protos. */
435         @NonNull
setDocumentRetrievingLatencyMillis(int documentRetrievingLatencyMillis)436         public Builder setDocumentRetrievingLatencyMillis(int documentRetrievingLatencyMillis) {
437             mNativeDocumentRetrievingLatencyMillis = documentRetrievingLatencyMillis;
438             return this;
439         }
440 
441         /** Sets how many snippets are calculated. */
442         @NonNull
setResultWithSnippetsCount(int resultWithSnippetsCount)443         public Builder setResultWithSnippetsCount(int resultWithSnippetsCount) {
444             mNativeNumResultsWithSnippets = resultWithSnippetsCount;
445             return this;
446         }
447 
448         /**
449          * Constructs a new {@link SearchStats} from the contents of this {@link
450          * SearchStats.Builder}.
451          */
452         @NonNull
build()453         public SearchStats build() {
454             if (mDatabase == null) {
455                 Preconditions.checkState(
456                         mVisibilityScope != SearchStats.VISIBILITY_SCOPE_LOCAL,
457                         "database can not be null if visibilityScope is local.");
458             }
459 
460             return new SearchStats(/* builder= */ this);
461         }
462     }
463 }
464