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 
17 package com.android.server.appsearch.external.localstorage.stats;
18 
19 import static android.app.appsearch.stats.SchemaMigrationStats.NO_MIGRATION;
20 import static android.app.appsearch.stats.SchemaMigrationStats.SECOND_CALL_APPLY_NEW_SCHEMA;
21 
22 import android.annotation.NonNull;
23 import android.app.appsearch.AppSearchResult;
24 import android.app.appsearch.annotation.CanIgnoreReturnValue;
25 import android.app.appsearch.stats.SchemaMigrationStats;
26 
27 import com.android.internal.util.Preconditions;
28 
29 import java.util.Objects;
30 
31 /**
32  * Class holds detailed stats for {@link
33  * android.app.appsearch.AppSearchSession#setSchema(SetSchemaRequest)}.
34  *
35  * @hide
36  */
37 public final class SetSchemaStats {
38 
39     @NonNull private final String mPackageName;
40 
41     @NonNull private final String mDatabase;
42 
43     @AppSearchResult.ResultCode private final int mStatusCode;
44     private final int mTotalLatencyMillis;
45     private final int mNewTypeCount;
46     private final int mDeletedTypeCount;
47     private final int mCompatibleTypeChangeCount;
48     private final int mIndexIncompatibleTypeChangeCount;
49     private final int mBackwardsIncompatibleTypeChangeCount;
50     private final int mVerifyIncomingCallLatencyMillis;
51     private final int mExecutorAcquisitionLatencyMillis;
52     private final int mRebuildFromBundleLatencyMillis;
53     private final int mJavaLockAcquisitionLatencyMillis;
54     private final int mRewriteSchemaLatencyMillis;
55     private final int mTotalNativeLatencyMillis;
56     private final int mVisibilitySettingLatencyMillis;
57     private final int mConvertToResponseLatencyMillis;
58     private final int mDispatchChangeNotificationsLatencyMillis;
59     private final int mOptimizeLatencyMillis;
60     private final boolean mIsPackageObserved;
61     private final int mGetOldSchemaLatencyMillis;
62     private final int mGetObserverLatencyMillis;
63     private final int mPreparingChangeNotificationLatencyMillis;
64     @SchemaMigrationStats.SchemaMigrationCallType private final int mSchemaMigrationCallType;
65 
SetSchemaStats(@onNull Builder builder)66     SetSchemaStats(@NonNull Builder builder) {
67         Objects.requireNonNull(builder);
68         mPackageName = builder.mPackageName;
69         mDatabase = builder.mDatabase;
70         mStatusCode = builder.mStatusCode;
71         mTotalLatencyMillis = builder.mTotalLatencyMillis;
72         mNewTypeCount = builder.mNewTypeCount;
73         mDeletedTypeCount = builder.mDeletedTypeCount;
74         mCompatibleTypeChangeCount = builder.mCompatibleTypeChangeCount;
75         mIndexIncompatibleTypeChangeCount = builder.mIndexIncompatibleTypeChangeCount;
76         mBackwardsIncompatibleTypeChangeCount = builder.mBackwardsIncompatibleTypeChangeCount;
77         mVerifyIncomingCallLatencyMillis = builder.mVerifyIncomingCallLatencyMillis;
78         mExecutorAcquisitionLatencyMillis = builder.mExecutorAcquisitionLatencyMillis;
79         mRebuildFromBundleLatencyMillis = builder.mRebuildFromBundleLatencyMillis;
80         mJavaLockAcquisitionLatencyMillis = builder.mJavaLockAcquisitionLatencyMillis;
81         mRewriteSchemaLatencyMillis = builder.mRewriteSchemaLatencyMillis;
82         mTotalNativeLatencyMillis = builder.mTotalNativeLatencyMillis;
83         mVisibilitySettingLatencyMillis = builder.mVisibilitySettingLatencyMillis;
84         mConvertToResponseLatencyMillis = builder.mConvertToResponseLatencyMillis;
85         mDispatchChangeNotificationsLatencyMillis =
86                 builder.mDispatchChangeNotificationsLatencyMillis;
87         mOptimizeLatencyMillis = builder.mOptimizeLatencyMillis;
88         mIsPackageObserved = builder.mIsPackageObserved;
89         mGetOldSchemaLatencyMillis = builder.mGetOldSchemaLatencyMillis;
90         mGetObserverLatencyMillis = builder.mGetObserverLatencyMillis;
91         mPreparingChangeNotificationLatencyMillis =
92                 builder.mPreparingChangeNotificationLatencyMillis;
93         mSchemaMigrationCallType = builder.mSchemaMigrationCallType;
94     }
95 
96     /** Returns calling package name. */
97     @NonNull
getPackageName()98     public String getPackageName() {
99         return mPackageName;
100     }
101 
102     /** Returns calling database name. */
103     @NonNull
getDatabase()104     public String getDatabase() {
105         return mDatabase;
106     }
107 
108     /** Returns status of the SetSchema action. */
109     @AppSearchResult.ResultCode
getStatusCode()110     public int getStatusCode() {
111         return mStatusCode;
112     }
113 
114     /** Returns the total latency of the SetSchema action. */
getTotalLatencyMillis()115     public int getTotalLatencyMillis() {
116         return mTotalLatencyMillis;
117     }
118 
119     /** Returns number of newly added schema types. */
getNewTypeCount()120     public int getNewTypeCount() {
121         return mNewTypeCount;
122     }
123 
124     /** Returns number of deleted schema types. */
getDeletedTypeCount()125     public int getDeletedTypeCount() {
126         return mDeletedTypeCount;
127     }
128 
129     /** Returns number of compatible type changes. */
getCompatibleTypeChangeCount()130     public int getCompatibleTypeChangeCount() {
131         return mCompatibleTypeChangeCount;
132     }
133 
134     /**
135      * Returns number of index-incompatible type change.
136      *
137      * <p>An index-incompatible type change is one that affects how pre-existing data should be
138      * searched over, such as modifying the {@code IndexingType} of an existing property.
139      */
getIndexIncompatibleTypeChangeCount()140     public int getIndexIncompatibleTypeChangeCount() {
141         return mIndexIncompatibleTypeChangeCount;
142     }
143 
144     /**
145      * Returns number of backwards-incompatible type change.
146      *
147      * <p>For details on what constitutes a backward-incompatible type change, please see {@link
148      * android.app.appsearch.SetSchemaRequest}.
149      */
getBackwardsIncompatibleTypeChangeCount()150     public int getBackwardsIncompatibleTypeChangeCount() {
151         return mBackwardsIncompatibleTypeChangeCount;
152     }
153 
154     /** Gets time used for verifying the incoming call. */
getVerifyIncomingCallLatencyMillis()155     public int getVerifyIncomingCallLatencyMillis() {
156         return mVerifyIncomingCallLatencyMillis;
157     }
158 
159     /** Gets time passed while waiting to acquire the lock during Java function calls. */
getJavaLockAcquisitionLatencyMillis()160     public int getJavaLockAcquisitionLatencyMillis() {
161         return mJavaLockAcquisitionLatencyMillis;
162     }
163 
164     /** Gets latency for the rebuild schema object from bundle action in milliseconds. */
getRebuildFromBundleLatencyMillis()165     public int getRebuildFromBundleLatencyMillis() {
166         return mRebuildFromBundleLatencyMillis;
167     }
168 
169     /** Gets total latency for creating or waiting the user executor. */
getExecutorAcquisitionLatencyMillis()170     public int getExecutorAcquisitionLatencyMillis() {
171         return mExecutorAcquisitionLatencyMillis;
172     }
173 
174     /** Gets latency for the rewrite the schema proto action in milliseconds. */
getRewriteSchemaLatencyMillis()175     public int getRewriteSchemaLatencyMillis() {
176         return mRewriteSchemaLatencyMillis;
177     }
178 
179     /** Gets total latency for the SetSchema in native action in milliseconds. */
getTotalNativeLatencyMillis()180     public int getTotalNativeLatencyMillis() {
181         return mTotalNativeLatencyMillis;
182     }
183 
184     /** Gets latency for the dispatch change notification action in milliseconds. */
getDispatchChangeNotificationsLatencyMillis()185     public int getDispatchChangeNotificationsLatencyMillis() {
186         return mDispatchChangeNotificationsLatencyMillis;
187     }
188 
189     /** Gets latency for the apply visibility settings action in milliseconds. */
getVisibilitySettingLatencyMillis()190     public int getVisibilitySettingLatencyMillis() {
191         return mVisibilitySettingLatencyMillis;
192     }
193 
194     /** Gets latency for converting to SetSchemaResponseInternal object in milliseconds. */
getConvertToResponseLatencyMillis()195     public int getConvertToResponseLatencyMillis() {
196         return mConvertToResponseLatencyMillis;
197     }
198 
199     /** Gets latency for the optimization action in milliseconds. */
getOptimizeLatencyMillis()200     public int getOptimizeLatencyMillis() {
201         return mOptimizeLatencyMillis;
202     }
203 
204     /** Whether this package is observed and we should prepare change notifications */
isPackageObserved()205     public boolean isPackageObserved() {
206         return mIsPackageObserved;
207     }
208 
209     /** Gets latency for the old schema action in milliseconds. */
getGetOldSchemaLatencyMillis()210     public int getGetOldSchemaLatencyMillis() {
211         return mGetOldSchemaLatencyMillis;
212     }
213 
214     /** Gets latency for the registered observer action in milliseconds. */
getGetObserverLatencyMillis()215     public int getGetObserverLatencyMillis() {
216         return mGetObserverLatencyMillis;
217     }
218 
219     /** Gets latency for the preparing change notification action in milliseconds. */
getPreparingChangeNotificationLatencyMillis()220     public int getPreparingChangeNotificationLatencyMillis() {
221         return mPreparingChangeNotificationLatencyMillis;
222     }
223 
224     /** Gets the type indicate how this set schema call relative to schema migration cases */
225     @SchemaMigrationStats.SchemaMigrationCallType
getSchemaMigrationCallType()226     public int getSchemaMigrationCallType() {
227         return mSchemaMigrationCallType;
228     }
229 
230     /** Builder for {@link SetSchemaStats}. */
231     public static class Builder {
232         @NonNull final String mPackageName;
233         @NonNull final String mDatabase;
234         @AppSearchResult.ResultCode int mStatusCode;
235         int mTotalLatencyMillis;
236         int mNewTypeCount;
237         int mDeletedTypeCount;
238         int mCompatibleTypeChangeCount;
239         int mIndexIncompatibleTypeChangeCount;
240         int mBackwardsIncompatibleTypeChangeCount;
241         int mVerifyIncomingCallLatencyMillis;
242         int mExecutorAcquisitionLatencyMillis;
243         int mRebuildFromBundleLatencyMillis;
244         int mJavaLockAcquisitionLatencyMillis;
245         int mRewriteSchemaLatencyMillis;
246         int mTotalNativeLatencyMillis;
247         int mVisibilitySettingLatencyMillis;
248         int mConvertToResponseLatencyMillis;
249         int mDispatchChangeNotificationsLatencyMillis;
250         int mOptimizeLatencyMillis;
251         boolean mIsPackageObserved;
252         int mGetOldSchemaLatencyMillis;
253         int mGetObserverLatencyMillis;
254         int mPreparingChangeNotificationLatencyMillis;
255         @SchemaMigrationStats.SchemaMigrationCallType int mSchemaMigrationCallType;
256 
257         /** Constructor for the {@link Builder}. */
Builder(@onNull String packageName, @NonNull String database)258         public Builder(@NonNull String packageName, @NonNull String database) {
259             mPackageName = Objects.requireNonNull(packageName);
260             mDatabase = Objects.requireNonNull(database);
261         }
262 
263         /** Sets the status of the SetSchema action. */
264         @CanIgnoreReturnValue
265         @NonNull
setStatusCode(@ppSearchResult.ResultCode int statusCode)266         public Builder setStatusCode(@AppSearchResult.ResultCode int statusCode) {
267             mStatusCode = statusCode;
268             return this;
269         }
270 
271         /** Sets total latency for the SetSchema action in milliseconds. */
272         @CanIgnoreReturnValue
273         @NonNull
setTotalLatencyMillis(int totalLatencyMillis)274         public Builder setTotalLatencyMillis(int totalLatencyMillis) {
275             mTotalLatencyMillis = totalLatencyMillis;
276             return this;
277         }
278 
279         /** Sets number of new types. */
280         @CanIgnoreReturnValue
281         @NonNull
setNewTypeCount(int newTypeCount)282         public Builder setNewTypeCount(int newTypeCount) {
283             mNewTypeCount = newTypeCount;
284             return this;
285         }
286 
287         /** Sets number of deleted types. */
288         @CanIgnoreReturnValue
289         @NonNull
setDeletedTypeCount(int deletedTypeCount)290         public Builder setDeletedTypeCount(int deletedTypeCount) {
291             mDeletedTypeCount = deletedTypeCount;
292             return this;
293         }
294 
295         /** Sets number of compatible type changes. */
296         @CanIgnoreReturnValue
297         @NonNull
setCompatibleTypeChangeCount(int compatibleTypeChangeCount)298         public Builder setCompatibleTypeChangeCount(int compatibleTypeChangeCount) {
299             mCompatibleTypeChangeCount = compatibleTypeChangeCount;
300             return this;
301         }
302 
303         /** Sets number of index-incompatible type changes. */
304         @CanIgnoreReturnValue
305         @NonNull
setIndexIncompatibleTypeChangeCount(int indexIncompatibleTypeChangeCount)306         public Builder setIndexIncompatibleTypeChangeCount(int indexIncompatibleTypeChangeCount) {
307             mIndexIncompatibleTypeChangeCount = indexIncompatibleTypeChangeCount;
308             return this;
309         }
310 
311         /** Sets number of backwards-incompatible type changes. */
312         @CanIgnoreReturnValue
313         @NonNull
setBackwardsIncompatibleTypeChangeCount( int backwardsIncompatibleTypeChangeCount)314         public Builder setBackwardsIncompatibleTypeChangeCount(
315                 int backwardsIncompatibleTypeChangeCount) {
316             mBackwardsIncompatibleTypeChangeCount = backwardsIncompatibleTypeChangeCount;
317             return this;
318         }
319 
320         /** Sets total latency for the SetSchema in native action in milliseconds. */
321         @CanIgnoreReturnValue
322         @NonNull
setVerifyIncomingCallLatencyMillis(int verifyIncomingCallLatencyMillis)323         public Builder setVerifyIncomingCallLatencyMillis(int verifyIncomingCallLatencyMillis) {
324             mVerifyIncomingCallLatencyMillis = verifyIncomingCallLatencyMillis;
325             return this;
326         }
327 
328         /** Sets total latency for the SetSchema in native action in milliseconds. */
329         @CanIgnoreReturnValue
330         @NonNull
setExecutorAcquisitionLatencyMillis(int executorAcquisitionLatencyMillis)331         public Builder setExecutorAcquisitionLatencyMillis(int executorAcquisitionLatencyMillis) {
332             mExecutorAcquisitionLatencyMillis = executorAcquisitionLatencyMillis;
333             return this;
334         }
335 
336         /** Sets latency for the rebuild schema object from bundle action in milliseconds. */
337         @CanIgnoreReturnValue
338         @NonNull
setRebuildFromBundleLatencyMillis(int rebuildFromBundleLatencyMillis)339         public Builder setRebuildFromBundleLatencyMillis(int rebuildFromBundleLatencyMillis) {
340             mRebuildFromBundleLatencyMillis = rebuildFromBundleLatencyMillis;
341             return this;
342         }
343 
344         /**
345          * Sets latency for waiting to acquire the lock during Java function calls in milliseconds.
346          */
347         @CanIgnoreReturnValue
348         @NonNull
setJavaLockAcquisitionLatencyMillis(int javaLockAcquisitionLatencyMillis)349         public Builder setJavaLockAcquisitionLatencyMillis(int javaLockAcquisitionLatencyMillis) {
350             mJavaLockAcquisitionLatencyMillis = javaLockAcquisitionLatencyMillis;
351             return this;
352         }
353 
354         /** Sets latency for the rewrite the schema proto action in milliseconds. */
355         @CanIgnoreReturnValue
356         @NonNull
setRewriteSchemaLatencyMillis(int rewriteSchemaLatencyMillis)357         public Builder setRewriteSchemaLatencyMillis(int rewriteSchemaLatencyMillis) {
358             mRewriteSchemaLatencyMillis = rewriteSchemaLatencyMillis;
359             return this;
360         }
361 
362         /** Sets total latency for a single set schema in native action in milliseconds. */
363         @CanIgnoreReturnValue
364         @NonNull
setTotalNativeLatencyMillis(int totalNativeLatencyMillis)365         public Builder setTotalNativeLatencyMillis(int totalNativeLatencyMillis) {
366             mTotalNativeLatencyMillis = totalNativeLatencyMillis;
367             return this;
368         }
369 
370         /** Sets latency for the apply visibility settings action in milliseconds. */
371         @CanIgnoreReturnValue
372         @NonNull
setVisibilitySettingLatencyMillis(int visibilitySettingLatencyMillis)373         public Builder setVisibilitySettingLatencyMillis(int visibilitySettingLatencyMillis) {
374             mVisibilitySettingLatencyMillis = visibilitySettingLatencyMillis;
375             return this;
376         }
377 
378         /** Sets latency for converting to SetSchemaResponseInternal object in milliseconds. */
379         @CanIgnoreReturnValue
380         @NonNull
setConvertToResponseLatencyMillis(int convertToResponseLatencyMillis)381         public Builder setConvertToResponseLatencyMillis(int convertToResponseLatencyMillis) {
382             mConvertToResponseLatencyMillis = convertToResponseLatencyMillis;
383             return this;
384         }
385 
386         /** Sets latency for the dispatch change notification action in milliseconds. */
387         @CanIgnoreReturnValue
388         @NonNull
setDispatchChangeNotificationsLatencyMillis( int dispatchChangeNotificationsLatencyMillis)389         public Builder setDispatchChangeNotificationsLatencyMillis(
390                 int dispatchChangeNotificationsLatencyMillis) {
391             mDispatchChangeNotificationsLatencyMillis = dispatchChangeNotificationsLatencyMillis;
392             return this;
393         }
394 
395         /** Sets latency for the optimization action in milliseconds. */
396         @CanIgnoreReturnValue
397         @NonNull
setOptimizeLatencyMillis(int optimizeLatencyMillis)398         public Builder setOptimizeLatencyMillis(int optimizeLatencyMillis) {
399             mOptimizeLatencyMillis = optimizeLatencyMillis;
400             return this;
401         }
402 
403         /** Sets whether this package is observed and we should prepare change notifications. */
404         @CanIgnoreReturnValue
405         @NonNull
setIsPackageObserved(boolean isPackageObserved)406         public Builder setIsPackageObserved(boolean isPackageObserved) {
407             mIsPackageObserved = isPackageObserved;
408             return this;
409         }
410 
411         /** Sets latency for the old schema action in milliseconds. */
412         @CanIgnoreReturnValue
413         @NonNull
setGetOldSchemaLatencyMillis(int getOldSchemaLatencyMillis)414         public Builder setGetOldSchemaLatencyMillis(int getOldSchemaLatencyMillis) {
415             mGetOldSchemaLatencyMillis = getOldSchemaLatencyMillis;
416             return this;
417         }
418 
419         /** Sets latency for the registered observer action in milliseconds. */
420         @CanIgnoreReturnValue
421         @NonNull
setGetObserverLatencyMillis(int getObserverLatencyMillis)422         public Builder setGetObserverLatencyMillis(int getObserverLatencyMillis) {
423             mGetObserverLatencyMillis = getObserverLatencyMillis;
424             return this;
425         }
426 
427         /** Sets latency for the preparing change notification action in milliseconds. */
428         @CanIgnoreReturnValue
429         @NonNull
setPreparingChangeNotificationLatencyMillis( int preparingChangeNotificationLatencyMillis)430         public Builder setPreparingChangeNotificationLatencyMillis(
431                 int preparingChangeNotificationLatencyMillis) {
432             mPreparingChangeNotificationLatencyMillis = preparingChangeNotificationLatencyMillis;
433             return this;
434         }
435 
436         /** Sets the type indicate how this set schema call relative to schema migration cases */
437         @CanIgnoreReturnValue
438         @NonNull
setSchemaMigrationCallType( @chemaMigrationStats.SchemaMigrationCallType int schemaMigrationCallType)439         public Builder setSchemaMigrationCallType(
440                 @SchemaMigrationStats.SchemaMigrationCallType int schemaMigrationCallType) {
441             Preconditions.checkArgumentInRange(
442                     schemaMigrationCallType,
443                     NO_MIGRATION,
444                     SECOND_CALL_APPLY_NEW_SCHEMA,
445                     "schemaMigrationCallType");
446             mSchemaMigrationCallType = schemaMigrationCallType;
447             return this;
448         }
449 
450         /** Builds a new {@link SetSchemaStats} from the {@link Builder}. */
451         @NonNull
build()452         public SetSchemaStats build() {
453             return new SetSchemaStats(/* builder= */ this);
454         }
455     }
456 }
457