blob: 5a57b067f2c435f7c40d36feff774319331a9afa [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;
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060020import android.annotation.RequiresPermission;
Amith Yamasaniaf575b92015-05-29 15:35:26 -070021import android.annotation.SystemApi;
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060022import android.annotation.SystemService;
Adam Lesinski0debc9a2014-07-16 19:09:13 -070023import android.content.Context;
Adam Lesinski35168002014-07-21 15:25:30 -070024import android.content.pm.ParceledListSlice;
Adam Lesinski0debc9a2014-07-16 19:09:13 -070025import android.os.RemoteException;
Amith Yamasanicf768722015-04-23 20:36:41 -070026import android.os.UserHandle;
Adam Lesinski35168002014-07-21 15:25:30 -070027import android.util.ArrayMap;
Adam Lesinski0debc9a2014-07-16 19:09:13 -070028
Amith Yamasaniafbccb72017-11-27 10:44:24 -080029import java.lang.annotation.Retention;
30import java.lang.annotation.RetentionPolicy;
Suprabh Shukla868bde22018-02-20 20:59:52 -080031import java.util.ArrayList;
Adam Lesinski35168002014-07-21 15:25:30 -070032import java.util.Collections;
33import java.util.List;
Adam Lesinskicc562a82014-08-27 11:52:52 -070034import java.util.Map;
Adam Lesinski35168002014-07-21 15:25:30 -070035
36/**
37 * Provides access to device usage history and statistics. Usage data is aggregated into
38 * time intervals: days, weeks, months, and years.
39 * <p />
40 * When requesting usage data since a particular time, the request might look something like this:
41 * <pre>
42 * PAST REQUEST_TIME TODAY FUTURE
43 * ————————————————————————————||———————————————————————————¦-----------------------|
44 * YEAR || ¦ |
45 * ————————————————————————————||———————————————————————————¦-----------------------|
46 * MONTH | || MONTH ¦ |
47 * ——————————————————|—————————||———————————————————————————¦-----------------------|
48 * | WEEK | WEEK|| | WEEK | WE¦EK | WEEK |
49 * ————————————————————————————||———————————————————|———————¦-----------------------|
50 * || |DAY|DAY|DAY|DAY¦DAY|DAY|DAY|DAY|DAY|DAY|
51 * ————————————————————————————||———————————————————————————¦-----------------------|
52 * </pre>
53 * A request for data in the middle of a time interval will include that interval.
54 * <p/>
Esteban Talaverafa962312017-10-09 14:58:28 +010055 * <b>NOTE:</b> This API requires the permission android.permission.PACKAGE_USAGE_STATS.
56 * However, declaring the permission implies intention to use the API and the user of the device
57 * still needs to grant permission through the Settings application.
58 * See {@link android.provider.Settings#ACTION_USAGE_ACCESS_SETTINGS}
Adam Lesinski35168002014-07-21 15:25:30 -070059 */
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060060@SystemService(Context.USAGE_STATS_SERVICE)
Adam Lesinski0debc9a2014-07-16 19:09:13 -070061public final class UsageStatsManager {
Adam Lesinski0debc9a2014-07-16 19:09:13 -070062
63 /**
Adam Lesinski35168002014-07-21 15:25:30 -070064 * An interval type that spans a day. See {@link #queryUsageStats(int, long, long)}.
Adam Lesinski0debc9a2014-07-16 19:09:13 -070065 */
Adam Lesinski35168002014-07-21 15:25:30 -070066 public static final int INTERVAL_DAILY = 0;
Adam Lesinski0debc9a2014-07-16 19:09:13 -070067
68 /**
Adam Lesinski35168002014-07-21 15:25:30 -070069 * An interval type that spans a week. See {@link #queryUsageStats(int, long, long)}.
Adam Lesinski0debc9a2014-07-16 19:09:13 -070070 */
Adam Lesinski35168002014-07-21 15:25:30 -070071 public static final int INTERVAL_WEEKLY = 1;
Adam Lesinski0debc9a2014-07-16 19:09:13 -070072
73 /**
Adam Lesinski35168002014-07-21 15:25:30 -070074 * An interval type that spans a month. See {@link #queryUsageStats(int, long, long)}.
Adam Lesinski0debc9a2014-07-16 19:09:13 -070075 */
Adam Lesinski35168002014-07-21 15:25:30 -070076 public static final int INTERVAL_MONTHLY = 2;
Adam Lesinski0debc9a2014-07-16 19:09:13 -070077
78 /**
Adam Lesinski35168002014-07-21 15:25:30 -070079 * An interval type that spans a year. See {@link #queryUsageStats(int, long, long)}.
80 */
81 public static final int INTERVAL_YEARLY = 3;
82
83 /**
84 * An interval type that will use the best fit interval for the given time range.
85 * See {@link #queryUsageStats(int, long, long)}.
86 */
87 public static final int INTERVAL_BEST = 4;
88
89 /**
90 * The number of available intervals. Does not include {@link #INTERVAL_BEST}, since it
91 * is a pseudo interval (it actually selects a real interval).
Adam Lesinski0debc9a2014-07-16 19:09:13 -070092 * {@hide}
93 */
Adam Lesinski35168002014-07-21 15:25:30 -070094 public static final int INTERVAL_COUNT = 4;
95
Amith Yamasaniafbccb72017-11-27 10:44:24 -080096
97 /**
98 * The app is whitelisted for some reason and the bucket cannot be changed.
99 * {@hide}
100 */
101 @SystemApi
102 public static final int STANDBY_BUCKET_EXEMPTED = 5;
103
104 /**
105 * The app was used very recently, currently in use or likely to be used very soon.
106 * @see #getAppStandbyBucket()
107 */
108 public static final int STANDBY_BUCKET_ACTIVE = 10;
109
110 /**
111 * The app was used recently and/or likely to be used in the next few hours.
112 * @see #getAppStandbyBucket()
113 */
114 public static final int STANDBY_BUCKET_WORKING_SET = 20;
115
116 /**
117 * The app was used in the last few days and/or likely to be used in the next few days.
118 * @see #getAppStandbyBucket()
119 */
120 public static final int STANDBY_BUCKET_FREQUENT = 30;
121
122 /**
123 * The app has not be used for several days and/or is unlikely to be used for several days.
124 * @see #getAppStandbyBucket()
125 */
126 public static final int STANDBY_BUCKET_RARE = 40;
127
128 /**
129 * The app has never been used.
130 * {@hide}
131 */
132 @SystemApi
133 public static final int STANDBY_BUCKET_NEVER = 50;
134
Amith Yamasani119be9a2018-02-18 22:23:00 -0800135 /** @hide */
136 public static final int REASON_MAIN_MASK = 0xFF00;
137 /** @hide */
138 public static final int REASON_MAIN_DEFAULT = 0x0100;
139 /** @hide */
140 public static final int REASON_MAIN_TIMEOUT = 0x0200;
141 /** @hide */
142 public static final int REASON_MAIN_USAGE = 0x0300;
143 /** @hide */
144 public static final int REASON_MAIN_FORCED = 0x0400;
145 /** @hide */
146 public static final int REASON_MAIN_PREDICTED = 0x0500;
Amith Yamasaniafbccb72017-11-27 10:44:24 -0800147
Amith Yamasani119be9a2018-02-18 22:23:00 -0800148 /** @hide */
149 public static final int REASON_SUB_MASK = 0x00FF;
150 /** @hide */
151 public static final int REASON_SUB_USAGE_SYSTEM_INTERACTION = 0x0001;
152 /** @hide */
153 public static final int REASON_SUB_USAGE_NOTIFICATION_SEEN = 0x0002;
154 /** @hide */
155 public static final int REASON_SUB_USAGE_USER_INTERACTION = 0x0003;
156 /** @hide */
157 public static final int REASON_SUB_USAGE_MOVE_TO_FOREGROUND = 0x0004;
158 /** @hide */
159 public static final int REASON_SUB_USAGE_MOVE_TO_BACKGROUND = 0x0005;
160 /** @hide */
161 public static final int REASON_SUB_USAGE_SYSTEM_UPDATE = 0x0006;
162 /** @hide */
163 public static final int REASON_SUB_USAGE_ACTIVE_TIMEOUT = 0x0007;
164 /** @hide */
165 public static final int REASON_SUB_USAGE_SYNC_ADAPTER = 0x0008;
Amith Yamasaniafbccb72017-11-27 10:44:24 -0800166
167 /** @hide */
Jeff Sharkeyce8db992017-12-13 20:05:05 -0700168 @IntDef(flag = false, prefix = { "STANDBY_BUCKET_" }, value = {
Amith Yamasaniafbccb72017-11-27 10:44:24 -0800169 STANDBY_BUCKET_EXEMPTED,
170 STANDBY_BUCKET_ACTIVE,
171 STANDBY_BUCKET_WORKING_SET,
172 STANDBY_BUCKET_FREQUENT,
173 STANDBY_BUCKET_RARE,
174 STANDBY_BUCKET_NEVER,
175 })
176 @Retention(RetentionPolicy.SOURCE)
177 public @interface StandbyBuckets {}
178
Adam Lesinski35168002014-07-21 15:25:30 -0700179 private static final UsageEvents sEmptyResults = new UsageEvents();
Adam Lesinski0debc9a2014-07-16 19:09:13 -0700180
181 private final Context mContext;
182 private final IUsageStatsManager mService;
183
184 /**
185 * {@hide}
186 */
187 public UsageStatsManager(Context context, IUsageStatsManager service) {
188 mContext = context;
189 mService = service;
190 }
191
Adam Lesinski35168002014-07-21 15:25:30 -0700192 /**
193 * Gets application usage stats for the given time range, aggregated by the specified interval.
194 * <p>The returned list will contain a {@link UsageStats} object for each package that
195 * has data for an interval that is a subset of the time range given. To illustrate:</p>
196 * <pre>
197 * intervalType = INTERVAL_YEARLY
198 * beginTime = 2013
199 * endTime = 2015 (exclusive)
200 *
201 * Results:
202 * 2013 - com.example.alpha
203 * 2013 - com.example.beta
204 * 2014 - com.example.alpha
205 * 2014 - com.example.beta
206 * 2014 - com.example.charlie
207 * </pre>
208 *
209 * @param intervalType The time interval by which the stats are aggregated.
210 * @param beginTime The inclusive beginning of the range of stats to include in the results.
211 * @param endTime The exclusive end of the range of stats to include in the results.
Esteban Talaverafa962312017-10-09 14:58:28 +0100212 * @return A list of {@link UsageStats}
Adam Lesinski35168002014-07-21 15:25:30 -0700213 *
214 * @see #INTERVAL_DAILY
215 * @see #INTERVAL_WEEKLY
216 * @see #INTERVAL_MONTHLY
217 * @see #INTERVAL_YEARLY
218 * @see #INTERVAL_BEST
219 */
Adam Lesinski35168002014-07-21 15:25:30 -0700220 public List<UsageStats> queryUsageStats(int intervalType, long beginTime, long endTime) {
Adam Lesinski0debc9a2014-07-16 19:09:13 -0700221 try {
Adam Lesinski7f61e962014-09-02 16:43:52 -0700222 @SuppressWarnings("unchecked")
Adam Lesinski35168002014-07-21 15:25:30 -0700223 ParceledListSlice<UsageStats> slice = mService.queryUsageStats(intervalType, beginTime,
224 endTime, mContext.getOpPackageName());
225 if (slice != null) {
226 return slice.getList();
Adam Lesinski0debc9a2014-07-16 19:09:13 -0700227 }
Adam Lesinski35168002014-07-21 15:25:30 -0700228 } catch (RemoteException e) {
Esteban Talaverafa962312017-10-09 14:58:28 +0100229 // fallthrough and return the empty list.
Adam Lesinski35168002014-07-21 15:25:30 -0700230 }
Adam Lesinski7f61e962014-09-02 16:43:52 -0700231 return Collections.emptyList();
232 }
233
234 /**
235 * Gets the hardware configurations the device was in for the given time range, aggregated by
236 * the specified interval. The results are ordered as in
237 * {@link #queryUsageStats(int, long, long)}.
238 *
239 * @param intervalType The time interval by which the stats are aggregated.
240 * @param beginTime The inclusive beginning of the range of stats to include in the results.
241 * @param endTime The exclusive end of the range of stats to include in the results.
Esteban Talaverafa962312017-10-09 14:58:28 +0100242 * @return A list of {@link ConfigurationStats}
Adam Lesinski7f61e962014-09-02 16:43:52 -0700243 */
244 public List<ConfigurationStats> queryConfigurations(int intervalType, long beginTime,
245 long endTime) {
246 try {
247 @SuppressWarnings("unchecked")
248 ParceledListSlice<ConfigurationStats> slice = mService.queryConfigurationStats(
249 intervalType, beginTime, endTime, mContext.getOpPackageName());
250 if (slice != null) {
251 return slice.getList();
252 }
253 } catch (RemoteException e) {
254 // fallthrough and return the empty list.
255 }
256 return Collections.emptyList();
Adam Lesinski35168002014-07-21 15:25:30 -0700257 }
Adam Lesinski0debc9a2014-07-16 19:09:13 -0700258
Adam Lesinski35168002014-07-21 15:25:30 -0700259 /**
260 * Query for events in the given time range. Events are only kept by the system for a few
261 * days.
Adam Lesinski35168002014-07-21 15:25:30 -0700262 *
263 * @param beginTime The inclusive beginning of the range of events to include in the results.
264 * @param endTime The exclusive end of the range of events to include in the results.
265 * @return A {@link UsageEvents}.
266 */
Adam Lesinski35168002014-07-21 15:25:30 -0700267 public UsageEvents queryEvents(long beginTime, long endTime) {
268 try {
269 UsageEvents iter = mService.queryEvents(beginTime, endTime,
270 mContext.getOpPackageName());
271 if (iter != null) {
272 return iter;
273 }
274 } catch (RemoteException e) {
Esteban Talaverafa962312017-10-09 14:58:28 +0100275 // fallthrough and return empty result.
Adam Lesinski35168002014-07-21 15:25:30 -0700276 }
277 return sEmptyResults;
278 }
Adam Lesinski0debc9a2014-07-16 19:09:13 -0700279
Adam Lesinski35168002014-07-21 15:25:30 -0700280 /**
281 * A convenience method that queries for all stats in the given range (using the best interval
282 * for that range), merges the resulting data, and keys it by package name.
283 * See {@link #queryUsageStats(int, long, long)}.
284 *
285 * @param beginTime The inclusive beginning of the range of stats to include in the results.
286 * @param endTime The exclusive end of the range of stats to include in the results.
Esteban Talaverafa962312017-10-09 14:58:28 +0100287 * @return A {@link java.util.Map} keyed by package name
Adam Lesinski35168002014-07-21 15:25:30 -0700288 */
Adam Lesinskicc562a82014-08-27 11:52:52 -0700289 public Map<String, UsageStats> queryAndAggregateUsageStats(long beginTime, long endTime) {
Adam Lesinski35168002014-07-21 15:25:30 -0700290 List<UsageStats> stats = queryUsageStats(INTERVAL_BEST, beginTime, endTime);
291 if (stats.isEmpty()) {
Adam Lesinskicc562a82014-08-27 11:52:52 -0700292 return Collections.emptyMap();
Adam Lesinski35168002014-07-21 15:25:30 -0700293 }
Adam Lesinski0debc9a2014-07-16 19:09:13 -0700294
Adam Lesinski35168002014-07-21 15:25:30 -0700295 ArrayMap<String, UsageStats> aggregatedStats = new ArrayMap<>();
296 final int statCount = stats.size();
297 for (int i = 0; i < statCount; i++) {
298 UsageStats newStat = stats.get(i);
299 UsageStats existingStat = aggregatedStats.get(newStat.getPackageName());
300 if (existingStat == null) {
301 aggregatedStats.put(newStat.mPackageName, newStat);
302 } else {
303 existingStat.add(newStat);
Adam Lesinski0debc9a2014-07-16 19:09:13 -0700304 }
305 }
306 return aggregatedStats;
307 }
Amith Yamasanicf768722015-04-23 20:36:41 -0700308
309 /**
Amith Yamasanie5f33042015-05-08 13:20:22 -0700310 * Returns whether the specified app is currently considered inactive. This will be true if the
Amith Yamasanicf768722015-04-23 20:36:41 -0700311 * app hasn't been used directly or indirectly for a period of time defined by the system. This
312 * could be of the order of several hours or days.
313 * @param packageName The package name of the app to query
Amith Yamasanie5f33042015-05-08 13:20:22 -0700314 * @return whether the app is currently considered inactive
Amith Yamasanicf768722015-04-23 20:36:41 -0700315 */
Amith Yamasanie5f33042015-05-08 13:20:22 -0700316 public boolean isAppInactive(String packageName) {
Amith Yamasanicf768722015-04-23 20:36:41 -0700317 try {
Jeff Sharkeyad357d12018-02-02 13:25:31 -0700318 return mService.isAppInactive(packageName, mContext.getUserId());
Amith Yamasanicf768722015-04-23 20:36:41 -0700319 } catch (RemoteException e) {
320 // fall through and return default
321 }
322 return false;
323 }
Amith Yamasani901e9242015-05-13 18:21:09 -0700324
325 /**
Amith Yamasaniafbccb72017-11-27 10:44:24 -0800326 * {@hide}
Amith Yamasani901e9242015-05-13 18:21:09 -0700327 */
328 public void setAppInactive(String packageName, boolean inactive) {
329 try {
Jeff Sharkeyad357d12018-02-02 13:25:31 -0700330 mService.setAppInactive(packageName, inactive, mContext.getUserId());
Amith Yamasani901e9242015-05-13 18:21:09 -0700331 } catch (RemoteException e) {
332 // fall through
333 }
334 }
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700335
336 /**
Amith Yamasaniafbccb72017-11-27 10:44:24 -0800337 * Returns the current standby bucket of the calling app. The system determines the standby
338 * state of the app based on app usage patterns. Standby buckets determine how much an app will
339 * be restricted from running background tasks such as jobs, alarms and certain PendingIntent
340 * callbacks.
Amith Yamasanie8789312017-12-10 14:34:26 -0800341 * <p>Restrictions increase progressively from {@link #STANDBY_BUCKET_ACTIVE} to
Amith Yamasaniafbccb72017-11-27 10:44:24 -0800342 * {@link #STANDBY_BUCKET_RARE}, with {@link #STANDBY_BUCKET_ACTIVE} being the least
343 * restrictive. The battery level of the device might also affect the restrictions.
344 *
Amith Yamasanie8789312017-12-10 14:34:26 -0800345 * @return the current standby bucket of the calling app. One of STANDBY_BUCKET_* constants.
Amith Yamasani17fffee2017-09-29 13:17:43 -0700346 */
Amith Yamasaniafbccb72017-11-27 10:44:24 -0800347 public @StandbyBuckets int getAppStandbyBucket() {
348 try {
349 return mService.getAppStandbyBucket(mContext.getOpPackageName(),
350 mContext.getOpPackageName(),
351 mContext.getUserId());
352 } catch (RemoteException e) {
353 }
354 return STANDBY_BUCKET_ACTIVE;
355 }
356
357 /**
358 * {@hide}
359 * Returns the current standby bucket of the specified app. The caller must hold the permission
360 * android.permission.PACKAGE_USAGE_STATS.
361 * @param packageName the package for which to fetch the current standby bucket.
362 */
363 @SystemApi
364 @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS)
Amith Yamasani17fffee2017-09-29 13:17:43 -0700365 public @StandbyBuckets int getAppStandbyBucket(String packageName) {
366 try {
367 return mService.getAppStandbyBucket(packageName, mContext.getOpPackageName(),
368 mContext.getUserId());
369 } catch (RemoteException e) {
370 }
Amith Yamasaniafbccb72017-11-27 10:44:24 -0800371 return STANDBY_BUCKET_ACTIVE;
Amith Yamasani17fffee2017-09-29 13:17:43 -0700372 }
373
374 /**
Amith Yamasaniafbccb72017-11-27 10:44:24 -0800375 * {@hide}
Amith Yamasanie8789312017-12-10 14:34:26 -0800376 * Changes an app's standby bucket to the provided value. The caller can only set the standby
377 * bucket for a different app than itself.
378 * @param packageName the package name of the app to set the bucket for. A SecurityException
379 * will be thrown if the package name is that of the caller.
380 * @param bucket the standby bucket to set it to, which should be one of STANDBY_BUCKET_*.
381 * Setting a standby bucket outside of the range of STANDBY_BUCKET_ACTIVE to
382 * STANDBY_BUCKET_NEVER will result in a SecurityException.
Amith Yamasani17fffee2017-09-29 13:17:43 -0700383 */
Amith Yamasani4470ab92017-10-31 13:29:00 -0700384 @SystemApi
385 @RequiresPermission(android.Manifest.permission.CHANGE_APP_IDLE_STATE)
Amith Yamasani17fffee2017-09-29 13:17:43 -0700386 public void setAppStandbyBucket(String packageName, @StandbyBuckets int bucket) {
387 try {
388 mService.setAppStandbyBucket(packageName, bucket, mContext.getUserId());
389 } catch (RemoteException e) {
390 // Nothing to do
391 }
392 }
393
394 /**
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700395 * {@hide}
Amith Yamasanie8789312017-12-10 14:34:26 -0800396 * Returns the current standby bucket of every app that has a bucket assigned to it.
397 * The caller must hold the permission android.permission.PACKAGE_USAGE_STATS. The key of the
398 * returned Map is the package name and the value is the bucket assigned to the package.
399 * @see #getAppStandbyBucket()
400 */
401 @SystemApi
402 @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS)
403 public Map<String, Integer> getAppStandbyBuckets() {
404 try {
Suprabh Shukla868bde22018-02-20 20:59:52 -0800405 final ParceledListSlice<AppStandbyInfo> slice = mService.getAppStandbyBuckets(
Amith Yamasanie8789312017-12-10 14:34:26 -0800406 mContext.getOpPackageName(), mContext.getUserId());
Suprabh Shukla868bde22018-02-20 20:59:52 -0800407 final List<AppStandbyInfo> bucketList = slice.getList();
408 final ArrayMap<String, Integer> bucketMap = new ArrayMap<>();
409 final int n = bucketList.size();
410 for (int i = 0; i < n; i++) {
411 final AppStandbyInfo bucketInfo = bucketList.get(i);
412 bucketMap.put(bucketInfo.mPackageName, bucketInfo.mStandbyBucket);
413 }
414 return bucketMap;
Amith Yamasanie8789312017-12-10 14:34:26 -0800415 } catch (RemoteException e) {
416 }
417 return Collections.EMPTY_MAP;
418 }
419
420 /**
421 * {@hide}
422 * Changes the app standby bucket for multiple apps at once. The Map is keyed by the package
423 * name and the value is one of STANDBY_BUCKET_*.
424 * @param appBuckets a map of package name to bucket value.
425 */
426 @SystemApi
427 @RequiresPermission(android.Manifest.permission.CHANGE_APP_IDLE_STATE)
428 public void setAppStandbyBuckets(Map<String, Integer> appBuckets) {
Suprabh Shukla868bde22018-02-20 20:59:52 -0800429 if (appBuckets == null) {
430 return;
431 }
432 final List<AppStandbyInfo> bucketInfoList = new ArrayList<>(appBuckets.size());
433 for (Map.Entry<String, Integer> bucketEntry : appBuckets.entrySet()) {
434 bucketInfoList.add(new AppStandbyInfo(bucketEntry.getKey(), bucketEntry.getValue()));
435 }
436 final ParceledListSlice<AppStandbyInfo> slice = new ParceledListSlice<>(bucketInfoList);
Amith Yamasanie8789312017-12-10 14:34:26 -0800437 try {
Suprabh Shukla868bde22018-02-20 20:59:52 -0800438 mService.setAppStandbyBuckets(slice, mContext.getUserId());
Amith Yamasanie8789312017-12-10 14:34:26 -0800439 } catch (RemoteException e) {
440 }
441 }
442
Amith Yamasani119be9a2018-02-18 22:23:00 -0800443 /** @hide */
444 public static String reasonToString(int standbyReason) {
445 StringBuilder sb = new StringBuilder();
446 switch (standbyReason & REASON_MAIN_MASK) {
447 case REASON_MAIN_DEFAULT:
448 sb.append("d");
449 break;
450 case REASON_MAIN_FORCED:
451 sb.append("f");
452 break;
453 case REASON_MAIN_PREDICTED:
454 sb.append("p");
455 break;
456 case REASON_MAIN_TIMEOUT:
457 sb.append("t");
458 break;
459 case REASON_MAIN_USAGE:
460 sb.append("u-");
461 switch (standbyReason & REASON_SUB_MASK) {
462 case REASON_SUB_USAGE_SYSTEM_INTERACTION:
463 sb.append("si");
464 break;
465 case REASON_SUB_USAGE_NOTIFICATION_SEEN:
466 sb.append("ns");
467 break;
468 case REASON_SUB_USAGE_USER_INTERACTION:
469 sb.append("ui");
470 break;
471 case REASON_SUB_USAGE_MOVE_TO_FOREGROUND:
472 sb.append("mf");
473 break;
474 case REASON_SUB_USAGE_MOVE_TO_BACKGROUND:
475 sb.append("mb");
476 break;
477 case REASON_SUB_USAGE_SYSTEM_UPDATE:
478 sb.append("su");
479 break;
480 case REASON_SUB_USAGE_ACTIVE_TIMEOUT:
481 sb.append("at");
482 break;
483 case REASON_SUB_USAGE_SYNC_ADAPTER:
484 sb.append("sa");
485 break;
486 }
487 break;
488 }
489 return sb.toString();
490 }
491
Amith Yamasanie8789312017-12-10 14:34:26 -0800492 /**
493 * {@hide}
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700494 * Temporarily whitelist the specified app for a short duration. This is to allow an app
495 * receiving a high priority message to be able to access the network and acquire wakelocks
496 * even if the device is in power-save mode or the app is currently considered inactive.
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700497 * @param packageName The package name of the app to whitelist.
498 * @param duration Duration to whitelist the app for, in milliseconds. It is recommended that
499 * this be limited to 10s of seconds. Requested duration will be clamped to a few minutes.
500 * @param user The user for whom the package should be whitelisted. Passing in a user that is
501 * not the same as the caller's process will require the INTERACT_ACROSS_USERS permission.
502 * @see #isAppInactive(String)
503 */
504 @SystemApi
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -0600505 @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST)
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700506 public void whitelistAppTemporarily(String packageName, long duration, UserHandle user) {
507 try {
508 mService.whitelistAppTemporarily(packageName, duration, user.getIdentifier());
509 } catch (RemoteException re) {
510 }
511 }
Amith Yamasani4ec63682016-02-19 12:55:27 -0800512
513 /**
514 * Inform usage stats that the carrier privileged apps access rules have changed.
515 * @hide
516 */
517 public void onCarrierPrivilegedAppsChanged() {
518 try {
519 mService.onCarrierPrivilegedAppsChanged();
520 } catch (RemoteException re) {
521 }
522 }
Kang Li53b43142016-11-14 14:38:25 -0800523
524 /**
525 * Reports a Chooser action to the UsageStatsManager.
526 *
527 * @param packageName The package name of the app that is selected.
528 * @param userId The user id of who makes the selection.
529 * @param contentType The type of the content, e.g., Image, Video, App.
530 * @param annotations The annotations of the content, e.g., Game, Selfie.
531 * @param action The action type of Intent that invokes ChooserActivity.
532 * {@link UsageEvents}
533 * @hide
534 */
535 public void reportChooserSelection(String packageName, int userId, String contentType,
536 String[] annotations, String action) {
537 try {
538 mService.reportChooserSelection(packageName, userId, contentType, annotations, action);
539 } catch (RemoteException re) {
540 }
541 }
Adam Lesinski0debc9a2014-07-16 19:09:13 -0700542}