blob: 8a6cc95319fbbca3352ad601679df91db4e43277 [file] [log] [blame]
Adam Lesinski0debc9a2014-07-16 19:09:13 -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 */
16
17package android.app.usage;
18
Amith Yamasaniafbccb72017-11-27 10:44:24 -080019import android.annotation.IntDef;
Amith Yamasanibc813eb2018-03-20 19:37:46 -070020import android.annotation.NonNull;
Michael Wachenschwanz641e3382018-10-23 23:21:48 -070021import android.annotation.Nullable;
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060022import android.annotation.RequiresPermission;
Amith Yamasaniaf575b92015-05-29 15:35:26 -070023import android.annotation.SystemApi;
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060024import android.annotation.SystemService;
Michael Wachenschwanz0b4ab1f2019-01-07 13:59:10 -080025import android.annotation.TestApi;
Michael Wachenschwanz36778522018-11-12 11:06:19 -080026import android.app.Activity;
Amith Yamasani62ec27e92018-03-11 14:42:06 -070027import android.app.PendingIntent;
Artur Satayevc895b1b2019-12-10 17:47:51 +000028import android.compat.annotation.UnsupportedAppUsage;
Adam Lesinski0debc9a2014-07-16 19:09:13 -070029import android.content.Context;
Adam Lesinski35168002014-07-21 15:25:30 -070030import android.content.pm.ParceledListSlice;
Mathew Inwood8c854f82018-09-14 12:35:36 +010031import android.os.Build;
Kweku Adams835283f2019-11-20 14:41:22 -080032import android.os.PowerWhitelistManager;
Adam Lesinski0debc9a2014-07-16 19:09:13 -070033import android.os.RemoteException;
Amith Yamasanicf768722015-04-23 20:36:41 -070034import android.os.UserHandle;
Varun Shah3a315202019-07-24 16:33:42 -070035import android.os.UserManager;
Adam Lesinski35168002014-07-21 15:25:30 -070036import android.util.ArrayMap;
Adam Lesinski0debc9a2014-07-16 19:09:13 -070037
Amith Yamasaniafbccb72017-11-27 10:44:24 -080038import java.lang.annotation.Retention;
39import java.lang.annotation.RetentionPolicy;
Varun Shah9f58b7c2019-03-01 10:36:21 -080040import java.time.Duration;
Suprabh Shukla868bde22018-02-20 20:59:52 -080041import java.util.ArrayList;
Adam Lesinski35168002014-07-21 15:25:30 -070042import java.util.Collections;
43import java.util.List;
Adam Lesinskicc562a82014-08-27 11:52:52 -070044import java.util.Map;
Amith Yamasani62ec27e92018-03-11 14:42:06 -070045import java.util.concurrent.TimeUnit;
Adam Lesinski35168002014-07-21 15:25:30 -070046
47/**
48 * Provides access to device usage history and statistics. Usage data is aggregated into
49 * time intervals: days, weeks, months, and years.
50 * <p />
51 * When requesting usage data since a particular time, the request might look something like this:
52 * <pre>
53 * PAST REQUEST_TIME TODAY FUTURE
54 * ————————————————————————————||———————————————————————————¦-----------------------|
55 * YEAR || ¦ |
56 * ————————————————————————————||———————————————————————————¦-----------------------|
57 * MONTH | || MONTH ¦ |
58 * ——————————————————|—————————||———————————————————————————¦-----------------------|
59 * | WEEK | WEEK|| | WEEK | WE¦EK | WEEK |
60 * ————————————————————————————||———————————————————|———————¦-----------------------|
61 * || |DAY|DAY|DAY|DAY¦DAY|DAY|DAY|DAY|DAY|DAY|
62 * ————————————————————————————||———————————————————————————¦-----------------------|
63 * </pre>
64 * A request for data in the middle of a time interval will include that interval.
65 * <p/>
Suprabh Shukla217ccda2018-02-23 17:57:12 -080066 * <b>NOTE:</b> Most methods on this API require the permission
67 * android.permission.PACKAGE_USAGE_STATS. However, declaring the permission implies intention to
68 * use the API and the user of the device still needs to grant permission through the Settings
69 * application.
70 * See {@link android.provider.Settings#ACTION_USAGE_ACCESS_SETTINGS}.
71 * Methods which only return the information for the calling package do not require this permission.
72 * E.g. {@link #getAppStandbyBucket()} and {@link #queryEventsForSelf(long, long)}.
Adam Lesinski35168002014-07-21 15:25:30 -070073 */
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060074@SystemService(Context.USAGE_STATS_SERVICE)
Adam Lesinski0debc9a2014-07-16 19:09:13 -070075public final class UsageStatsManager {
Adam Lesinski0debc9a2014-07-16 19:09:13 -070076
77 /**
Adam Lesinski35168002014-07-21 15:25:30 -070078 * An interval type that spans a day. See {@link #queryUsageStats(int, long, long)}.
Adam Lesinski0debc9a2014-07-16 19:09:13 -070079 */
Adam Lesinski35168002014-07-21 15:25:30 -070080 public static final int INTERVAL_DAILY = 0;
Adam Lesinski0debc9a2014-07-16 19:09:13 -070081
82 /**
Adam Lesinski35168002014-07-21 15:25:30 -070083 * An interval type that spans a week. See {@link #queryUsageStats(int, long, long)}.
Adam Lesinski0debc9a2014-07-16 19:09:13 -070084 */
Adam Lesinski35168002014-07-21 15:25:30 -070085 public static final int INTERVAL_WEEKLY = 1;
Adam Lesinski0debc9a2014-07-16 19:09:13 -070086
87 /**
Adam Lesinski35168002014-07-21 15:25:30 -070088 * An interval type that spans a month. See {@link #queryUsageStats(int, long, long)}.
Adam Lesinski0debc9a2014-07-16 19:09:13 -070089 */
Adam Lesinski35168002014-07-21 15:25:30 -070090 public static final int INTERVAL_MONTHLY = 2;
Adam Lesinski0debc9a2014-07-16 19:09:13 -070091
92 /**
Adam Lesinski35168002014-07-21 15:25:30 -070093 * An interval type that spans a year. See {@link #queryUsageStats(int, long, long)}.
94 */
95 public static final int INTERVAL_YEARLY = 3;
96
97 /**
98 * An interval type that will use the best fit interval for the given time range.
99 * See {@link #queryUsageStats(int, long, long)}.
100 */
101 public static final int INTERVAL_BEST = 4;
102
103 /**
104 * The number of available intervals. Does not include {@link #INTERVAL_BEST}, since it
105 * is a pseudo interval (it actually selects a real interval).
Adam Lesinski0debc9a2014-07-16 19:09:13 -0700106 * {@hide}
107 */
Adam Lesinski35168002014-07-21 15:25:30 -0700108 public static final int INTERVAL_COUNT = 4;
109
Amith Yamasaniafbccb72017-11-27 10:44:24 -0800110
111 /**
112 * The app is whitelisted for some reason and the bucket cannot be changed.
113 * {@hide}
114 */
115 @SystemApi
116 public static final int STANDBY_BUCKET_EXEMPTED = 5;
117
118 /**
Amith Yamasani853e53f2018-03-16 16:08:57 -0700119 * The app was used very recently, currently in use or likely to be used very soon. Standby
120 * bucket values that are &le; {@link #STANDBY_BUCKET_ACTIVE} will not be throttled by the
121 * system while they are in this bucket. Buckets &gt; {@link #STANDBY_BUCKET_ACTIVE} will most
122 * likely be restricted in some way. For instance, jobs and alarms may be deferred.
Amith Yamasaniafbccb72017-11-27 10:44:24 -0800123 * @see #getAppStandbyBucket()
124 */
125 public static final int STANDBY_BUCKET_ACTIVE = 10;
126
127 /**
Amith Yamasani853e53f2018-03-16 16:08:57 -0700128 * The app was used recently and/or likely to be used in the next few hours. Restrictions will
129 * apply to these apps, such as deferral of jobs and alarms.
Amith Yamasaniafbccb72017-11-27 10:44:24 -0800130 * @see #getAppStandbyBucket()
131 */
132 public static final int STANDBY_BUCKET_WORKING_SET = 20;
133
134 /**
135 * The app was used in the last few days and/or likely to be used in the next few days.
Amith Yamasani853e53f2018-03-16 16:08:57 -0700136 * Restrictions will apply to these apps, such as deferral of jobs and alarms. The delays may be
137 * greater than for apps in higher buckets (lower bucket value). Bucket values &gt;
138 * {@link #STANDBY_BUCKET_FREQUENT} may additionally have network access limited.
Amith Yamasaniafbccb72017-11-27 10:44:24 -0800139 * @see #getAppStandbyBucket()
140 */
141 public static final int STANDBY_BUCKET_FREQUENT = 30;
142
143 /**
144 * The app has not be used for several days and/or is unlikely to be used for several days.
Kweku Adamsc6a9b342020-01-08 18:37:26 -0800145 * Apps in this bucket will have more restrictions, including network restrictions, except
Amith Yamasani853e53f2018-03-16 16:08:57 -0700146 * during certain short periods (at a minimum, once a day) when they are allowed to execute
147 * jobs, access the network, etc.
Amith Yamasaniafbccb72017-11-27 10:44:24 -0800148 * @see #getAppStandbyBucket()
149 */
150 public static final int STANDBY_BUCKET_RARE = 40;
151
152 /**
Kweku Adamsc6a9b342020-01-08 18:37:26 -0800153 * The app has not be used for several days, is unlikely to be used for several days, and has
154 * been misbehaving in some manner.
155 * Apps in this bucket will have the most restrictions, including network restrictions and
156 * additional restrictions on jobs.
Kweku Adams71eac9e2020-06-04 11:22:04 -0700157 * <p> Note: this bucket is not enabled in {@link Build.VERSION_CODES#R}.
Kweku Adamsc6a9b342020-01-08 18:37:26 -0800158 * @see #getAppStandbyBucket()
159 */
160 public static final int STANDBY_BUCKET_RESTRICTED = 45;
161
162 /**
Amith Yamasaniafbccb72017-11-27 10:44:24 -0800163 * The app has never been used.
164 * {@hide}
165 */
166 @SystemApi
167 public static final int STANDBY_BUCKET_NEVER = 50;
168
Amith Yamasani119be9a2018-02-18 22:23:00 -0800169 /** @hide */
170 public static final int REASON_MAIN_MASK = 0xFF00;
171 /** @hide */
172 public static final int REASON_MAIN_DEFAULT = 0x0100;
Kweku Adamsd18f0732019-12-03 13:39:40 -0800173 /**
174 * The app spent sufficient time in the old bucket without any substantial event so it reached
175 * the timeout threshold to have its bucket lowered.
Kweku Adamsd18f0732019-12-03 13:39:40 -0800176 * @hide
177 */
Amith Yamasani119be9a2018-02-18 22:23:00 -0800178 public static final int REASON_MAIN_TIMEOUT = 0x0200;
Kweku Adamsd18f0732019-12-03 13:39:40 -0800179 /**
180 * The app was used in some way. Look at the REASON_SUB_USAGE_ reason for more details.
181 * @hide
182 */
Amith Yamasani119be9a2018-02-18 22:23:00 -0800183 public static final int REASON_MAIN_USAGE = 0x0300;
Kweku Adamsd18f0732019-12-03 13:39:40 -0800184 /**
Kweku Adamsc182d5e2020-01-08 18:37:26 -0800185 * Forced by the user/developer, either explicitly or implicitly through some action. If user
186 * action was not involved and this is purely due to the system,
187 * {@link #REASON_MAIN_FORCED_BY_SYSTEM} should be used instead.
Kweku Adamsd18f0732019-12-03 13:39:40 -0800188 * @hide
189 */
Kweku Adamsc182d5e2020-01-08 18:37:26 -0800190 public static final int REASON_MAIN_FORCED_BY_USER = 0x0400;
Kweku Adamsd18f0732019-12-03 13:39:40 -0800191 /**
Kweku Adamsc182d5e2020-01-08 18:37:26 -0800192 * Set by a privileged system app. This may be overridden by
193 * {@link #REASON_MAIN_FORCED_BY_SYSTEM} or user action.
Kweku Adamsd18f0732019-12-03 13:39:40 -0800194 * @hide
195 */
Amith Yamasani119be9a2018-02-18 22:23:00 -0800196 public static final int REASON_MAIN_PREDICTED = 0x0500;
Kweku Adamsc182d5e2020-01-08 18:37:26 -0800197 /**
198 * Forced by the system, independent of user action. If user action is involved,
199 * {@link #REASON_MAIN_FORCED_BY_USER} should be used instead. When this is used, only
200 * {@link #REASON_MAIN_FORCED_BY_SYSTEM} or user action can change the bucket.
201 * @hide
202 */
203 public static final int REASON_MAIN_FORCED_BY_SYSTEM = 0x0600;
Amith Yamasaniafbccb72017-11-27 10:44:24 -0800204
Amith Yamasani119be9a2018-02-18 22:23:00 -0800205 /** @hide */
206 public static final int REASON_SUB_MASK = 0x00FF;
Kweku Adamsd18f0732019-12-03 13:39:40 -0800207 /**
Kweku Adams917f8a42020-02-26 17:18:03 -0800208 * The reason for using the default main reason is unknown or undefined.
209 * @hide
210 */
211 public static final int REASON_SUB_DEFAULT_UNDEFINED = 0x0000;
212 /**
213 * The app was updated.
214 * @hide
215 */
216 public static final int REASON_SUB_DEFAULT_APP_UPDATE = 0x0001;
217 /**
Kweku Adamsd18f0732019-12-03 13:39:40 -0800218 * The app was interacted with in some way by the system.
219 * @hide
220 */
Amith Yamasani119be9a2018-02-18 22:23:00 -0800221 public static final int REASON_SUB_USAGE_SYSTEM_INTERACTION = 0x0001;
Kweku Adamsd18f0732019-12-03 13:39:40 -0800222 /**
223 * A notification was viewed by the user. This does not mean the user interacted with the
224 * notification.
225 * @hide
226 */
Amith Yamasani119be9a2018-02-18 22:23:00 -0800227 public static final int REASON_SUB_USAGE_NOTIFICATION_SEEN = 0x0002;
Kweku Adamsd18f0732019-12-03 13:39:40 -0800228 /**
229 * The app was interacted with in some way by the user. This includes interacting with
230 * notification.
231 * @hide
232 */
Amith Yamasani119be9a2018-02-18 22:23:00 -0800233 public static final int REASON_SUB_USAGE_USER_INTERACTION = 0x0003;
Kweku Adamsd18f0732019-12-03 13:39:40 -0800234 /**
235 * An {@link android.app.Activity} moved to the foreground.
236 * @hide
237 */
Amith Yamasani119be9a2018-02-18 22:23:00 -0800238 public static final int REASON_SUB_USAGE_MOVE_TO_FOREGROUND = 0x0004;
Kweku Adamsd18f0732019-12-03 13:39:40 -0800239 /**
240 * An {@link android.app.Activity} moved to the background.
241 * @hide
242 */
Amith Yamasani119be9a2018-02-18 22:23:00 -0800243 public static final int REASON_SUB_USAGE_MOVE_TO_BACKGROUND = 0x0005;
Kweku Adamsd18f0732019-12-03 13:39:40 -0800244 /**
245 * There was a system update.
246 * @hide
247 */
Amith Yamasani119be9a2018-02-18 22:23:00 -0800248 public static final int REASON_SUB_USAGE_SYSTEM_UPDATE = 0x0006;
Kweku Adamsd18f0732019-12-03 13:39:40 -0800249 /**
250 * An app is in an elevated bucket because of an active timeout preventing it from being placed
251 * in a lower bucket.
252 * @hide
253 */
Amith Yamasani119be9a2018-02-18 22:23:00 -0800254 public static final int REASON_SUB_USAGE_ACTIVE_TIMEOUT = 0x0007;
Kweku Adamsd18f0732019-12-03 13:39:40 -0800255 /**
256 * This system package's sync adapter has been used for another package's content provider.
257 * @hide
258 */
Amith Yamasani119be9a2018-02-18 22:23:00 -0800259 public static final int REASON_SUB_USAGE_SYNC_ADAPTER = 0x0008;
Kweku Adamsd18f0732019-12-03 13:39:40 -0800260 /**
261 * A slice was pinned by an app.
262 * @hide
263 */
Amith Yamasani80c4be82018-03-26 10:54:04 -0700264 public static final int REASON_SUB_USAGE_SLICE_PINNED = 0x0009;
Kweku Adamsd18f0732019-12-03 13:39:40 -0800265 /** /**
266 * A slice was pinned by the default launcher or the default assistant.
267 * @hide
268 */
Amith Yamasani80c4be82018-03-26 10:54:04 -0700269 public static final int REASON_SUB_USAGE_SLICE_PINNED_PRIV = 0x000A;
Kweku Adamsd18f0732019-12-03 13:39:40 -0800270 /**
271 * A sync operation that is exempt from app standby was scheduled when the device wasn't Dozing.
272 * @hide
273 */
Makoto Onukid5f25d22018-05-22 16:02:17 -0700274 public static final int REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_NON_DOZE = 0x000B;
Kweku Adamsd18f0732019-12-03 13:39:40 -0800275 /**
276 * A sync operation that is exempt from app standby was scheduled while the device was Dozing.
277 * @hide
278 */
Makoto Onukid5f25d22018-05-22 16:02:17 -0700279 public static final int REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_DOZE = 0x000C;
Kweku Adamsd18f0732019-12-03 13:39:40 -0800280 /**
281 * A sync operation that is exempt from app standby started.
282 * @hide
283 */
Makoto Onukid5f25d22018-05-22 16:02:17 -0700284 public static final int REASON_SUB_USAGE_EXEMPTED_SYNC_START = 0x000D;
Kweku Adamsd18f0732019-12-03 13:39:40 -0800285 /**
286 * A sync operation that is not exempt from app standby was scheduled.
287 * @hide
288 */
Michael Wachenschwanzc3295202019-02-20 17:19:52 -0800289 public static final int REASON_SUB_USAGE_UNEXEMPTED_SYNC_SCHEDULED = 0x000E;
Kweku Adamsd18f0732019-12-03 13:39:40 -0800290 /**
291 * A foreground service started.
292 * @hide
293 */
Michael Wachenschwanz6ced0ee2019-04-15 16:43:28 -0700294 public static final int REASON_SUB_USAGE_FOREGROUND_SERVICE_START = 0x000F;
Kweku Adamsd18f0732019-12-03 13:39:40 -0800295 /**
296 * The predicted bucket was restored after the app's temporary elevation to the ACTIVE bucket
297 * ended.
298 * @hide
299 */
Amith Yamasani3154dcf2018-03-27 18:24:04 -0700300 public static final int REASON_SUB_PREDICTED_RESTORED = 0x0001;
Kweku Adamsc6a9b342020-01-08 18:37:26 -0800301 /**
Kweku Adamsaa461942020-03-16 11:59:05 -0700302 * The reason the system forced the app into the bucket is unknown or undefined.
Kweku Adamsc6a9b342020-01-08 18:37:26 -0800303 * @hide
304 */
Kweku Adamsaa461942020-03-16 11:59:05 -0700305 public static final int REASON_SUB_FORCED_SYSTEM_FLAG_UNDEFINED = 0;
Kweku Adamsc6a9b342020-01-08 18:37:26 -0800306 /**
307 * The app was unnecessarily using system resources (battery, memory, etc) in the background.
308 * @hide
309 */
Kweku Adamsaa461942020-03-16 11:59:05 -0700310 public static final int REASON_SUB_FORCED_SYSTEM_FLAG_BACKGROUND_RESOURCE_USAGE = 1 << 0;
Kweku Adamsc6a9b342020-01-08 18:37:26 -0800311 /**
312 * The app was deemed to be intentionally abusive.
313 * @hide
314 */
Kweku Adamsaa461942020-03-16 11:59:05 -0700315 public static final int REASON_SUB_FORCED_SYSTEM_FLAG_ABUSE = 1 << 1;
Kweku Adamsc6a9b342020-01-08 18:37:26 -0800316 /**
317 * The app was displaying buggy behavior.
318 * @hide
319 */
Kweku Adamsaa461942020-03-16 11:59:05 -0700320 public static final int REASON_SUB_FORCED_SYSTEM_FLAG_BUGGY = 1 << 2;
Amith Yamasani3154dcf2018-03-27 18:24:04 -0700321
Makoto Onuki75ad2492018-03-28 14:42:42 -0700322
Amith Yamasani3154dcf2018-03-27 18:24:04 -0700323 /** @hide */
Jeff Sharkeyce8db992017-12-13 20:05:05 -0700324 @IntDef(flag = false, prefix = { "STANDBY_BUCKET_" }, value = {
Amith Yamasaniafbccb72017-11-27 10:44:24 -0800325 STANDBY_BUCKET_EXEMPTED,
326 STANDBY_BUCKET_ACTIVE,
327 STANDBY_BUCKET_WORKING_SET,
328 STANDBY_BUCKET_FREQUENT,
329 STANDBY_BUCKET_RARE,
Kweku Adamsc6a9b342020-01-08 18:37:26 -0800330 STANDBY_BUCKET_RESTRICTED,
Amith Yamasaniafbccb72017-11-27 10:44:24 -0800331 STANDBY_BUCKET_NEVER,
332 })
333 @Retention(RetentionPolicy.SOURCE)
334 public @interface StandbyBuckets {}
335
Kweku Adamsaa461942020-03-16 11:59:05 -0700336 /** @hide */
337 @IntDef(flag = true, prefix = {"REASON_SUB_FORCED_SYSTEM_FLAG_FLAG_"}, value = {
338 REASON_SUB_FORCED_SYSTEM_FLAG_UNDEFINED,
339 REASON_SUB_FORCED_SYSTEM_FLAG_BACKGROUND_RESOURCE_USAGE,
340 REASON_SUB_FORCED_SYSTEM_FLAG_ABUSE,
341 REASON_SUB_FORCED_SYSTEM_FLAG_BUGGY,
342 })
343 @Retention(RetentionPolicy.SOURCE)
344 public @interface SystemForcedReasons {
345 }
346
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700347 /**
348 * Observer id of the registered observer for the group of packages that reached the usage
349 * time limit. Included as an extra in the PendingIntent that was registered.
350 * @hide
351 */
352 @SystemApi
353 public static final String EXTRA_OBSERVER_ID = "android.app.usage.extra.OBSERVER_ID";
354
355 /**
356 * Original time limit in milliseconds specified by the registered observer for the group of
357 * packages that reached the usage time limit. Included as an extra in the PendingIntent that
358 * was registered.
359 * @hide
360 */
361 @SystemApi
362 public static final String EXTRA_TIME_LIMIT = "android.app.usage.extra.TIME_LIMIT";
363
364 /**
365 * Actual usage time in milliseconds for the group of packages that reached the specified time
366 * limit. Included as an extra in the PendingIntent that was registered.
367 * @hide
368 */
369 @SystemApi
370 public static final String EXTRA_TIME_USED = "android.app.usage.extra.TIME_USED";
371
Michael Wachenschwanz0b4ab1f2019-01-07 13:59:10 -0800372
373 /**
374 * App usage observers will consider the task root package the source of usage.
375 * @hide
376 */
377 @SystemApi
378 public static final int USAGE_SOURCE_TASK_ROOT_ACTIVITY = 1;
379
380 /**
381 * App usage observers will consider the visible activity's package the source of usage.
382 * @hide
383 */
384 @SystemApi
385 public static final int USAGE_SOURCE_CURRENT_ACTIVITY = 2;
386
387 /** @hide */
388 @IntDef(prefix = { "USAGE_SOURCE_" }, value = {
389 USAGE_SOURCE_TASK_ROOT_ACTIVITY,
390 USAGE_SOURCE_CURRENT_ACTIVITY,
391 })
392 @Retention(RetentionPolicy.SOURCE)
393 public @interface UsageSource {}
394
Mathew Inwood31755f92018-12-20 13:53:36 +0000395 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Adam Lesinski35168002014-07-21 15:25:30 -0700396 private static final UsageEvents sEmptyResults = new UsageEvents();
Adam Lesinski0debc9a2014-07-16 19:09:13 -0700397
Mathew Inwood8c854f82018-09-14 12:35:36 +0100398 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Adam Lesinski0debc9a2014-07-16 19:09:13 -0700399 private final Context mContext;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100400 @UnsupportedAppUsage
Adam Lesinski0debc9a2014-07-16 19:09:13 -0700401 private final IUsageStatsManager mService;
402
403 /**
404 * {@hide}
405 */
406 public UsageStatsManager(Context context, IUsageStatsManager service) {
407 mContext = context;
408 mService = service;
409 }
410
Adam Lesinski35168002014-07-21 15:25:30 -0700411 /**
412 * Gets application usage stats for the given time range, aggregated by the specified interval.
Adam Lesinski35168002014-07-21 15:25:30 -0700413 *
Michael Wachenschwanzd1e659b2019-04-05 11:55:02 -0700414 * <p>
415 * The returned list will contain one or more {@link UsageStats} objects for each package, with
416 * usage data that covers at least the given time range.
417 * Note: The begin and end times of the time range may be expanded to the nearest whole interval
418 * period.
419 * </p>
Adam Lesinski35168002014-07-21 15:25:30 -0700420 *
Suprabh Shukla217ccda2018-02-23 17:57:12 -0800421 * <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} </p>
Varun Shah3a315202019-07-24 16:33:42 -0700422 * <em>Note: Starting from {@link android.os.Build.VERSION_CODES#R Android R}, if the user's
423 * device is not in an unlocked state (as defined by {@link UserManager#isUserUnlocked()}),
424 * then {@code null} will be returned.</em>
Suprabh Shukla217ccda2018-02-23 17:57:12 -0800425 *
Adam Lesinski35168002014-07-21 15:25:30 -0700426 * @param intervalType The time interval by which the stats are aggregated.
427 * @param beginTime The inclusive beginning of the range of stats to include in the results.
Michael Wachenschwanz17415c22019-04-01 15:40:49 -0700428 * Defined in terms of "Unix time", see
429 * {@link java.lang.System#currentTimeMillis}.
430 * @param endTime The exclusive end of the range of stats to include in the results. Defined
431 * in terms of "Unix time", see {@link java.lang.System#currentTimeMillis}.
Esteban Talaverafa962312017-10-09 14:58:28 +0100432 * @return A list of {@link UsageStats}
Adam Lesinski35168002014-07-21 15:25:30 -0700433 *
434 * @see #INTERVAL_DAILY
435 * @see #INTERVAL_WEEKLY
436 * @see #INTERVAL_MONTHLY
437 * @see #INTERVAL_YEARLY
438 * @see #INTERVAL_BEST
439 */
Adam Lesinski35168002014-07-21 15:25:30 -0700440 public List<UsageStats> queryUsageStats(int intervalType, long beginTime, long endTime) {
Adam Lesinski0debc9a2014-07-16 19:09:13 -0700441 try {
Adam Lesinski7f61e962014-09-02 16:43:52 -0700442 @SuppressWarnings("unchecked")
Adam Lesinski35168002014-07-21 15:25:30 -0700443 ParceledListSlice<UsageStats> slice = mService.queryUsageStats(intervalType, beginTime,
444 endTime, mContext.getOpPackageName());
445 if (slice != null) {
446 return slice.getList();
Adam Lesinski0debc9a2014-07-16 19:09:13 -0700447 }
Adam Lesinski35168002014-07-21 15:25:30 -0700448 } catch (RemoteException e) {
Esteban Talaverafa962312017-10-09 14:58:28 +0100449 // fallthrough and return the empty list.
Adam Lesinski35168002014-07-21 15:25:30 -0700450 }
Adam Lesinski7f61e962014-09-02 16:43:52 -0700451 return Collections.emptyList();
452 }
453
454 /**
455 * Gets the hardware configurations the device was in for the given time range, aggregated by
456 * the specified interval. The results are ordered as in
457 * {@link #queryUsageStats(int, long, long)}.
Suprabh Shukla217ccda2018-02-23 17:57:12 -0800458 * <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} </p>
Varun Shah3a315202019-07-24 16:33:42 -0700459 * <em>Note: Starting from {@link android.os.Build.VERSION_CODES#R Android R}, if the user's
460 * device is not in an unlocked state (as defined by {@link UserManager#isUserUnlocked()}),
461 * then {@code null} will be returned.</em>
Adam Lesinski7f61e962014-09-02 16:43:52 -0700462 *
463 * @param intervalType The time interval by which the stats are aggregated.
464 * @param beginTime The inclusive beginning of the range of stats to include in the results.
Michael Wachenschwanz17415c22019-04-01 15:40:49 -0700465 * Defined in terms of "Unix time", see
466 * {@link java.lang.System#currentTimeMillis}.
467 * @param endTime The exclusive end of the range of stats to include in the results. Defined
468 * in terms of "Unix time", see {@link java.lang.System#currentTimeMillis}.
Esteban Talaverafa962312017-10-09 14:58:28 +0100469 * @return A list of {@link ConfigurationStats}
Adam Lesinski7f61e962014-09-02 16:43:52 -0700470 */
471 public List<ConfigurationStats> queryConfigurations(int intervalType, long beginTime,
472 long endTime) {
473 try {
474 @SuppressWarnings("unchecked")
475 ParceledListSlice<ConfigurationStats> slice = mService.queryConfigurationStats(
476 intervalType, beginTime, endTime, mContext.getOpPackageName());
477 if (slice != null) {
478 return slice.getList();
479 }
480 } catch (RemoteException e) {
481 // fallthrough and return the empty list.
482 }
483 return Collections.emptyList();
Adam Lesinski35168002014-07-21 15:25:30 -0700484 }
Adam Lesinski0debc9a2014-07-16 19:09:13 -0700485
Adam Lesinski35168002014-07-21 15:25:30 -0700486 /**
Dianne Hackbornced54392018-02-26 13:07:42 -0800487 * Gets aggregated event stats for the given time range, aggregated by the specified interval.
488 * <p>The returned list will contain a {@link EventStats} object for each event type that
489 * is being aggregated and has data for an interval that is a subset of the time range given.
490 *
491 * <p>The current event types that will be aggregated here are:</p>
492 * <ul>
493 * <li>{@link UsageEvents.Event#SCREEN_INTERACTIVE}</li>
494 * <li>{@link UsageEvents.Event#SCREEN_NON_INTERACTIVE}</li>
Dianne Hackborn3378aa92018-03-30 17:43:49 -0700495 * <li>{@link UsageEvents.Event#KEYGUARD_SHOWN}</li>
496 * <li>{@link UsageEvents.Event#KEYGUARD_HIDDEN}</li>
Dianne Hackbornced54392018-02-26 13:07:42 -0800497 * </ul>
498 *
499 * <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} </p>
Varun Shah3a315202019-07-24 16:33:42 -0700500 * <em>Note: Starting from {@link android.os.Build.VERSION_CODES#R Android R}, if the user's
501 * device is not in an unlocked state (as defined by {@link UserManager#isUserUnlocked()}),
502 * then {@code null} will be returned.</em>
Dianne Hackbornced54392018-02-26 13:07:42 -0800503 *
504 * @param intervalType The time interval by which the stats are aggregated.
505 * @param beginTime The inclusive beginning of the range of stats to include in the results.
Michael Wachenschwanz17415c22019-04-01 15:40:49 -0700506 * Defined in terms of "Unix time", see
507 * {@link java.lang.System#currentTimeMillis}.
508 * @param endTime The exclusive end of the range of stats to include in the results. Defined
509 * in terms of "Unix time", see {@link java.lang.System#currentTimeMillis}.
Dianne Hackbornced54392018-02-26 13:07:42 -0800510 * @return A list of {@link EventStats}
511 *
512 * @see #INTERVAL_DAILY
513 * @see #INTERVAL_WEEKLY
514 * @see #INTERVAL_MONTHLY
515 * @see #INTERVAL_YEARLY
516 * @see #INTERVAL_BEST
517 */
518 public List<EventStats> queryEventStats(int intervalType, long beginTime, long endTime) {
519 try {
520 @SuppressWarnings("unchecked")
521 ParceledListSlice<EventStats> slice = mService.queryEventStats(intervalType, beginTime,
522 endTime, mContext.getOpPackageName());
523 if (slice != null) {
524 return slice.getList();
525 }
526 } catch (RemoteException e) {
527 // fallthrough and return the empty list.
528 }
529 return Collections.emptyList();
530 }
531
532 /**
Adam Lesinski35168002014-07-21 15:25:30 -0700533 * Query for events in the given time range. Events are only kept by the system for a few
534 * days.
Suprabh Shukla217ccda2018-02-23 17:57:12 -0800535 * <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} </p>
Varun Shah3a315202019-07-24 16:33:42 -0700536 * <em>Note: Starting from {@link android.os.Build.VERSION_CODES#R Android R}, if the user's
537 * device is not in an unlocked state (as defined by {@link UserManager#isUserUnlocked()}),
538 * then {@code null} will be returned.</em>
Adam Lesinski35168002014-07-21 15:25:30 -0700539 *
540 * @param beginTime The inclusive beginning of the range of events to include in the results.
Michael Wachenschwanz17415c22019-04-01 15:40:49 -0700541 * Defined in terms of "Unix time", see
542 * {@link java.lang.System#currentTimeMillis}.
543 * @param endTime The exclusive end of the range of events to include in the results. Defined
544 * in terms of "Unix time", see {@link java.lang.System#currentTimeMillis}.
Adam Lesinski35168002014-07-21 15:25:30 -0700545 * @return A {@link UsageEvents}.
546 */
Adam Lesinski35168002014-07-21 15:25:30 -0700547 public UsageEvents queryEvents(long beginTime, long endTime) {
548 try {
549 UsageEvents iter = mService.queryEvents(beginTime, endTime,
550 mContext.getOpPackageName());
551 if (iter != null) {
552 return iter;
553 }
554 } catch (RemoteException e) {
Esteban Talaverafa962312017-10-09 14:58:28 +0100555 // fallthrough and return empty result.
Adam Lesinski35168002014-07-21 15:25:30 -0700556 }
557 return sEmptyResults;
558 }
Adam Lesinski0debc9a2014-07-16 19:09:13 -0700559
Adam Lesinski35168002014-07-21 15:25:30 -0700560 /**
Suprabh Shukla217ccda2018-02-23 17:57:12 -0800561 * Like {@link #queryEvents(long, long)}, but only returns events for the calling package.
Varun Shah3a315202019-07-24 16:33:42 -0700562 * <em>Note: Starting from {@link android.os.Build.VERSION_CODES#R Android R}, if the user's
563 * device is not in an unlocked state (as defined by {@link UserManager#isUserUnlocked()}),
564 * then {@code null} will be returned.</em>
Suprabh Shukla217ccda2018-02-23 17:57:12 -0800565 *
566 * @param beginTime The inclusive beginning of the range of events to include in the results.
Michael Wachenschwanz17415c22019-04-01 15:40:49 -0700567 * Defined in terms of "Unix time", see
568 * {@link java.lang.System#currentTimeMillis}.
569 * @param endTime The exclusive end of the range of events to include in the results. Defined
570 * in terms of "Unix time", see {@link java.lang.System#currentTimeMillis}.
Suprabh Shukla217ccda2018-02-23 17:57:12 -0800571 * @return A {@link UsageEvents} object.
572 *
573 * @see #queryEvents(long, long)
574 */
575 public UsageEvents queryEventsForSelf(long beginTime, long endTime) {
576 try {
577 final UsageEvents events = mService.queryEventsForPackage(beginTime, endTime,
578 mContext.getOpPackageName());
579 if (events != null) {
580 return events;
581 }
582 } catch (RemoteException e) {
583 // fallthrough
584 }
585 return sEmptyResults;
586 }
587
588 /**
Adam Lesinski35168002014-07-21 15:25:30 -0700589 * A convenience method that queries for all stats in the given range (using the best interval
590 * for that range), merges the resulting data, and keys it by package name.
591 * See {@link #queryUsageStats(int, long, long)}.
Suprabh Shukla217ccda2018-02-23 17:57:12 -0800592 * <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} </p>
Adam Lesinski35168002014-07-21 15:25:30 -0700593 *
594 * @param beginTime The inclusive beginning of the range of stats to include in the results.
Michael Wachenschwanz17415c22019-04-01 15:40:49 -0700595 * Defined in terms of "Unix time", see
596 * {@link java.lang.System#currentTimeMillis}.
597 * @param endTime The exclusive end of the range of stats to include in the results. Defined
598 * in terms of "Unix time", see {@link java.lang.System#currentTimeMillis}.
Esteban Talaverafa962312017-10-09 14:58:28 +0100599 * @return A {@link java.util.Map} keyed by package name
Adam Lesinski35168002014-07-21 15:25:30 -0700600 */
Adam Lesinskicc562a82014-08-27 11:52:52 -0700601 public Map<String, UsageStats> queryAndAggregateUsageStats(long beginTime, long endTime) {
Adam Lesinski35168002014-07-21 15:25:30 -0700602 List<UsageStats> stats = queryUsageStats(INTERVAL_BEST, beginTime, endTime);
603 if (stats.isEmpty()) {
Adam Lesinskicc562a82014-08-27 11:52:52 -0700604 return Collections.emptyMap();
Adam Lesinski35168002014-07-21 15:25:30 -0700605 }
Adam Lesinski0debc9a2014-07-16 19:09:13 -0700606
Adam Lesinski35168002014-07-21 15:25:30 -0700607 ArrayMap<String, UsageStats> aggregatedStats = new ArrayMap<>();
608 final int statCount = stats.size();
609 for (int i = 0; i < statCount; i++) {
610 UsageStats newStat = stats.get(i);
611 UsageStats existingStat = aggregatedStats.get(newStat.getPackageName());
612 if (existingStat == null) {
613 aggregatedStats.put(newStat.mPackageName, newStat);
614 } else {
615 existingStat.add(newStat);
Adam Lesinski0debc9a2014-07-16 19:09:13 -0700616 }
617 }
618 return aggregatedStats;
619 }
Amith Yamasanicf768722015-04-23 20:36:41 -0700620
621 /**
Amith Yamasanie5f33042015-05-08 13:20:22 -0700622 * Returns whether the specified app is currently considered inactive. This will be true if the
Amith Yamasanicf768722015-04-23 20:36:41 -0700623 * app hasn't been used directly or indirectly for a period of time defined by the system. This
Kweku Adamsf35ed3702020-02-11 17:32:54 -0800624 * could be of the order of several hours or days. Apps are not considered inactive when the
625 * device is charging.
Michael Wachenschwanzd2b132f2020-04-01 16:28:46 -0700626 * <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} to query the
627 * inactive state of other apps</p>
628 *
Amith Yamasanicf768722015-04-23 20:36:41 -0700629 * @param packageName The package name of the app to query
Michael Wachenschwanzd2b132f2020-04-01 16:28:46 -0700630 * @return whether the app is currently considered inactive or false if querying another app
631 * without {@link android.Manifest.permission#PACKAGE_USAGE_STATS}
Amith Yamasanicf768722015-04-23 20:36:41 -0700632 */
Amith Yamasanie5f33042015-05-08 13:20:22 -0700633 public boolean isAppInactive(String packageName) {
Amith Yamasanicf768722015-04-23 20:36:41 -0700634 try {
Michael Wachenschwanzd2b132f2020-04-01 16:28:46 -0700635 return mService.isAppInactive(packageName, mContext.getUserId(),
636 mContext.getOpPackageName());
Amith Yamasanicf768722015-04-23 20:36:41 -0700637 } catch (RemoteException e) {
638 // fall through and return default
639 }
640 return false;
641 }
Amith Yamasani901e9242015-05-13 18:21:09 -0700642
643 /**
Amith Yamasaniafbccb72017-11-27 10:44:24 -0800644 * {@hide}
Amith Yamasani901e9242015-05-13 18:21:09 -0700645 */
646 public void setAppInactive(String packageName, boolean inactive) {
647 try {
Jeff Sharkeyad357d12018-02-02 13:25:31 -0700648 mService.setAppInactive(packageName, inactive, mContext.getUserId());
Amith Yamasani901e9242015-05-13 18:21:09 -0700649 } catch (RemoteException e) {
650 // fall through
651 }
652 }
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700653
654 /**
Amith Yamasaniafbccb72017-11-27 10:44:24 -0800655 * Returns the current standby bucket of the calling app. The system determines the standby
656 * state of the app based on app usage patterns. Standby buckets determine how much an app will
Amith Yamasani853e53f2018-03-16 16:08:57 -0700657 * be restricted from running background tasks such as jobs and alarms.
Amith Yamasanie8789312017-12-10 14:34:26 -0800658 * <p>Restrictions increase progressively from {@link #STANDBY_BUCKET_ACTIVE} to
Kweku Adamsc6a9b342020-01-08 18:37:26 -0800659 * {@link #STANDBY_BUCKET_RESTRICTED}, with {@link #STANDBY_BUCKET_ACTIVE} being the least
Amith Yamasaniafbccb72017-11-27 10:44:24 -0800660 * restrictive. The battery level of the device might also affect the restrictions.
Amith Yamasani853e53f2018-03-16 16:08:57 -0700661 * <p>Apps in buckets &le; {@link #STANDBY_BUCKET_ACTIVE} have no standby restrictions imposed.
662 * Apps in buckets &gt; {@link #STANDBY_BUCKET_FREQUENT} may have network access restricted when
663 * running in the background.
664 * <p>The standby state of an app can change at any time either due to a user interaction or a
665 * system interaction or some algorithm determining that the app can be restricted for a period
666 * of time before the user has a need for it.
667 * <p>You can also query the recent history of standby bucket changes by calling
668 * {@link #queryEventsForSelf(long, long)} and searching for
669 * {@link UsageEvents.Event#STANDBY_BUCKET_CHANGED}.
Amith Yamasaniafbccb72017-11-27 10:44:24 -0800670 *
Amith Yamasanie8789312017-12-10 14:34:26 -0800671 * @return the current standby bucket of the calling app. One of STANDBY_BUCKET_* constants.
Amith Yamasani17fffee2017-09-29 13:17:43 -0700672 */
Amith Yamasaniafbccb72017-11-27 10:44:24 -0800673 public @StandbyBuckets int getAppStandbyBucket() {
674 try {
675 return mService.getAppStandbyBucket(mContext.getOpPackageName(),
676 mContext.getOpPackageName(),
677 mContext.getUserId());
678 } catch (RemoteException e) {
679 }
680 return STANDBY_BUCKET_ACTIVE;
681 }
682
683 /**
684 * {@hide}
685 * Returns the current standby bucket of the specified app. The caller must hold the permission
686 * android.permission.PACKAGE_USAGE_STATS.
687 * @param packageName the package for which to fetch the current standby bucket.
688 */
689 @SystemApi
690 @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS)
Amith Yamasani17fffee2017-09-29 13:17:43 -0700691 public @StandbyBuckets int getAppStandbyBucket(String packageName) {
692 try {
693 return mService.getAppStandbyBucket(packageName, mContext.getOpPackageName(),
694 mContext.getUserId());
695 } catch (RemoteException e) {
696 }
Amith Yamasaniafbccb72017-11-27 10:44:24 -0800697 return STANDBY_BUCKET_ACTIVE;
Amith Yamasani17fffee2017-09-29 13:17:43 -0700698 }
699
700 /**
Amith Yamasaniafbccb72017-11-27 10:44:24 -0800701 * {@hide}
Amith Yamasanie8789312017-12-10 14:34:26 -0800702 * Changes an app's standby bucket to the provided value. The caller can only set the standby
Kweku Adamsc6a9b342020-01-08 18:37:26 -0800703 * bucket for a different app than itself. The caller will not be able to change an app's
704 * standby bucket if that app is in the {@link #STANDBY_BUCKET_RESTRICTED} bucket.
Amith Yamasanie8789312017-12-10 14:34:26 -0800705 * @param packageName the package name of the app to set the bucket for. A SecurityException
706 * will be thrown if the package name is that of the caller.
707 * @param bucket the standby bucket to set it to, which should be one of STANDBY_BUCKET_*.
708 * Setting a standby bucket outside of the range of STANDBY_BUCKET_ACTIVE to
709 * STANDBY_BUCKET_NEVER will result in a SecurityException.
Amith Yamasani17fffee2017-09-29 13:17:43 -0700710 */
Amith Yamasani4470ab92017-10-31 13:29:00 -0700711 @SystemApi
712 @RequiresPermission(android.Manifest.permission.CHANGE_APP_IDLE_STATE)
Amith Yamasani17fffee2017-09-29 13:17:43 -0700713 public void setAppStandbyBucket(String packageName, @StandbyBuckets int bucket) {
714 try {
715 mService.setAppStandbyBucket(packageName, bucket, mContext.getUserId());
716 } catch (RemoteException e) {
Amith Yamasanifd44f272018-05-14 14:47:19 -0700717 throw e.rethrowFromSystemServer();
Amith Yamasani17fffee2017-09-29 13:17:43 -0700718 }
719 }
720
721 /**
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700722 * {@hide}
Amith Yamasanie8789312017-12-10 14:34:26 -0800723 * Returns the current standby bucket of every app that has a bucket assigned to it.
724 * The caller must hold the permission android.permission.PACKAGE_USAGE_STATS. The key of the
725 * returned Map is the package name and the value is the bucket assigned to the package.
726 * @see #getAppStandbyBucket()
727 */
728 @SystemApi
729 @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS)
730 public Map<String, Integer> getAppStandbyBuckets() {
731 try {
Suprabh Shukla868bde22018-02-20 20:59:52 -0800732 final ParceledListSlice<AppStandbyInfo> slice = mService.getAppStandbyBuckets(
Amith Yamasanie8789312017-12-10 14:34:26 -0800733 mContext.getOpPackageName(), mContext.getUserId());
Suprabh Shukla868bde22018-02-20 20:59:52 -0800734 final List<AppStandbyInfo> bucketList = slice.getList();
735 final ArrayMap<String, Integer> bucketMap = new ArrayMap<>();
736 final int n = bucketList.size();
737 for (int i = 0; i < n; i++) {
738 final AppStandbyInfo bucketInfo = bucketList.get(i);
739 bucketMap.put(bucketInfo.mPackageName, bucketInfo.mStandbyBucket);
740 }
741 return bucketMap;
Amith Yamasanie8789312017-12-10 14:34:26 -0800742 } catch (RemoteException e) {
Amith Yamasanifd44f272018-05-14 14:47:19 -0700743 throw e.rethrowFromSystemServer();
Amith Yamasanie8789312017-12-10 14:34:26 -0800744 }
Amith Yamasanie8789312017-12-10 14:34:26 -0800745 }
746
747 /**
748 * {@hide}
749 * Changes the app standby bucket for multiple apps at once. The Map is keyed by the package
Kweku Adamsc6a9b342020-01-08 18:37:26 -0800750 * name and the value is one of STANDBY_BUCKET_*. The caller will not be able to change an
751 * app's standby bucket if that app is in the {@link #STANDBY_BUCKET_RESTRICTED} bucket.
Amith Yamasanie8789312017-12-10 14:34:26 -0800752 * @param appBuckets a map of package name to bucket value.
753 */
754 @SystemApi
755 @RequiresPermission(android.Manifest.permission.CHANGE_APP_IDLE_STATE)
756 public void setAppStandbyBuckets(Map<String, Integer> appBuckets) {
Suprabh Shukla868bde22018-02-20 20:59:52 -0800757 if (appBuckets == null) {
758 return;
759 }
760 final List<AppStandbyInfo> bucketInfoList = new ArrayList<>(appBuckets.size());
761 for (Map.Entry<String, Integer> bucketEntry : appBuckets.entrySet()) {
762 bucketInfoList.add(new AppStandbyInfo(bucketEntry.getKey(), bucketEntry.getValue()));
763 }
764 final ParceledListSlice<AppStandbyInfo> slice = new ParceledListSlice<>(bucketInfoList);
Amith Yamasanie8789312017-12-10 14:34:26 -0800765 try {
Suprabh Shukla868bde22018-02-20 20:59:52 -0800766 mService.setAppStandbyBuckets(slice, mContext.getUserId());
Amith Yamasanie8789312017-12-10 14:34:26 -0800767 } catch (RemoteException e) {
Amith Yamasanifd44f272018-05-14 14:47:19 -0700768 throw e.rethrowFromSystemServer();
Amith Yamasanie8789312017-12-10 14:34:26 -0800769 }
770 }
771
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700772 /**
773 * @hide
774 * Register an app usage limit observer that receives a callback on the provided intent when
Michael Wachenschwanz36778522018-11-12 11:06:19 -0800775 * the sum of usages of apps and tokens in the {@code observed} array exceeds the
776 * {@code timeLimit} specified. The structure of a token is a String with the reporting
777 * package's name and a token the reporting app will use, separated by the forward slash
778 * character. Example: com.reporting.package/5OM3*0P4QU3-7OK3N
779 * The observer will automatically be unregistered when the time limit is reached and the
780 * intent is delivered. Registering an {@code observerId} that was already registered will
781 * override the previous one. No more than 1000 unique {@code observerId} may be registered by
782 * a single uid at any one time.
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700783 * @param observerId A unique id associated with the group of apps to be monitored. There can
784 * be multiple groups with common packages and different time limits.
Michael Wachenschwanz36778522018-11-12 11:06:19 -0800785 * @param observedEntities The list of packages and token to observe for usage time. Cannot be
786 * null and must include at least one package or token.
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700787 * @param timeLimit The total time the set of apps can be in the foreground before the
Michael Wachenschwanzc8703092018-05-01 16:02:45 -0700788 * callbackIntent is delivered. Must be at least one minute.
Amith Yamasanibc813eb2018-03-20 19:37:46 -0700789 * @param timeUnit The unit for time specified in {@code timeLimit}. Cannot be null.
Varun Shah2546cef2019-01-11 15:50:54 -0800790 * @param callbackIntent The PendingIntent that will be dispatched when the usage limit is
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700791 * exceeded by the group of apps. The delivered Intent will also contain
792 * the extras {@link #EXTRA_OBSERVER_ID}, {@link #EXTRA_TIME_LIMIT} and
Amith Yamasanibc813eb2018-03-20 19:37:46 -0700793 * {@link #EXTRA_TIME_USED}. Cannot be null.
Michael Wachenschwanz641e3382018-10-23 23:21:48 -0700794 * @throws SecurityException if the caller doesn't have the OBSERVE_APP_USAGE permission and
Amith Yamasanibc813eb2018-03-20 19:37:46 -0700795 * is not the profile owner of this user.
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700796 */
797 @SystemApi
Amith Yamasanibc813eb2018-03-20 19:37:46 -0700798 @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE)
Michael Wachenschwanz36778522018-11-12 11:06:19 -0800799 public void registerAppUsageObserver(int observerId, @NonNull String[] observedEntities,
800 long timeLimit, @NonNull TimeUnit timeUnit, @NonNull PendingIntent callbackIntent) {
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700801 try {
Michael Wachenschwanz36778522018-11-12 11:06:19 -0800802 mService.registerAppUsageObserver(observerId, observedEntities,
803 timeUnit.toMillis(timeLimit), callbackIntent, mContext.getOpPackageName());
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700804 } catch (RemoteException e) {
Amith Yamasanifd44f272018-05-14 14:47:19 -0700805 throw e.rethrowFromSystemServer();
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700806 }
807 }
808
809 /**
810 * @hide
Amith Yamasanibc813eb2018-03-20 19:37:46 -0700811 * Unregister the app usage observer specified by the {@code observerId}. This will only apply
812 * to any observer registered by this application. Unregistering an observer that was already
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700813 * unregistered or never registered will have no effect.
814 * @param observerId The id of the observer that was previously registered.
Michael Wachenschwanz641e3382018-10-23 23:21:48 -0700815 * @throws SecurityException if the caller doesn't have the OBSERVE_APP_USAGE permission and is
Amith Yamasanibc813eb2018-03-20 19:37:46 -0700816 * not the profile owner of this user.
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700817 */
818 @SystemApi
Amith Yamasanibc813eb2018-03-20 19:37:46 -0700819 @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE)
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700820 public void unregisterAppUsageObserver(int observerId) {
821 try {
822 mService.unregisterAppUsageObserver(observerId, mContext.getOpPackageName());
823 } catch (RemoteException e) {
Amith Yamasanifd44f272018-05-14 14:47:19 -0700824 throw e.rethrowFromSystemServer();
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700825 }
826 }
827
Michael Wachenschwanz641e3382018-10-23 23:21:48 -0700828 /**
829 * Register a usage session observer that receives a callback on the provided {@code
Michael Wachenschwanz36778522018-11-12 11:06:19 -0800830 * limitReachedCallbackIntent} when the sum of usages of apps and tokens in the {@code
831 * observed} array exceeds the {@code timeLimit} specified within a usage session. The
832 * structure of a token is a String with the reporting packages' name and a token the
833 * reporting app will use, separated by the forward slash character.
834 * Example: com.reporting.package/5OM3*0P4QU3-7OK3N
835 * After the {@code timeLimit} has been reached, the usage session observer will receive a
836 * callback on the provided {@code sessionEndCallbackIntent} when the usage session ends.
837 * Registering another session observer against a {@code sessionObserverId} that has already
838 * been registered will override the previous session observer.
Michael Wachenschwanz641e3382018-10-23 23:21:48 -0700839 *
840 * @param sessionObserverId A unique id associated with the group of apps to be
841 * monitored. There can be multiple groups with common
842 * packages and different time limits.
Michael Wachenschwanz36778522018-11-12 11:06:19 -0800843 * @param observedEntities The list of packages and token to observe for usage time. Cannot be
844 * null and must include at least one package or token.
Michael Wachenschwanz641e3382018-10-23 23:21:48 -0700845 * @param timeLimit The total time the set of apps can be used continuously before the {@code
846 * limitReachedCallbackIntent} is delivered. Must be at least one minute.
Michael Wachenschwanz641e3382018-10-23 23:21:48 -0700847 * @param sessionThresholdTime The time that can take place between usage sessions before the
848 * next session is considered a new session. Must be non-negative.
Michael Wachenschwanz641e3382018-10-23 23:21:48 -0700849 * @param limitReachedCallbackIntent The {@link PendingIntent} that will be dispatched when the
Varun Shah2546cef2019-01-11 15:50:54 -0800850 * usage limit is exceeded by the group of apps. The
851 * delivered Intent will also contain the extras {@link
Michael Wachenschwanz641e3382018-10-23 23:21:48 -0700852 * #EXTRA_OBSERVER_ID}, {@link #EXTRA_TIME_LIMIT} and {@link
853 * #EXTRA_TIME_USED}. Cannot be null.
854 * @param sessionEndCallbackIntent The {@link PendingIntent} that will be dispatched when the
Varun Shah2546cef2019-01-11 15:50:54 -0800855 * session has ended after the usage limit has been exceeded.
856 * The session is considered at its end after the {@code
857 * observed} usage has stopped and an additional {@code
Michael Wachenschwanz641e3382018-10-23 23:21:48 -0700858 * sessionThresholdTime} has passed. The delivered Intent will
859 * also contain the extras {@link #EXTRA_OBSERVER_ID} and {@link
860 * #EXTRA_TIME_USED}. Can be null.
861 * @throws SecurityException if the caller doesn't have the OBSERVE_APP_USAGE permission and
862 * is not the profile owner of this user.
863 * @hide
864 */
865 @SystemApi
866 @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE)
Michael Wachenschwanz36778522018-11-12 11:06:19 -0800867 public void registerUsageSessionObserver(int sessionObserverId,
Michael Wachenschwanzd3cb9982019-03-12 16:05:10 -0700868 @NonNull String[] observedEntities, @NonNull Duration timeLimit,
869 @NonNull Duration sessionThresholdTime,
Michael Wachenschwanz641e3382018-10-23 23:21:48 -0700870 @NonNull PendingIntent limitReachedCallbackIntent,
871 @Nullable PendingIntent sessionEndCallbackIntent) {
872 try {
Michael Wachenschwanz36778522018-11-12 11:06:19 -0800873 mService.registerUsageSessionObserver(sessionObserverId, observedEntities,
Michael Wachenschwanzd3cb9982019-03-12 16:05:10 -0700874 timeLimit.toMillis(), sessionThresholdTime.toMillis(),
Michael Wachenschwanz641e3382018-10-23 23:21:48 -0700875 limitReachedCallbackIntent, sessionEndCallbackIntent,
876 mContext.getOpPackageName());
877 } catch (RemoteException e) {
878 throw e.rethrowFromSystemServer();
879 }
880 }
881
882 /**
883 * Unregister the usage session observer specified by the {@code sessionObserverId}. This will
884 * only apply to any app session observer registered by this application. Unregistering an
885 * observer that was already unregistered or never registered will have no effect.
886 *
887 * @param sessionObserverId The id of the observer that was previously registered.
888 * @throws SecurityException if the caller doesn't have the OBSERVE_APP_USAGE permission and
889 * is not the profile owner of this user.
890 * @hide
891 */
892 @SystemApi
893 @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE)
894 public void unregisterUsageSessionObserver(int sessionObserverId) {
895 try {
896 mService.unregisterUsageSessionObserver(sessionObserverId, mContext.getOpPackageName());
897 } catch (RemoteException e) {
898 throw e.rethrowFromSystemServer();
899 }
900 }
901
Michael Wachenschwanz36778522018-11-12 11:06:19 -0800902 /**
Varun Shah2546cef2019-01-11 15:50:54 -0800903 * Register a usage limit observer that receives a callback on the provided intent when the
904 * sum of usages of apps and tokens in the provided {@code observedEntities} array exceeds the
905 * {@code timeLimit} specified. The structure of a token is a {@link String} with the reporting
906 * package's name and a token that the calling app will use, separated by the forward slash
907 * character. Example: com.reporting.package/5OM3*0P4QU3-7OK3N
908 * <p>
909 * Registering an {@code observerId} that was already registered will override the previous one.
910 * No more than 1000 unique {@code observerId} may be registered by a single uid
911 * at any one time.
Varun Shah54f7f7f2019-02-07 10:21:17 -0800912 * A limit is not cleared when the usage time is exceeded. It needs to be unregistered via
913 * {@link #unregisterAppUsageLimitObserver}.
914 * <p>
915 * Note: usage limits are not persisted in the system and are cleared on reboots. Callers
916 * must reset any limits that they need on reboots.
Varun Shah2546cef2019-01-11 15:50:54 -0800917 * <p>
918 * This method is similar to {@link #registerAppUsageObserver}, but the usage limit set here
919 * will be visible to the launcher so that it can report the limit to the user and how much
920 * of it is remaining.
921 * @see android.content.pm.LauncherApps#getAppUsageLimit
922 *
923 * @param observerId A unique id associated with the group of apps to be monitored. There can
Varun Shah9f58b7c2019-03-01 10:36:21 -0800924 * be multiple groups with common packages and different time limits.
Varun Shah2546cef2019-01-11 15:50:54 -0800925 * @param observedEntities The list of packages and token to observe for usage time. Cannot be
926 * null and must include at least one package or token.
927 * @param timeLimit The total time the set of apps can be in the foreground before the
Varun Shah9f58b7c2019-03-01 10:36:21 -0800928 * {@code callbackIntent} is delivered. Must be at least one minute.
Varun Shah4f76a1e2019-03-12 11:46:10 -0700929 * @param timeUsed The time that has already been used by the set of apps in
930 * {@code observedEntities}. Note: a time used equal to or greater than
931 * {@code timeLimit} can be set to indicate that the user has already exhausted
932 * the limit for a group, in which case, the given {@code callbackIntent} will
933 * be ignored.
Varun Shah54f7f7f2019-02-07 10:21:17 -0800934 * @param callbackIntent The PendingIntent that will be dispatched when the usage limit is
Varun Shah2546cef2019-01-11 15:50:54 -0800935 * exceeded by the group of apps. The delivered Intent will also contain
936 * the extras {@link #EXTRA_OBSERVER_ID}, {@link #EXTRA_TIME_LIMIT} and
Varun Shah54f7f7f2019-02-07 10:21:17 -0800937 * {@link #EXTRA_TIME_USED}. Cannot be {@code null} unless the observer is
Varun Shah4f76a1e2019-03-12 11:46:10 -0700938 * being registered with a {@code timeUsed} equal to or greater than
939 * {@code timeLimit}.
Varun Shahb472b8f2019-09-23 23:01:06 -0700940 * @throws SecurityException if the caller is neither the active supervision app nor does it
941 * have both SUSPEND_APPS and OBSERVE_APP_USAGE permissions.
Varun Shah2546cef2019-01-11 15:50:54 -0800942 * @hide
943 */
944 @SystemApi
945 @RequiresPermission(allOf = {
946 android.Manifest.permission.SUSPEND_APPS,
947 android.Manifest.permission.OBSERVE_APP_USAGE})
948 public void registerAppUsageLimitObserver(int observerId, @NonNull String[] observedEntities,
Varun Shah4f76a1e2019-03-12 11:46:10 -0700949 @NonNull Duration timeLimit, @NonNull Duration timeUsed,
Varun Shah9f58b7c2019-03-01 10:36:21 -0800950 @Nullable PendingIntent callbackIntent) {
Varun Shah2546cef2019-01-11 15:50:54 -0800951 try {
952 mService.registerAppUsageLimitObserver(observerId, observedEntities,
Varun Shah4f76a1e2019-03-12 11:46:10 -0700953 timeLimit.toMillis(), timeUsed.toMillis(), callbackIntent,
Varun Shah9f58b7c2019-03-01 10:36:21 -0800954 mContext.getOpPackageName());
Varun Shah2546cef2019-01-11 15:50:54 -0800955 } catch (RemoteException e) {
956 throw e.rethrowFromSystemServer();
957 }
958 }
959
960 /**
961 * Unregister the app usage limit observer specified by the {@code observerId}.
962 * This will only apply to any observer registered by this application. Unregistering
963 * an observer that was already unregistered or never registered will have no effect.
964 *
965 * @param observerId The id of the observer that was previously registered.
Varun Shahb472b8f2019-09-23 23:01:06 -0700966 * @throws SecurityException if the caller is neither the active supervision app nor does it
967 * have both SUSPEND_APPS and OBSERVE_APP_USAGE permissions.
Varun Shah2546cef2019-01-11 15:50:54 -0800968 * @hide
969 */
970 @SystemApi
971 @RequiresPermission(allOf = {
972 android.Manifest.permission.SUSPEND_APPS,
973 android.Manifest.permission.OBSERVE_APP_USAGE})
974 public void unregisterAppUsageLimitObserver(int observerId) {
975 try {
976 mService.unregisterAppUsageLimitObserver(observerId, mContext.getOpPackageName());
977 } catch (RemoteException e) {
978 throw e.rethrowFromSystemServer();
979 }
980 }
981
982 /**
Michael Wachenschwanz36778522018-11-12 11:06:19 -0800983 * Report usage associated with a particular {@code token} has started. Tokens are app defined
984 * strings used to represent usage of in-app features. Apps with the {@link
985 * android.Manifest.permission#OBSERVE_APP_USAGE} permission can register time limit observers
986 * to monitor the usage of a token. In app usage can only associated with an {@code activity}
987 * and usage will be considered stopped if the activity stops or crashes.
988 * @see #registerAppUsageObserver
989 * @see #registerUsageSessionObserver
Varun Shah2546cef2019-01-11 15:50:54 -0800990 * @see #registerAppUsageLimitObserver
Michael Wachenschwanz36778522018-11-12 11:06:19 -0800991 *
992 * @param activity The activity {@code token} is associated with.
993 * @param token The token to report usage against.
994 * @hide
995 */
996 @SystemApi
997 public void reportUsageStart(@NonNull Activity activity, @NonNull String token) {
998 try {
999 mService.reportUsageStart(activity.getActivityToken(), token,
1000 mContext.getOpPackageName());
1001 } catch (RemoteException e) {
1002 throw e.rethrowFromSystemServer();
1003 }
1004 }
1005
1006 /**
1007 * Report usage associated with a particular {@code token} had started some amount of time in
1008 * the past. Tokens are app defined strings used to represent usage of in-app features. Apps
1009 * with the {@link android.Manifest.permission#OBSERVE_APP_USAGE} permission can register time
1010 * limit observers to monitor the usage of a token. In app usage can only associated with an
1011 * {@code activity} and usage will be considered stopped if the activity stops or crashes.
1012 * @see #registerAppUsageObserver
1013 * @see #registerUsageSessionObserver
Varun Shah2546cef2019-01-11 15:50:54 -08001014 * @see #registerAppUsageLimitObserver
Michael Wachenschwanz36778522018-11-12 11:06:19 -08001015 *
1016 * @param activity The activity {@code token} is associated with.
1017 * @param token The token to report usage against.
1018 * @param timeAgoMs How long ago the start of usage took place
1019 * @hide
1020 */
1021 @SystemApi
1022 public void reportUsageStart(@NonNull Activity activity, @NonNull String token,
1023 long timeAgoMs) {
1024 try {
1025 mService.reportPastUsageStart(activity.getActivityToken(), token, timeAgoMs,
1026 mContext.getOpPackageName());
1027 } catch (RemoteException e) {
1028 throw e.rethrowFromSystemServer();
1029 }
1030 }
1031
1032 /**
1033 * Report the usage associated with a particular {@code token} has stopped.
1034 *
1035 * @param activity The activity {@code token} is associated with.
1036 * @param token The token to report usage against.
1037 * @hide
1038 */
1039 @SystemApi
1040 public void reportUsageStop(@NonNull Activity activity, @NonNull String token) {
1041 try {
1042 mService.reportUsageStop(activity.getActivityToken(), token,
1043 mContext.getOpPackageName());
1044 } catch (RemoteException e) {
1045 throw e.rethrowFromSystemServer();
1046 }
1047 }
1048
Michael Wachenschwanz0b4ab1f2019-01-07 13:59:10 -08001049 /**
1050 * Get what App Usage Observers will consider the source of usage for an activity. Usage Source
1051 * is decided at boot and will not change until next boot.
1052 * @see #USAGE_SOURCE_TASK_ROOT_ACTIVITY
1053 * @see #USAGE_SOURCE_CURRENT_ACTIVITY
1054 *
1055 * @throws SecurityException if the caller doesn't have the OBSERVE_APP_USAGE permission and
1056 * is not the profile owner of this user.
1057 * @hide
1058 */
1059 @SystemApi
1060 public @UsageSource int getUsageSource() {
1061 try {
1062 return mService.getUsageSource();
1063 } catch (RemoteException e) {
1064 throw e.rethrowFromSystemServer();
1065 }
1066 }
1067
1068 /**
1069 * Force the Usage Source be reread from global settings.
1070 * @hide
1071 */
1072 @TestApi
1073 public void forceUsageSourceSettingRead() {
1074 try {
1075 mService.forceUsageSourceSettingRead();
1076 } catch (RemoteException e) {
1077 throw e.rethrowFromSystemServer();
1078 }
1079 }
1080
Amith Yamasani119be9a2018-02-18 22:23:00 -08001081 /** @hide */
1082 public static String reasonToString(int standbyReason) {
Kweku Adamsaa461942020-03-16 11:59:05 -07001083 final int subReason = standbyReason & REASON_SUB_MASK;
Amith Yamasani119be9a2018-02-18 22:23:00 -08001084 StringBuilder sb = new StringBuilder();
1085 switch (standbyReason & REASON_MAIN_MASK) {
1086 case REASON_MAIN_DEFAULT:
1087 sb.append("d");
Kweku Adams917f8a42020-02-26 17:18:03 -08001088 switch (subReason) {
1089 case REASON_SUB_DEFAULT_UNDEFINED:
1090 // Historically, undefined didn't have a string, so don't add anything here.
1091 break;
1092 case REASON_SUB_DEFAULT_APP_UPDATE:
1093 sb.append("-au");
1094 break;
1095 }
Amith Yamasani119be9a2018-02-18 22:23:00 -08001096 break;
Kweku Adamsc182d5e2020-01-08 18:37:26 -08001097 case REASON_MAIN_FORCED_BY_SYSTEM:
1098 sb.append("s");
Kweku Adamsaa461942020-03-16 11:59:05 -07001099 if (subReason > 0) {
1100 sb.append("-").append(Integer.toBinaryString(subReason));
Kweku Adamsc6a9b342020-01-08 18:37:26 -08001101 }
Kweku Adamsc182d5e2020-01-08 18:37:26 -08001102 break;
1103 case REASON_MAIN_FORCED_BY_USER:
Amith Yamasani119be9a2018-02-18 22:23:00 -08001104 sb.append("f");
1105 break;
1106 case REASON_MAIN_PREDICTED:
1107 sb.append("p");
Kweku Adamsaa461942020-03-16 11:59:05 -07001108 switch (subReason) {
Amith Yamasani3154dcf2018-03-27 18:24:04 -07001109 case REASON_SUB_PREDICTED_RESTORED:
1110 sb.append("-r");
1111 break;
1112 }
Amith Yamasani119be9a2018-02-18 22:23:00 -08001113 break;
1114 case REASON_MAIN_TIMEOUT:
1115 sb.append("t");
1116 break;
1117 case REASON_MAIN_USAGE:
Amith Yamasani3154dcf2018-03-27 18:24:04 -07001118 sb.append("u");
Kweku Adamsaa461942020-03-16 11:59:05 -07001119 switch (subReason) {
Amith Yamasani119be9a2018-02-18 22:23:00 -08001120 case REASON_SUB_USAGE_SYSTEM_INTERACTION:
Amith Yamasani3154dcf2018-03-27 18:24:04 -07001121 sb.append("-si");
Amith Yamasani119be9a2018-02-18 22:23:00 -08001122 break;
1123 case REASON_SUB_USAGE_NOTIFICATION_SEEN:
Amith Yamasani3154dcf2018-03-27 18:24:04 -07001124 sb.append("-ns");
Amith Yamasani119be9a2018-02-18 22:23:00 -08001125 break;
1126 case REASON_SUB_USAGE_USER_INTERACTION:
Amith Yamasani3154dcf2018-03-27 18:24:04 -07001127 sb.append("-ui");
Amith Yamasani119be9a2018-02-18 22:23:00 -08001128 break;
1129 case REASON_SUB_USAGE_MOVE_TO_FOREGROUND:
Amith Yamasani3154dcf2018-03-27 18:24:04 -07001130 sb.append("-mf");
Amith Yamasani119be9a2018-02-18 22:23:00 -08001131 break;
1132 case REASON_SUB_USAGE_MOVE_TO_BACKGROUND:
Amith Yamasani3154dcf2018-03-27 18:24:04 -07001133 sb.append("-mb");
Amith Yamasani119be9a2018-02-18 22:23:00 -08001134 break;
1135 case REASON_SUB_USAGE_SYSTEM_UPDATE:
Amith Yamasani3154dcf2018-03-27 18:24:04 -07001136 sb.append("-su");
Amith Yamasani119be9a2018-02-18 22:23:00 -08001137 break;
1138 case REASON_SUB_USAGE_ACTIVE_TIMEOUT:
Amith Yamasani3154dcf2018-03-27 18:24:04 -07001139 sb.append("-at");
Amith Yamasani119be9a2018-02-18 22:23:00 -08001140 break;
1141 case REASON_SUB_USAGE_SYNC_ADAPTER:
Amith Yamasani3154dcf2018-03-27 18:24:04 -07001142 sb.append("-sa");
Amith Yamasani119be9a2018-02-18 22:23:00 -08001143 break;
Amith Yamasani80c4be82018-03-26 10:54:04 -07001144 case REASON_SUB_USAGE_SLICE_PINNED:
Makoto Onukid5f25d22018-05-22 16:02:17 -07001145 sb.append("-lp");
Amith Yamasani80c4be82018-03-26 10:54:04 -07001146 break;
1147 case REASON_SUB_USAGE_SLICE_PINNED_PRIV:
Makoto Onukid5f25d22018-05-22 16:02:17 -07001148 sb.append("-lv");
1149 break;
1150 case REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_NON_DOZE:
1151 sb.append("-en");
1152 break;
1153 case REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_DOZE:
1154 sb.append("-ed");
Amith Yamasani80c4be82018-03-26 10:54:04 -07001155 break;
Makoto Onuki75ad2492018-03-28 14:42:42 -07001156 case REASON_SUB_USAGE_EXEMPTED_SYNC_START:
Makoto Onukid5f25d22018-05-22 16:02:17 -07001157 sb.append("-es");
Makoto Onuki75ad2492018-03-28 14:42:42 -07001158 break;
Michael Wachenschwanzc3295202019-02-20 17:19:52 -08001159 case REASON_SUB_USAGE_UNEXEMPTED_SYNC_SCHEDULED:
1160 sb.append("-uss");
1161 break;
Michael Wachenschwanz6ced0ee2019-04-15 16:43:28 -07001162 case REASON_SUB_USAGE_FOREGROUND_SERVICE_START:
1163 sb.append("-fss");
1164 break;
Amith Yamasani119be9a2018-02-18 22:23:00 -08001165 }
1166 break;
1167 }
1168 return sb.toString();
1169 }
1170
Michael Wachenschwanz0b4ab1f2019-01-07 13:59:10 -08001171 /** @hide */
1172 public static String usageSourceToString(int usageSource) {
1173 switch (usageSource) {
1174 case USAGE_SOURCE_TASK_ROOT_ACTIVITY:
1175 return "TASK_ROOT_ACTIVITY";
1176 case USAGE_SOURCE_CURRENT_ACTIVITY:
1177 return "CURRENT_ACTIVITY";
1178 default:
1179 StringBuilder sb = new StringBuilder();
1180 sb.append("UNKNOWN(");
1181 sb.append(usageSource);
1182 sb.append(")");
1183 return sb.toString();
1184 }
1185 }
1186
Amith Yamasanie8789312017-12-10 14:34:26 -08001187 /**
1188 * {@hide}
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001189 * Temporarily whitelist the specified app for a short duration. This is to allow an app
1190 * receiving a high priority message to be able to access the network and acquire wakelocks
1191 * even if the device is in power-save mode or the app is currently considered inactive.
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001192 * @param packageName The package name of the app to whitelist.
1193 * @param duration Duration to whitelist the app for, in milliseconds. It is recommended that
1194 * this be limited to 10s of seconds. Requested duration will be clamped to a few minutes.
1195 * @param user The user for whom the package should be whitelisted. Passing in a user that is
1196 * not the same as the caller's process will require the INTERACT_ACROSS_USERS permission.
1197 * @see #isAppInactive(String)
Kweku Adams835283f2019-11-20 14:41:22 -08001198 *
1199 * @deprecated Use
1200 * {@link android.os.PowerWhitelistManager#whitelistAppTemporarily(String, long)} instead.
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001201 */
1202 @SystemApi
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -06001203 @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST)
Kweku Adams835283f2019-11-20 14:41:22 -08001204 @Deprecated
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001205 public void whitelistAppTemporarily(String packageName, long duration, UserHandle user) {
Kweku Adams835283f2019-11-20 14:41:22 -08001206 mContext.getSystemService(PowerWhitelistManager.class)
1207 .whitelistAppTemporarily(packageName, duration);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001208 }
Amith Yamasani4ec63682016-02-19 12:55:27 -08001209
1210 /**
1211 * Inform usage stats that the carrier privileged apps access rules have changed.
yinxu0016eef2019-12-09 16:51:53 -08001212 * <p> The caller must have {@link android.Manifest.permission#BIND_CARRIER_SERVICES} </p>
Amith Yamasani4ec63682016-02-19 12:55:27 -08001213 * @hide
1214 */
yinxu0016eef2019-12-09 16:51:53 -08001215 @SystemApi
1216 @RequiresPermission(android.Manifest.permission.BIND_CARRIER_SERVICES)
Amith Yamasani4ec63682016-02-19 12:55:27 -08001217 public void onCarrierPrivilegedAppsChanged() {
1218 try {
1219 mService.onCarrierPrivilegedAppsChanged();
1220 } catch (RemoteException re) {
Amith Yamasanifd44f272018-05-14 14:47:19 -07001221 throw re.rethrowFromSystemServer();
Amith Yamasani4ec63682016-02-19 12:55:27 -08001222 }
1223 }
Kang Li53b43142016-11-14 14:38:25 -08001224
1225 /**
1226 * Reports a Chooser action to the UsageStatsManager.
1227 *
1228 * @param packageName The package name of the app that is selected.
1229 * @param userId The user id of who makes the selection.
1230 * @param contentType The type of the content, e.g., Image, Video, App.
1231 * @param annotations The annotations of the content, e.g., Game, Selfie.
1232 * @param action The action type of Intent that invokes ChooserActivity.
1233 * {@link UsageEvents}
1234 * @hide
1235 */
1236 public void reportChooserSelection(String packageName, int userId, String contentType,
1237 String[] annotations, String action) {
1238 try {
1239 mService.reportChooserSelection(packageName, userId, contentType, annotations, action);
1240 } catch (RemoteException re) {
1241 }
1242 }
Adam Lesinski0debc9a2014-07-16 19:09:13 -07001243}