• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 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 android.app.appsearch.stats;
18 
19 import android.annotation.IntDef;
20 import android.annotation.NonNull;
21 import android.app.appsearch.AppSearchResult;
22 import android.app.appsearch.SetSchemaRequest;
23 import android.app.appsearch.annotation.CanIgnoreReturnValue;
24 import android.app.appsearch.util.BundleUtil;
25 import android.os.Bundle;
26 
27 import java.lang.annotation.Retention;
28 import java.lang.annotation.RetentionPolicy;
29 import java.util.Objects;
30 
31 /**
32  * Class holds detailed stats for Schema migration.
33  *
34  * @hide
35  */
36 public final class SchemaMigrationStats {
37 
38     // Indicate the how a SetSchema call relative to SchemaMigration case.
39     @IntDef(
40             value = {
41                 NO_MIGRATION,
42                 FIRST_CALL_GET_INCOMPATIBLE,
43                 SECOND_CALL_APPLY_NEW_SCHEMA,
44             })
45     @Retention(RetentionPolicy.SOURCE)
46     public @interface SchemaMigrationCallType {}
47 
48     /** This SetSchema call is not relative to a SchemaMigration case. */
49     public static final int NO_MIGRATION = 0;
50     /** This is the first SetSchema call in Migration cases to get all incompatible changes. */
51     public static final int FIRST_CALL_GET_INCOMPATIBLE = 1;
52     /** This is the second SetSchema call in Migration cases to apply new schema changes */
53     public static final int SECOND_CALL_APPLY_NEW_SCHEMA = 2;
54 
55     private static final String PACKAGE_NAME_FIELD = "packageName";
56     private static final String DATABASE_FIELD = "database";
57     private static final String STATUS_CODE_FIELD = "StatusCode";
58     private static final String EXECUTOR_ACQUISITION_MILLIS_FIELD =
59             "ExecutorAcquisitionLatencyMillis";
60     private static final String TOTAL_LATENCY_MILLIS_FIELD = "totalLatencyMillis";
61     private static final String GET_SCHEMA_LATENCY_MILLIS_FIELD = "getSchemaLatencyMillis";
62     private static final String QUERY_AND_TRANSFORM_LATENCY_MILLIS_FIELD =
63             "queryAndTransformLatencyMillis";
64     private static final String FIRST_SET_SCHEMA_LATENCY_MILLIS_FIELD =
65             "firstSetSchemaLatencyMillis";
66     private static final String IS_FIRST_SET_SCHEMA_SUCCESS_FIELD = "isFirstSetSchemaSuccess";
67     private static final String SECOND_SET_SCHEMA_LATENCY_MILLIS_FIELD =
68             "secondSetSchemaLatencyMillis";
69     private static final String SAVE_DOCUMENT_LATENCY_MILLIS_FIELD = "saveDocumentLatencyMillis";
70     private static final String TOTAL_NEED_MIGRATED_DOCUMENT_COUNT_FIELD =
71             "totalNeedMigratedDocumentCount";
72     private static final String MIGRATION_FAILURE_COUNT_FIELD = "migrationFailureCount";
73     private static final String TOTAL_SUCCESS_MIGRATED_DOCUMENT_COUNT_FIELD =
74             "totalSuccessMigratedDocumentCount";
75 
76     /**
77      * Contains all {@link SchemaMigrationStats} information in a packaged format.
78      *
79      * <p>Keys are the {@code *_FIELD} constants in this class.
80      */
81     @NonNull final Bundle mBundle;
82 
83     /** Build a {@link SchemaMigrationStats} from the given bundle. */
SchemaMigrationStats(@onNull Bundle bundle)84     public SchemaMigrationStats(@NonNull Bundle bundle) {
85         mBundle = Objects.requireNonNull(bundle);
86     }
87 
88     /**
89      * Returns the {@link Bundle} populated by this builder.
90      *
91      * @hide
92      */
93     @NonNull
getBundle()94     public Bundle getBundle() {
95         return mBundle;
96     }
97 
98     /** Returns calling package name. */
99     @NonNull
getPackageName()100     public String getPackageName() {
101         return mBundle.getString(PACKAGE_NAME_FIELD);
102     }
103 
104     /** Returns calling database name. */
105     @NonNull
getDatabase()106     public String getDatabase() {
107         return mBundle.getString(DATABASE_FIELD);
108     }
109 
110     /** Returns status of the schema migration action. */
111     @AppSearchResult.ResultCode
getStatusCode()112     public int getStatusCode() {
113         return mBundle.getInt(STATUS_CODE_FIELD);
114     }
115 
116     /** Gets the latency for waiting the executor. */
getExecutorAcquisitionLatencyMillis()117     public int getExecutorAcquisitionLatencyMillis() {
118         return mBundle.getInt(EXECUTOR_ACQUISITION_MILLIS_FIELD);
119     }
120 
121     /** Gets total latency for the schema migration action in milliseconds. */
getTotalLatencyMillis()122     public int getTotalLatencyMillis() {
123         return mBundle.getInt(TOTAL_LATENCY_MILLIS_FIELD);
124     }
125 
126     /** Returns GetSchema latency in milliseconds. */
getGetSchemaLatencyMillis()127     public int getGetSchemaLatencyMillis() {
128         return mBundle.getInt(GET_SCHEMA_LATENCY_MILLIS_FIELD);
129     }
130 
131     /**
132      * Returns latency of querying all documents that need to be migrated to new version and
133      * transforming documents to new version in milliseconds.
134      */
getQueryAndTransformLatencyMillis()135     public int getQueryAndTransformLatencyMillis() {
136         return mBundle.getInt(QUERY_AND_TRANSFORM_LATENCY_MILLIS_FIELD);
137     }
138 
139     /**
140      * Returns latency of first SetSchema action in milliseconds.
141      *
142      * <p>If all schema fields are backward compatible, the schema will be successful set to Icing.
143      * Otherwise, we will retrieve incompatible types here.
144      *
145      * <p>Please see {@link SetSchemaRequest} for what is "incompatible".
146      */
getFirstSetSchemaLatencyMillis()147     public int getFirstSetSchemaLatencyMillis() {
148         return mBundle.getInt(FIRST_SET_SCHEMA_LATENCY_MILLIS_FIELD);
149     }
150 
151     /** Returns whether the first SetSchema action success. */
isFirstSetSchemaSuccess()152     public boolean isFirstSetSchemaSuccess() {
153         return mBundle.getBoolean(IS_FIRST_SET_SCHEMA_SUCCESS_FIELD);
154     }
155 
156     /**
157      * Returns latency of second SetSchema action in milliseconds.
158      *
159      * <p>If all schema fields are backward compatible, the schema will be successful set to Icing
160      * in the first setSchema action and this value will be 0. Otherwise, schema types will be set
161      * to Icing by this action.
162      */
getSecondSetSchemaLatencyMillis()163     public int getSecondSetSchemaLatencyMillis() {
164         return mBundle.getInt(SECOND_SET_SCHEMA_LATENCY_MILLIS_FIELD);
165     }
166 
167     /** Returns latency of putting migrated document to Icing lib in milliseconds. */
getSaveDocumentLatencyMillis()168     public int getSaveDocumentLatencyMillis() {
169         return mBundle.getInt(SAVE_DOCUMENT_LATENCY_MILLIS_FIELD);
170     }
171 
172     /** Returns number of document that need to be migrated to another version. */
getTotalNeedMigratedDocumentCount()173     public int getTotalNeedMigratedDocumentCount() {
174         return mBundle.getInt(TOTAL_NEED_MIGRATED_DOCUMENT_COUNT_FIELD);
175     }
176 
177     /** Returns number of {@link android.app.appsearch.SetSchemaResponse.MigrationFailure}. */
getMigrationFailureCount()178     public int getMigrationFailureCount() {
179         return mBundle.getInt(MIGRATION_FAILURE_COUNT_FIELD);
180     }
181 
182     /** Returns number of successfully migrated and saved in Icing. */
getTotalSuccessMigratedDocumentCount()183     public int getTotalSuccessMigratedDocumentCount() {
184         return mBundle.getInt(TOTAL_SUCCESS_MIGRATED_DOCUMENT_COUNT_FIELD);
185     }
186 
187     /** Builder for {@link SchemaMigrationStats}. */
188     public static class Builder {
189 
190         private final Bundle mBundle;
191 
192         /** Creates a {@link SchemaMigrationStats.Builder}. */
Builder(@onNull String packageName, @NonNull String database)193         public Builder(@NonNull String packageName, @NonNull String database) {
194             mBundle = new Bundle();
195             mBundle.putString(PACKAGE_NAME_FIELD, packageName);
196             mBundle.putString(DATABASE_FIELD, database);
197         }
198 
199         /**
200          * Creates a {@link SchemaMigrationStats.Builder} from a given {@link SchemaMigrationStats}.
201          *
202          * <p>The returned builder is a deep copy whose data is separate from this
203          * SchemaMigrationStats.
204          */
Builder(@onNull SchemaMigrationStats stats)205         public Builder(@NonNull SchemaMigrationStats stats) {
206             mBundle = BundleUtil.deepCopy(stats.mBundle);
207         }
208 
209         /**
210          * Creates a new {@link SchemaMigrationStats.Builder} from the given Bundle
211          *
212          * <p>The bundle is NOT copied.
213          */
Builder(@onNull Bundle bundle)214         public Builder(@NonNull Bundle bundle) {
215             mBundle = Objects.requireNonNull(bundle);
216         }
217 
218         /** Sets status code for the schema migration action. */
219         @CanIgnoreReturnValue
220         @NonNull
setStatusCode(@ppSearchResult.ResultCode int statusCode)221         public Builder setStatusCode(@AppSearchResult.ResultCode int statusCode) {
222             mBundle.putInt(STATUS_CODE_FIELD, statusCode);
223             return this;
224         }
225 
226         /** Sets the latency for waiting the executor. */
227         @CanIgnoreReturnValue
228         @NonNull
setExecutorAcquisitionLatencyMillis(int executorAcquisitionLatencyMillis)229         public Builder setExecutorAcquisitionLatencyMillis(int executorAcquisitionLatencyMillis) {
230             mBundle.putInt(EXECUTOR_ACQUISITION_MILLIS_FIELD, executorAcquisitionLatencyMillis);
231             return this;
232         }
233 
234         /** Sets total latency for the schema migration action in milliseconds. */
235         @CanIgnoreReturnValue
236         @NonNull
setTotalLatencyMillis(int totalLatencyMillis)237         public Builder setTotalLatencyMillis(int totalLatencyMillis) {
238             mBundle.putInt(TOTAL_LATENCY_MILLIS_FIELD, totalLatencyMillis);
239             return this;
240         }
241 
242         /** Sets latency for the GetSchema action in milliseconds. */
243         @CanIgnoreReturnValue
244         @NonNull
setGetSchemaLatencyMillis(int getSchemaLatencyMillis)245         public Builder setGetSchemaLatencyMillis(int getSchemaLatencyMillis) {
246             mBundle.putInt(GET_SCHEMA_LATENCY_MILLIS_FIELD, getSchemaLatencyMillis);
247             return this;
248         }
249 
250         /**
251          * Sets latency for querying all documents that need to be migrated to new version and
252          * transforming documents to new version in milliseconds.
253          */
254         @CanIgnoreReturnValue
255         @NonNull
setQueryAndTransformLatencyMillis(int queryAndTransformLatencyMillis)256         public Builder setQueryAndTransformLatencyMillis(int queryAndTransformLatencyMillis) {
257             mBundle.putInt(
258                     QUERY_AND_TRANSFORM_LATENCY_MILLIS_FIELD, queryAndTransformLatencyMillis);
259             return this;
260         }
261 
262         /** Sets latency of first SetSchema action in milliseconds. */
263         @CanIgnoreReturnValue
264         @NonNull
setFirstSetSchemaLatencyMillis(int firstSetSchemaLatencyMillis)265         public Builder setFirstSetSchemaLatencyMillis(int firstSetSchemaLatencyMillis) {
266             mBundle.putInt(FIRST_SET_SCHEMA_LATENCY_MILLIS_FIELD, firstSetSchemaLatencyMillis);
267             return this;
268         }
269 
270         /** Returns status of the first SetSchema action. */
271         @CanIgnoreReturnValue
272         @NonNull
setIsFirstSetSchemaSuccess(boolean isFirstSetSchemaSuccess)273         public Builder setIsFirstSetSchemaSuccess(boolean isFirstSetSchemaSuccess) {
274             mBundle.putBoolean(IS_FIRST_SET_SCHEMA_SUCCESS_FIELD, isFirstSetSchemaSuccess);
275             return this;
276         }
277 
278         /** Sets latency of second SetSchema action in milliseconds. */
279         @CanIgnoreReturnValue
280         @NonNull
setSecondSetSchemaLatencyMillis(int secondSetSchemaLatencyMillis)281         public Builder setSecondSetSchemaLatencyMillis(int secondSetSchemaLatencyMillis) {
282             mBundle.putInt(SECOND_SET_SCHEMA_LATENCY_MILLIS_FIELD, secondSetSchemaLatencyMillis);
283             return this;
284         }
285 
286         /** Sets latency for putting migrated document to Icing lib in milliseconds. */
287         @CanIgnoreReturnValue
288         @NonNull
setSaveDocumentLatencyMillis(int saveDocumentLatencyMillis)289         public Builder setSaveDocumentLatencyMillis(int saveDocumentLatencyMillis) {
290             mBundle.putInt(SAVE_DOCUMENT_LATENCY_MILLIS_FIELD, saveDocumentLatencyMillis);
291             return this;
292         }
293 
294         /** Sets number of document that need to be migrated to another version. */
295         @CanIgnoreReturnValue
296         @NonNull
setTotalNeedMigratedDocumentCount(int migratedDocumentCount)297         public Builder setTotalNeedMigratedDocumentCount(int migratedDocumentCount) {
298             mBundle.putInt(TOTAL_NEED_MIGRATED_DOCUMENT_COUNT_FIELD, migratedDocumentCount);
299             return this;
300         }
301 
302         /** Sets total document count of successfully migrated and saved in Icing. */
303         @CanIgnoreReturnValue
304         @NonNull
setTotalSuccessMigratedDocumentCount(int totalSuccessMigratedDocumentCount)305         public Builder setTotalSuccessMigratedDocumentCount(int totalSuccessMigratedDocumentCount) {
306             mBundle.putInt(
307                     TOTAL_SUCCESS_MIGRATED_DOCUMENT_COUNT_FIELD, totalSuccessMigratedDocumentCount);
308             return this;
309         }
310 
311         /** Sets number of {@link android.app.appsearch.SetSchemaResponse.MigrationFailure}. */
312         @CanIgnoreReturnValue
313         @NonNull
setMigrationFailureCount(int migrationFailureCount)314         public Builder setMigrationFailureCount(int migrationFailureCount) {
315             mBundle.putInt(MIGRATION_FAILURE_COUNT_FIELD, migrationFailureCount);
316             return this;
317         }
318 
319         /**
320          * Builds a new {@link SchemaMigrationStats} from the {@link SchemaMigrationStats.Builder}.
321          */
322         @NonNull
build()323         public SchemaMigrationStats build() {
324             return new SchemaMigrationStats(mBundle);
325         }
326     }
327 }
328