blob: b3d01fd6872636f9ef7fc65e3f30a04a31f626ad [file] [log] [blame]
Adam Lesinski35168002014-07-21 15:25:30 -07001/**
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy
6 * 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, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations
14 * under the License.
15 */
16package android.app.usage;
17
Makoto Onukiad623012017-05-15 09:29:34 -070018import android.annotation.IntDef;
Michael Wachenschwanz0b4ab1f2019-01-07 13:59:10 -080019import android.annotation.Nullable;
Amith Yamasani7ec89412018-02-07 08:48:49 -080020import android.annotation.SystemApi;
Mathew Inwood61e8ae62018-08-14 14:17:44 +010021import android.annotation.UnsupportedAppUsage;
Adam Lesinski7f61e962014-09-02 16:43:52 -070022import android.content.res.Configuration;
Mathew Inwood31755f92018-12-20 13:53:36 +000023import android.os.Build;
Adam Lesinski35168002014-07-21 15:25:30 -070024import android.os.Parcel;
25import android.os.Parcelable;
26
Makoto Onukiad623012017-05-15 09:29:34 -070027import java.lang.annotation.Retention;
28import java.lang.annotation.RetentionPolicy;
Adam Lesinski35168002014-07-21 15:25:30 -070029import java.util.Arrays;
30import java.util.List;
31
32/**
33 * A result returned from {@link android.app.usage.UsageStatsManager#queryEvents(long, long)}
34 * from which to read {@link android.app.usage.UsageEvents.Event} objects.
35 */
36public final class UsageEvents implements Parcelable {
37
Makoto Onukiad623012017-05-15 09:29:34 -070038 /** @hide */
39 public static final String INSTANT_APP_PACKAGE_NAME = "android.instant_app";
40
41 /** @hide */
42 public static final String INSTANT_APP_CLASS_NAME = "android.instant_class";
43
Adam Lesinski35168002014-07-21 15:25:30 -070044 /**
45 * An event representing a state change for a component.
46 */
47 public static final class Event {
48
49 /**
50 * No event type.
51 */
52 public static final int NONE = 0;
53
54 /**
Hui Yue497ad22019-01-25 15:54:57 -080055 * A device level event like {@link #DEVICE_SHUTDOWN} does not have package name, but some
56 * user code always expect a non-null {@link #mPackage} for every event. Use
57 * {@link #DEVICE_EVENT_PACKAGE_NAME} as packageName for these device level events.
58 * @hide
59 */
60 public static final String DEVICE_EVENT_PACKAGE_NAME = "android";
61
62 /**
Hui Yu03d12402018-12-06 18:00:37 -080063 * @deprecated by {@link #ACTIVITY_RESUMED}
64 */
65 @Deprecated
66 public static final int MOVE_TO_FOREGROUND = 1;
67
68 /**
Hui Yue361a232018-10-04 15:05:21 -070069 * An event type denoting that an {@link android.app.Activity} moved to the foreground.
70 * This event has a package name and class name associated with it and can be retrieved
71 * using {@link #getPackageName()} and {@link #getClassName()}.
72 * If a package has multiple activities, this event is reported for each activity that moves
73 * to foreground.
Hui Yu03d12402018-12-06 18:00:37 -080074 * This event is corresponding to {@link android.app.Activity#onResume()} of the
75 * activity's lifecycle.
Adam Lesinski35168002014-07-21 15:25:30 -070076 */
Hui Yu03d12402018-12-06 18:00:37 -080077 public static final int ACTIVITY_RESUMED = MOVE_TO_FOREGROUND;
78
79 /**
80 * @deprecated by {@link #ACTIVITY_PAUSED}
81 */
82 @Deprecated
83 public static final int MOVE_TO_BACKGROUND = 2;
Adam Lesinski35168002014-07-21 15:25:30 -070084
85 /**
Hui Yue361a232018-10-04 15:05:21 -070086 * An event type denoting that an {@link android.app.Activity} moved to the background.
87 * This event has a package name and class name associated with it and can be retrieved
88 * using {@link #getPackageName()} and {@link #getClassName()}.
89 * If a package has multiple activities, this event is reported for each activity that moves
90 * to background.
Hui Yu03d12402018-12-06 18:00:37 -080091 * This event is corresponding to {@link android.app.Activity#onPause()} of the activity's
92 * lifecycle.
Adam Lesinski35168002014-07-21 15:25:30 -070093 */
Hui Yu03d12402018-12-06 18:00:37 -080094 public static final int ACTIVITY_PAUSED = MOVE_TO_BACKGROUND;
Adam Lesinski35168002014-07-21 15:25:30 -070095
96 /**
97 * An event type denoting that a component was in the foreground when the stats
Hui Yu03d12402018-12-06 18:00:37 -080098 * rolled-over. This is effectively treated as a {@link #ACTIVITY_PAUSED}.
Adam Lesinski35168002014-07-21 15:25:30 -070099 * {@hide}
100 */
101 public static final int END_OF_DAY = 3;
102
103 /**
104 * An event type denoting that a component was in the foreground the previous day.
Hui Yu03d12402018-12-06 18:00:37 -0800105 * This is effectively treated as a {@link #ACTIVITY_RESUMED}.
Adam Lesinski35168002014-07-21 15:25:30 -0700106 * {@hide}
107 */
108 public static final int CONTINUE_PREVIOUS_DAY = 4;
109
110 /**
Adam Lesinski7f61e962014-09-02 16:43:52 -0700111 * An event type denoting that the device configuration has changed.
112 */
113 public static final int CONFIGURATION_CHANGE = 5;
114
115 /**
Adam Lesinskic8e87292015-06-10 15:33:45 -0700116 * An event type denoting that a package was interacted with in some way by the system.
117 * @hide
Adam Lesinski978a1ed2015-03-02 11:37:24 -0800118 */
Michael Wachenschwanzf0acb022018-03-15 20:17:22 -0700119 @SystemApi
Adam Lesinskic8e87292015-06-10 15:33:45 -0700120 public static final int SYSTEM_INTERACTION = 6;
121
122 /**
123 * An event type denoting that a package was interacted with in some way by the user.
124 */
125 public static final int USER_INTERACTION = 7;
Adam Lesinski978a1ed2015-03-02 11:37:24 -0800126
127 /**
Makoto Onukiac042502016-05-20 16:39:42 -0700128 * An event type denoting that an action equivalent to a ShortcutInfo is taken by the user.
129 *
130 * @see android.content.pm.ShortcutManager#reportShortcutUsed(String)
131 */
132 public static final int SHORTCUT_INVOCATION = 8;
133
134 /**
Kang Li53b43142016-11-14 14:38:25 -0800135 * An event type denoting that a package was selected by the user for ChooserActivity.
136 * @hide
137 */
138 public static final int CHOOSER_ACTION = 9;
139
Amith Yamasani803eab692017-11-09 17:47:04 -0800140 /**
141 * An event type denoting that a notification was viewed by the user.
142 * @hide
143 */
Amith Yamasani7ec89412018-02-07 08:48:49 -0800144 @SystemApi
Amith Yamasani803eab692017-11-09 17:47:04 -0800145 public static final int NOTIFICATION_SEEN = 10;
146
Amith Yamasanibfc4bf52018-01-19 06:55:08 -0800147 /**
Suprabh Shukla4e12de82018-03-08 18:34:15 -0800148 * An event type denoting a change in App Standby Bucket. The new bucket can be
Amith Yamasaniff1575f2018-04-08 22:41:38 -0700149 * retrieved by calling {@link #getAppStandbyBucket()}.
Suprabh Shukla4e12de82018-03-08 18:34:15 -0800150 *
151 * @see UsageStatsManager#getAppStandbyBucket()
Amith Yamasanibfc4bf52018-01-19 06:55:08 -0800152 */
153 public static final int STANDBY_BUCKET_CHANGED = 11;
154
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500155 /**
156 * An event type denoting that an app posted an interruptive notification. Visual and
157 * audible interruptions are included.
158 * @hide
159 */
160 @SystemApi
161 public static final int NOTIFICATION_INTERRUPTION = 12;
162
Jason Monk1918ef72018-03-14 09:20:39 -0400163 /**
164 * A Slice was pinned by the default launcher or the default assistant.
165 * @hide
166 */
167 @SystemApi
168 public static final int SLICE_PINNED_PRIV = 13;
169
170 /**
171 * A Slice was pinned by an app.
172 * @hide
173 */
174 @SystemApi
175 public static final int SLICE_PINNED = 14;
176
Dianne Hackbornced54392018-02-26 13:07:42 -0800177 /**
178 * An event type denoting that the screen has gone in to an interactive state (turned
179 * on for full user interaction, not ambient display or other non-interactive state).
180 */
181 public static final int SCREEN_INTERACTIVE = 15;
182
183 /**
184 * An event type denoting that the screen has gone in to a non-interactive state
185 * (completely turned off or turned on only in a non-interactive state like ambient
186 * display).
187 */
188 public static final int SCREEN_NON_INTERACTIVE = 16;
189
Dianne Hackborn3378aa92018-03-30 17:43:49 -0700190 /**
191 * An event type denoting that the screen's keyguard has been shown, whether or not
192 * the screen is off.
193 */
194 public static final int KEYGUARD_SHOWN = 17;
195
196 /**
197 * An event type denoting that the screen's keyguard has been hidden. This typically
198 * happens when the user unlocks their phone after turning it on.
199 */
200 public static final int KEYGUARD_HIDDEN = 18;
201
Michael Wachenschwanzc8c26362018-09-07 14:59:25 -0700202 /**
Hui Yue361a232018-10-04 15:05:21 -0700203 * An event type denoting start of a foreground service.
204 * This event has a package name and class name associated with it and can be retrieved
205 * using {@link #getPackageName()} and {@link #getClassName()}.
206 * If a package has multiple foreground services, this event is reported for each service
207 * that is started.
208 */
209 public static final int FOREGROUND_SERVICE_START = 19;
210
211 /**
212 * An event type denoting stop of a foreground service.
213 * This event has a package name and class name associated with it and can be retrieved
214 * using {@link #getPackageName()} and {@link #getClassName()}.
215 * If a package has multiple foreground services, this event is reported for each service
216 * that is stopped.
217 */
218 public static final int FOREGROUND_SERVICE_STOP = 20;
219
220 /**
221 * An event type denoting that a foreground service is at started state at beginning of a
222 * time interval.
223 * This is effectively treated as a {@link #FOREGROUND_SERVICE_START}.
224 * {@hide}
225 */
226 public static final int CONTINUING_FOREGROUND_SERVICE = 21;
227
228 /**
229 * An event type denoting that a foreground service is at started state when the stats
230 * rolled-over at the end of a time interval.
231 * {@hide}
232 */
233 public static final int ROLLOVER_FOREGROUND_SERVICE = 22;
234
235 /**
Hui Yu03d12402018-12-06 18:00:37 -0800236 * An activity becomes invisible on the UI, corresponding to
237 * {@link android.app.Activity#onStop()} of the activity's lifecycle.
238 */
239 public static final int ACTIVITY_STOPPED = 23;
240
241 /**
242 * An activity object is destroyed, corresponding to
243 * {@link android.app.Activity#onDestroy()} of the activity's lifecycle.
244 * {@hide}
245 */
246 public static final int ACTIVITY_DESTROYED = 24;
247
248 /**
249 * The event type demoting that a flush of UsageStatsDatabase to file system. Before the
250 * flush all usage stats need to be updated to latest timestamp to make sure the most
251 * up to date stats are persisted.
252 * @hide
253 */
254 public static final int FLUSH_TO_DISK = 25;
255
256 /**
Hui Yu80a8b462019-03-05 15:22:13 -0800257 * An event type denoting that the Android runtime underwent a shutdown process.
Hui Yub1d243a2018-12-13 12:02:00 -0800258 * A DEVICE_SHUTDOWN event should be treated as if all started activities and foreground
259 * services are now stopped and no explicit {@link #ACTIVITY_STOPPED} and
260 * {@link #FOREGROUND_SERVICE_STOP} events will be generated for them.
Hui Yu80a8b462019-03-05 15:22:13 -0800261 *
262 * <p>The DEVICE_SHUTDOWN timestamp is actually the last time UsageStats database is
263 * persisted before the actual shutdown. Events (if there are any) between this timestamp
264 * and the actual shutdown is not persisted in the database. So any open events without
265 * matching close events between DEVICE_SHUTDOWN and {@link #DEVICE_STARTUP} should be
266 * ignored because the closing time is unknown.</p>
Hui Yub1d243a2018-12-13 12:02:00 -0800267 */
268 public static final int DEVICE_SHUTDOWN = 26;
269
270 /**
Hui Yu80a8b462019-03-05 15:22:13 -0800271 * An event type denoting that the Android runtime started up. This could be after a
272 * shutdown or a runtime restart. Any open events without matching close events between
273 * {@link #DEVICE_SHUTDOWN} and DEVICE_STARTUP should be ignored because the closing time is
274 * unknown.
275 */
276 public static final int DEVICE_STARTUP = 27;
277
278 /**
Michael Wachenschwanzc8c26362018-09-07 14:59:25 -0700279 * Keep in sync with the greatest event type value.
280 * @hide
281 */
Hui Yu80a8b462019-03-05 15:22:13 -0800282 public static final int MAX_EVENT_TYPE = 27;
Michael Wachenschwanzc8c26362018-09-07 14:59:25 -0700283
Makoto Onukiad623012017-05-15 09:29:34 -0700284 /** @hide */
285 public static final int FLAG_IS_PACKAGE_INSTANT_APP = 1 << 0;
286
287 /** @hide */
Jeff Sharkeyce8db992017-12-13 20:05:05 -0700288 @IntDef(flag = true, prefix = { "FLAG_" }, value = {
289 FLAG_IS_PACKAGE_INSTANT_APP,
290 })
Makoto Onukiad623012017-05-15 09:29:34 -0700291 @Retention(RetentionPolicy.SOURCE)
292 public @interface EventFlags {}
293
Kang Li53b43142016-11-14 14:38:25 -0800294 /**
Michael Wachenschwanzc8c26362018-09-07 14:59:25 -0700295 * Bitwise OR all valid flag constants to create this constant.
296 * @hide
297 */
298 public static final int VALID_FLAG_BITS = FLAG_IS_PACKAGE_INSTANT_APP;
299
300 /**
Adam Lesinski35168002014-07-21 15:25:30 -0700301 * {@hide}
302 */
Mathew Inwood31755f92018-12-20 13:53:36 +0000303 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Adam Lesinski9d960752014-08-25 14:48:12 -0700304 public String mPackage;
305
306 /**
307 * {@hide}
308 */
Mathew Inwood31755f92018-12-20 13:53:36 +0000309 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Adam Lesinski9d960752014-08-25 14:48:12 -0700310 public String mClass;
Adam Lesinski35168002014-07-21 15:25:30 -0700311
Hui Yu03d12402018-12-06 18:00:37 -0800312 /**
313 * {@hide}
314 */
315 public int mInstanceId;
316
Adam Lesinski35168002014-07-21 15:25:30 -0700317 /**
318 * {@hide}
319 */
Michael Wachenschwanz0b4ab1f2019-01-07 13:59:10 -0800320 public String mTaskRootPackage;
321
322 /**
323 * {@hide}
324 */
325 public String mTaskRootClass;
326
327 /**
328 * {@hide}
329 */
Mathew Inwood31755f92018-12-20 13:53:36 +0000330 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Adam Lesinski35168002014-07-21 15:25:30 -0700331 public long mTimeStamp;
332
333 /**
334 * {@hide}
335 */
Mathew Inwood31755f92018-12-20 13:53:36 +0000336 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Adam Lesinski35168002014-07-21 15:25:30 -0700337 public int mEventType;
338
339 /**
Adam Lesinski7f61e962014-09-02 16:43:52 -0700340 * Only present for {@link #CONFIGURATION_CHANGE} event types.
341 * {@hide}
342 */
Mathew Inwood31755f92018-12-20 13:53:36 +0000343 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Adam Lesinski7f61e962014-09-02 16:43:52 -0700344 public Configuration mConfiguration;
345
346 /**
Makoto Onukiac042502016-05-20 16:39:42 -0700347 * ID of the shortcut.
348 * Only present for {@link #SHORTCUT_INVOCATION} event types.
349 * {@hide}
350 */
351 public String mShortcutId;
352
353 /**
Kang Li53b43142016-11-14 14:38:25 -0800354 * Action type passed to ChooserActivity
355 * Only present for {@link #CHOOSER_ACTION} event types.
356 * {@hide}
357 */
358 public String mAction;
359
360 /**
361 * Content type passed to ChooserActivity.
362 * Only present for {@link #CHOOSER_ACTION} event types.
363 * {@hide}
364 */
365 public String mContentType;
366
367 /**
368 * Content annotations passed to ChooserActivity.
369 * Only present for {@link #CHOOSER_ACTION} event types.
370 * {@hide}
371 */
372 public String[] mContentAnnotations;
373
Amith Yamasanibfc4bf52018-01-19 06:55:08 -0800374 /**
Amith Yamasani119be9a2018-02-18 22:23:00 -0800375 * The app standby bucket assigned and reason. Bucket is the high order 16 bits, reason
376 * is the low order 16 bits.
Amith Yamasanibfc4bf52018-01-19 06:55:08 -0800377 * Only present for {@link #STANDBY_BUCKET_CHANGED} event types
378 * {@hide}
379 */
Amith Yamasani119be9a2018-02-18 22:23:00 -0800380 public int mBucketAndReason;
Amith Yamasanibfc4bf52018-01-19 06:55:08 -0800381
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500382 /**
383 * The id of the {@link android.app.NotificationChannel} to which an interruptive
384 * notification was posted.
385 * Only present for {@link #NOTIFICATION_INTERRUPTION} event types.
386 * {@hide}
387 */
388 public String mNotificationChannelId;
389
Makoto Onukiad623012017-05-15 09:29:34 -0700390 /** @hide */
391 @EventFlags
392 public int mFlags;
393
394 public Event() {
395 }
396
397 /** @hide */
Hui Yu03d12402018-12-06 18:00:37 -0800398 public Event(int type, long timeStamp) {
399 mEventType = type;
400 mTimeStamp = timeStamp;
401 }
402
403 /** @hide */
Makoto Onukiad623012017-05-15 09:29:34 -0700404 public Event(Event orig) {
405 mPackage = orig.mPackage;
406 mClass = orig.mClass;
Hui Yu03d12402018-12-06 18:00:37 -0800407 mInstanceId = orig.mInstanceId;
Michael Wachenschwanz0b4ab1f2019-01-07 13:59:10 -0800408 mTaskRootPackage = orig.mTaskRootPackage;
409 mTaskRootClass = orig.mTaskRootClass;
Makoto Onukiad623012017-05-15 09:29:34 -0700410 mTimeStamp = orig.mTimeStamp;
411 mEventType = orig.mEventType;
412 mConfiguration = orig.mConfiguration;
413 mShortcutId = orig.mShortcutId;
414 mAction = orig.mAction;
415 mContentType = orig.mContentType;
416 mContentAnnotations = orig.mContentAnnotations;
417 mFlags = orig.mFlags;
Amith Yamasani119be9a2018-02-18 22:23:00 -0800418 mBucketAndReason = orig.mBucketAndReason;
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500419 mNotificationChannelId = orig.mNotificationChannelId;
Makoto Onukiad623012017-05-15 09:29:34 -0700420 }
421
Kang Li53b43142016-11-14 14:38:25 -0800422 /**
Adam Lesinski9d960752014-08-25 14:48:12 -0700423 * The package name of the source of this event.
424 */
425 public String getPackageName() {
426 return mPackage;
427 }
428
429 /**
Dimuthu Gamage88ebac42019-01-14 08:28:13 -0800430 * Indicates whether it is an instant app.
431 * STOPSHIP b/111407095: Add GTS tests for the newly added API method.
432 * @hide
433 */
434 @SystemApi
435 public boolean isInstantApp() {
436 return (mFlags & FLAG_IS_PACKAGE_INSTANT_APP) == FLAG_IS_PACKAGE_INSTANT_APP;
437 }
438
439 /**
Adam Lesinski9d960752014-08-25 14:48:12 -0700440 * The class name of the source of this event. This may be null for
441 * certain events.
442 */
443 public String getClassName() {
444 return mClass;
Adam Lesinski35168002014-07-21 15:25:30 -0700445 }
446
447 /**
Hui Yu03d12402018-12-06 18:00:37 -0800448 * An activity can be instantiated multiple times, this is the unique activity instance ID.
449 * For non-activity class, instance ID is always zero.
450 * @hide
451 */
452 @SystemApi
453 public int getInstanceId() {
454 return mInstanceId;
455 }
456
457 /**
Michael Wachenschwanz0b4ab1f2019-01-07 13:59:10 -0800458 * The package name of the task root when this event was reported.
459 * Or {@code null} for queries from apps without {@link
460 * android.Manifest.permission#PACKAGE_USAGE_STATS}
461 * @hide
462 */
463 @SystemApi
464 public @Nullable String getTaskRootPackageName() {
465 return mTaskRootPackage;
466 }
467
468 /**
469 * The class name of the task root when this event was reported.
470 * Or {@code null} for queries from apps without {@link
471 * android.Manifest.permission#PACKAGE_USAGE_STATS}
472 * @hide
473 */
474 @SystemApi
475 public @Nullable String getTaskRootClassName() {
476 return mTaskRootClass;
477 }
478
479 /**
Adam Lesinskicc562a82014-08-27 11:52:52 -0700480 * The time at which this event occurred, measured in milliseconds since the epoch.
481 * <p/>
482 * See {@link System#currentTimeMillis()}.
Adam Lesinski35168002014-07-21 15:25:30 -0700483 */
484 public long getTimeStamp() {
485 return mTimeStamp;
486 }
487
488 /**
489 * The event type.
Hui Yu03d12402018-12-06 18:00:37 -0800490 * @see #ACTIVITY_PAUSED
491 * @see #ACTIVITY_RESUMED
Suprabh Shukla4e12de82018-03-08 18:34:15 -0800492 * @see #CONFIGURATION_CHANGE
493 * @see #USER_INTERACTION
494 * @see #STANDBY_BUCKET_CHANGED
Hui Yu03d12402018-12-06 18:00:37 -0800495 * @see #FOREGROUND_SERVICE_START
496 * @see #FOREGROUND_SERVICE_STOP
497 * @see #ACTIVITY_STOPPED
Adam Lesinski35168002014-07-21 15:25:30 -0700498 */
499 public int getEventType() {
500 return mEventType;
501 }
Adam Lesinski7f61e962014-09-02 16:43:52 -0700502
503 /**
504 * Returns a {@link Configuration} for this event if the event is of type
505 * {@link #CONFIGURATION_CHANGE}, otherwise it returns null.
506 */
507 public Configuration getConfiguration() {
508 return mConfiguration;
509 }
Makoto Onukiac042502016-05-20 16:39:42 -0700510
511 /**
512 * Returns the ID of a {@link android.content.pm.ShortcutInfo} for this event
513 * if the event is of type {@link #SHORTCUT_INVOCATION}, otherwise it returns null.
514 *
515 * @see android.content.pm.ShortcutManager#reportShortcutUsed(String)
516 */
517 public String getShortcutId() {
518 return mShortcutId;
519 }
Makoto Onukiad623012017-05-15 09:29:34 -0700520
Amith Yamasani7ec89412018-02-07 08:48:49 -0800521 /**
522 * Returns the standby bucket of the app, if the event is of type
523 * {@link #STANDBY_BUCKET_CHANGED}, otherwise returns 0.
524 * @return the standby bucket associated with the event.
Amith Yamasaniff1575f2018-04-08 22:41:38 -0700525 * @hide
Amith Yamasani7ec89412018-02-07 08:48:49 -0800526 */
Amith Yamasani7ec89412018-02-07 08:48:49 -0800527 public int getStandbyBucket() {
Amith Yamasani119be9a2018-02-18 22:23:00 -0800528 return (mBucketAndReason & 0xFFFF0000) >>> 16;
529 }
530
531 /**
Amith Yamasaniff1575f2018-04-08 22:41:38 -0700532 * Returns the standby bucket of the app, if the event is of type
533 * {@link #STANDBY_BUCKET_CHANGED}, otherwise returns 0.
534 * @return the standby bucket associated with the event.
535 *
536 */
537 public int getAppStandbyBucket() {
538 return (mBucketAndReason & 0xFFFF0000) >>> 16;
539 }
540
541 /**
Amith Yamasani119be9a2018-02-18 22:23:00 -0800542 * Returns the reason for the bucketing, if the event is of type
543 * {@link #STANDBY_BUCKET_CHANGED}, otherwise returns 0. Reason values include
544 * the main reason which is one of REASON_MAIN_*, OR'ed with REASON_SUB_*, if there
545 * are sub-reasons for the main reason, such as REASON_SUB_USAGE_* when the main reason
546 * is REASON_MAIN_USAGE.
547 * @hide
548 */
549 public int getStandbyReason() {
550 return mBucketAndReason & 0x0000FFFF;
Amith Yamasani7ec89412018-02-07 08:48:49 -0800551 }
552
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500553 /**
554 * Returns the ID of the {@link android.app.NotificationChannel} for this event if the
555 * event is of type {@link #NOTIFICATION_INTERRUPTION}, otherwise it returns null;
556 * @hide
557 */
558 @SystemApi
559 public String getNotificationChannelId() {
560 return mNotificationChannelId;
561 }
562
Makoto Onukiad623012017-05-15 09:29:34 -0700563 /** @hide */
564 public Event getObfuscatedIfInstantApp() {
Dimuthu Gamage88ebac42019-01-14 08:28:13 -0800565 if (!isInstantApp()) {
Makoto Onukiad623012017-05-15 09:29:34 -0700566 return this;
567 }
568 final Event ret = new Event(this);
569 ret.mPackage = INSTANT_APP_PACKAGE_NAME;
570 ret.mClass = INSTANT_APP_CLASS_NAME;
571
572 // Note there are other string fields too, but they're for app shortcuts and choosers,
573 // which instant apps can't use anyway, so there's no need to hide them.
574 return ret;
575 }
Adam Lesinski35168002014-07-21 15:25:30 -0700576 }
577
578 // Only used when creating the resulting events. Not used for reading/unparceling.
Mathew Inwood31755f92018-12-20 13:53:36 +0000579 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Adam Lesinski35168002014-07-21 15:25:30 -0700580 private List<Event> mEventsToWrite = null;
581
582 // Only used for reading/unparceling events.
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100583 @UnsupportedAppUsage
Adam Lesinski35168002014-07-21 15:25:30 -0700584 private Parcel mParcel = null;
Mathew Inwood31755f92018-12-20 13:53:36 +0000585 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Adam Lesinski35168002014-07-21 15:25:30 -0700586 private final int mEventCount;
587
Mathew Inwood31755f92018-12-20 13:53:36 +0000588 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Adam Lesinski35168002014-07-21 15:25:30 -0700589 private int mIndex = 0;
590
Michael Wachenschwanz0b4ab1f2019-01-07 13:59:10 -0800591 // Only used when parceling events. If false, task roots will be omitted from the parcel
592 private final boolean mIncludeTaskRoots;
593
Adam Lesinski35168002014-07-21 15:25:30 -0700594 /*
595 * In order to save space, since ComponentNames will be duplicated everywhere,
596 * we use a map and index into it.
597 */
Mathew Inwood31755f92018-12-20 13:53:36 +0000598 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Adam Lesinski9d960752014-08-25 14:48:12 -0700599 private String[] mStringPool;
Adam Lesinski35168002014-07-21 15:25:30 -0700600
601 /**
602 * Construct the iterator from a parcel.
603 * {@hide}
604 */
Mathew Inwood31755f92018-12-20 13:53:36 +0000605 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Adam Lesinski35168002014-07-21 15:25:30 -0700606 public UsageEvents(Parcel in) {
Michael Wachenschwanz76d03fc2018-05-24 17:21:02 +0000607 byte[] bytes = in.readBlob();
608 Parcel data = Parcel.obtain();
609 data.unmarshall(bytes, 0, bytes.length);
610 data.setDataPosition(0);
611 mEventCount = data.readInt();
612 mIndex = data.readInt();
Adam Lesinski35168002014-07-21 15:25:30 -0700613 if (mEventCount > 0) {
Michael Wachenschwanz76d03fc2018-05-24 17:21:02 +0000614 mStringPool = data.createStringArray();
Adam Lesinski35168002014-07-21 15:25:30 -0700615
Michael Wachenschwanz76d03fc2018-05-24 17:21:02 +0000616 final int listByteLength = data.readInt();
617 final int positionInParcel = data.readInt();
Adam Lesinski35168002014-07-21 15:25:30 -0700618 mParcel = Parcel.obtain();
619 mParcel.setDataPosition(0);
Michael Wachenschwanz76d03fc2018-05-24 17:21:02 +0000620 mParcel.appendFrom(data, data.dataPosition(), listByteLength);
Adam Lesinski35168002014-07-21 15:25:30 -0700621 mParcel.setDataSize(mParcel.dataPosition());
622 mParcel.setDataPosition(positionInParcel);
623 }
Michael Wachenschwanz0b4ab1f2019-01-07 13:59:10 -0800624 mIncludeTaskRoots = true;
Adam Lesinski35168002014-07-21 15:25:30 -0700625 }
626
627 /**
628 * Create an empty iterator.
629 * {@hide}
630 */
631 UsageEvents() {
632 mEventCount = 0;
Michael Wachenschwanz0b4ab1f2019-01-07 13:59:10 -0800633 mIncludeTaskRoots = true;
634 }
635
636 /**
637 * Construct the iterator in preparation for writing it to a parcel.
638 * Defaults to excluding task roots from the parcel.
639 * {@hide}
640 */
641 public UsageEvents(List<Event> events, String[] stringPool) {
642 this(events, stringPool, false);
Adam Lesinski35168002014-07-21 15:25:30 -0700643 }
644
645 /**
646 * Construct the iterator in preparation for writing it to a parcel.
647 * {@hide}
648 */
Michael Wachenschwanz0b4ab1f2019-01-07 13:59:10 -0800649 public UsageEvents(List<Event> events, String[] stringPool, boolean includeTaskRoots) {
Adam Lesinski9d960752014-08-25 14:48:12 -0700650 mStringPool = stringPool;
Adam Lesinski35168002014-07-21 15:25:30 -0700651 mEventCount = events.size();
652 mEventsToWrite = events;
Michael Wachenschwanz0b4ab1f2019-01-07 13:59:10 -0800653 mIncludeTaskRoots = includeTaskRoots;
Adam Lesinski35168002014-07-21 15:25:30 -0700654 }
655
656 /**
657 * Returns whether or not there are more events to read using
658 * {@link #getNextEvent(android.app.usage.UsageEvents.Event)}.
659 *
660 * @return true if there are more events, false otherwise.
661 */
662 public boolean hasNextEvent() {
663 return mIndex < mEventCount;
664 }
665
666 /**
667 * Retrieve the next {@link android.app.usage.UsageEvents.Event} from the collection and put the
668 * resulting data into {@code eventOut}.
669 *
670 * @param eventOut The {@link android.app.usage.UsageEvents.Event} object that will receive the
671 * next event data.
672 * @return true if an event was available, false if there are no more events.
673 */
674 public boolean getNextEvent(Event eventOut) {
675 if (mIndex >= mEventCount) {
676 return false;
677 }
678
Adam Lesinski7f61e962014-09-02 16:43:52 -0700679 readEventFromParcel(mParcel, eventOut);
Adam Lesinski9d960752014-08-25 14:48:12 -0700680
Adam Lesinski35168002014-07-21 15:25:30 -0700681 mIndex++;
Adam Lesinski35168002014-07-21 15:25:30 -0700682 if (mIndex >= mEventCount) {
683 mParcel.recycle();
684 mParcel = null;
685 }
686 return true;
687 }
688
689 /**
690 * Resets the collection so that it can be iterated over from the beginning.
Adam Lesinski54e064b2014-10-08 12:33:16 -0700691 *
692 * @hide When this object is iterated to completion, the parcel is destroyed and
693 * so resetToStart doesn't work.
Adam Lesinski35168002014-07-21 15:25:30 -0700694 */
695 public void resetToStart() {
696 mIndex = 0;
697 if (mParcel != null) {
698 mParcel.setDataPosition(0);
699 }
700 }
701
Mathew Inwood31755f92018-12-20 13:53:36 +0000702 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Adam Lesinski9d960752014-08-25 14:48:12 -0700703 private int findStringIndex(String str) {
704 final int index = Arrays.binarySearch(mStringPool, str);
705 if (index < 0) {
706 throw new IllegalStateException("String '" + str + "' is not in the string pool");
707 }
708 return index;
709 }
710
Adam Lesinski7f61e962014-09-02 16:43:52 -0700711 /**
712 * Writes a single event to the parcel. Modify this when updating {@link Event}.
713 */
Mathew Inwood31755f92018-12-20 13:53:36 +0000714 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Adam Lesinski7f61e962014-09-02 16:43:52 -0700715 private void writeEventToParcel(Event event, Parcel p, int flags) {
716 final int packageIndex;
717 if (event.mPackage != null) {
718 packageIndex = findStringIndex(event.mPackage);
719 } else {
720 packageIndex = -1;
721 }
722
723 final int classIndex;
724 if (event.mClass != null) {
725 classIndex = findStringIndex(event.mClass);
726 } else {
727 classIndex = -1;
728 }
Michael Wachenschwanz0b4ab1f2019-01-07 13:59:10 -0800729
730 final int taskRootPackageIndex;
731 if (mIncludeTaskRoots && event.mTaskRootPackage != null) {
732 taskRootPackageIndex = findStringIndex(event.mTaskRootPackage);
733 } else {
734 taskRootPackageIndex = -1;
735 }
736
737 final int taskRootClassIndex;
738 if (mIncludeTaskRoots && event.mTaskRootClass != null) {
739 taskRootClassIndex = findStringIndex(event.mTaskRootClass);
740 } else {
741 taskRootClassIndex = -1;
742 }
Adam Lesinski7f61e962014-09-02 16:43:52 -0700743 p.writeInt(packageIndex);
744 p.writeInt(classIndex);
Hui Yu03d12402018-12-06 18:00:37 -0800745 p.writeInt(event.mInstanceId);
Michael Wachenschwanz0b4ab1f2019-01-07 13:59:10 -0800746 p.writeInt(taskRootPackageIndex);
747 p.writeInt(taskRootClassIndex);
Adam Lesinski7f61e962014-09-02 16:43:52 -0700748 p.writeInt(event.mEventType);
749 p.writeLong(event.mTimeStamp);
750
Makoto Onukiac042502016-05-20 16:39:42 -0700751 switch (event.mEventType) {
752 case Event.CONFIGURATION_CHANGE:
753 event.mConfiguration.writeToParcel(p, flags);
754 break;
755 case Event.SHORTCUT_INVOCATION:
756 p.writeString(event.mShortcutId);
757 break;
Kang Li53b43142016-11-14 14:38:25 -0800758 case Event.CHOOSER_ACTION:
759 p.writeString(event.mAction);
760 p.writeString(event.mContentType);
761 p.writeStringArray(event.mContentAnnotations);
762 break;
Amith Yamasanibfc4bf52018-01-19 06:55:08 -0800763 case Event.STANDBY_BUCKET_CHANGED:
Amith Yamasani119be9a2018-02-18 22:23:00 -0800764 p.writeInt(event.mBucketAndReason);
Amith Yamasanibfc4bf52018-01-19 06:55:08 -0800765 break;
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500766 case Event.NOTIFICATION_INTERRUPTION:
767 p.writeString(event.mNotificationChannelId);
768 break;
Adam Lesinski7f61e962014-09-02 16:43:52 -0700769 }
Dimuthu Gamage88ebac42019-01-14 08:28:13 -0800770 p.writeInt(event.mFlags);
Adam Lesinski7f61e962014-09-02 16:43:52 -0700771 }
772
773 /**
774 * Reads a single event from the parcel. Modify this when updating {@link Event}.
775 */
Mathew Inwood31755f92018-12-20 13:53:36 +0000776 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Adam Lesinski7f61e962014-09-02 16:43:52 -0700777 private void readEventFromParcel(Parcel p, Event eventOut) {
778 final int packageIndex = p.readInt();
779 if (packageIndex >= 0) {
780 eventOut.mPackage = mStringPool[packageIndex];
781 } else {
782 eventOut.mPackage = null;
783 }
784
785 final int classIndex = p.readInt();
786 if (classIndex >= 0) {
787 eventOut.mClass = mStringPool[classIndex];
788 } else {
789 eventOut.mClass = null;
790 }
Hui Yu03d12402018-12-06 18:00:37 -0800791 eventOut.mInstanceId = p.readInt();
Michael Wachenschwanz0b4ab1f2019-01-07 13:59:10 -0800792
793 final int taskRootPackageIndex = p.readInt();
794 if (taskRootPackageIndex >= 0) {
795 eventOut.mTaskRootPackage = mStringPool[taskRootPackageIndex];
796 } else {
797 eventOut.mTaskRootPackage = null;
798 }
799
800 final int taskRootClassIndex = p.readInt();
801 if (taskRootClassIndex >= 0) {
802 eventOut.mTaskRootClass = mStringPool[taskRootClassIndex];
803 } else {
804 eventOut.mTaskRootClass = null;
805 }
806
Adam Lesinski7f61e962014-09-02 16:43:52 -0700807 eventOut.mEventType = p.readInt();
808 eventOut.mTimeStamp = p.readLong();
809
Makoto Onukiac042502016-05-20 16:39:42 -0700810 // Fill out the event-dependant fields.
811 eventOut.mConfiguration = null;
812 eventOut.mShortcutId = null;
Kang Li53b43142016-11-14 14:38:25 -0800813 eventOut.mAction = null;
814 eventOut.mContentType = null;
815 eventOut.mContentAnnotations = null;
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500816 eventOut.mNotificationChannelId = null;
Makoto Onukiac042502016-05-20 16:39:42 -0700817
818 switch (eventOut.mEventType) {
819 case Event.CONFIGURATION_CHANGE:
820 // Extract the configuration for configuration change events.
821 eventOut.mConfiguration = Configuration.CREATOR.createFromParcel(p);
822 break;
823 case Event.SHORTCUT_INVOCATION:
824 eventOut.mShortcutId = p.readString();
825 break;
Kang Li53b43142016-11-14 14:38:25 -0800826 case Event.CHOOSER_ACTION:
827 eventOut.mAction = p.readString();
828 eventOut.mContentType = p.readString();
829 eventOut.mContentAnnotations = p.createStringArray();
830 break;
Amith Yamasanibfc4bf52018-01-19 06:55:08 -0800831 case Event.STANDBY_BUCKET_CHANGED:
Amith Yamasani119be9a2018-02-18 22:23:00 -0800832 eventOut.mBucketAndReason = p.readInt();
Amith Yamasanibfc4bf52018-01-19 06:55:08 -0800833 break;
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500834 case Event.NOTIFICATION_INTERRUPTION:
835 eventOut.mNotificationChannelId = p.readString();
836 break;
Adam Lesinski7f61e962014-09-02 16:43:52 -0700837 }
Dimuthu Gamage88ebac42019-01-14 08:28:13 -0800838 eventOut.mFlags = p.readInt();
Adam Lesinski7f61e962014-09-02 16:43:52 -0700839 }
840
841 @Override
842 public int describeContents() {
843 return 0;
844 }
845
Adam Lesinski35168002014-07-21 15:25:30 -0700846 @Override
847 public void writeToParcel(Parcel dest, int flags) {
Michael Wachenschwanz76d03fc2018-05-24 17:21:02 +0000848 Parcel data = Parcel.obtain();
849 data.writeInt(mEventCount);
850 data.writeInt(mIndex);
Adam Lesinski35168002014-07-21 15:25:30 -0700851 if (mEventCount > 0) {
Michael Wachenschwanz76d03fc2018-05-24 17:21:02 +0000852 data.writeStringArray(mStringPool);
Adam Lesinski35168002014-07-21 15:25:30 -0700853
854 if (mEventsToWrite != null) {
855 // Write out the events
856 Parcel p = Parcel.obtain();
857 try {
858 p.setDataPosition(0);
859 for (int i = 0; i < mEventCount; i++) {
860 final Event event = mEventsToWrite.get(i);
Adam Lesinski7f61e962014-09-02 16:43:52 -0700861 writeEventToParcel(event, p, flags);
Adam Lesinski35168002014-07-21 15:25:30 -0700862 }
Adam Lesinski7f61e962014-09-02 16:43:52 -0700863
Adam Lesinski35168002014-07-21 15:25:30 -0700864 final int listByteLength = p.dataPosition();
865
866 // Write the total length of the data.
Michael Wachenschwanz76d03fc2018-05-24 17:21:02 +0000867 data.writeInt(listByteLength);
Adam Lesinski35168002014-07-21 15:25:30 -0700868
869 // Write our current position into the data.
Michael Wachenschwanz76d03fc2018-05-24 17:21:02 +0000870 data.writeInt(0);
Adam Lesinski35168002014-07-21 15:25:30 -0700871
872 // Write the data.
Michael Wachenschwanz76d03fc2018-05-24 17:21:02 +0000873 data.appendFrom(p, 0, listByteLength);
Adam Lesinski35168002014-07-21 15:25:30 -0700874 } finally {
875 p.recycle();
876 }
877
878 } else if (mParcel != null) {
879 // Write the total length of the data.
Michael Wachenschwanz76d03fc2018-05-24 17:21:02 +0000880 data.writeInt(mParcel.dataSize());
Adam Lesinski35168002014-07-21 15:25:30 -0700881
882 // Write out current position into the data.
Michael Wachenschwanz76d03fc2018-05-24 17:21:02 +0000883 data.writeInt(mParcel.dataPosition());
Adam Lesinski35168002014-07-21 15:25:30 -0700884
885 // Write the data.
Michael Wachenschwanz76d03fc2018-05-24 17:21:02 +0000886 data.appendFrom(mParcel, 0, mParcel.dataSize());
Adam Lesinski35168002014-07-21 15:25:30 -0700887 } else {
888 throw new IllegalStateException(
889 "Either mParcel or mEventsToWrite must not be null");
890 }
891 }
Michael Wachenschwanz76d03fc2018-05-24 17:21:02 +0000892 // Data can be too large for a transact. Write the data as a Blob, which will be written to
893 // ashmem if too large.
894 dest.writeBlob(data.marshall());
Adam Lesinski35168002014-07-21 15:25:30 -0700895 }
896
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700897 public static final @android.annotation.NonNull Creator<UsageEvents> CREATOR = new Creator<UsageEvents>() {
Adam Lesinski35168002014-07-21 15:25:30 -0700898 @Override
899 public UsageEvents createFromParcel(Parcel source) {
900 return new UsageEvents(source);
901 }
902
903 @Override
904 public UsageEvents[] newArray(int size) {
905 return new UsageEvents[size];
906 }
907 };
Adam Lesinski35168002014-07-21 15:25:30 -0700908}