UsageStatsManager.java revision 80c4be88e0c108e3cb4c528c078c53fde6676af3
1/** 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 19import android.annotation.IntDef; 20import android.annotation.NonNull; 21import android.annotation.RequiresPermission; 22import android.annotation.SystemApi; 23import android.annotation.SystemService; 24import android.app.PendingIntent; 25import android.content.Context; 26import android.content.pm.ParceledListSlice; 27import android.os.RemoteException; 28import android.os.UserHandle; 29import android.util.ArrayMap; 30 31import java.lang.annotation.Retention; 32import java.lang.annotation.RetentionPolicy; 33import java.util.ArrayList; 34import java.util.Collections; 35import java.util.List; 36import java.util.Map; 37import java.util.concurrent.TimeUnit; 38 39/** 40 * Provides access to device usage history and statistics. Usage data is aggregated into 41 * time intervals: days, weeks, months, and years. 42 * <p /> 43 * When requesting usage data since a particular time, the request might look something like this: 44 * <pre> 45 * PAST REQUEST_TIME TODAY FUTURE 46 * ————————————————————————————||———————————————————————————¦-----------------------| 47 * YEAR || ¦ | 48 * ————————————————————————————||———————————————————————————¦-----------------------| 49 * MONTH | || MONTH ¦ | 50 * ——————————————————|—————————||———————————————————————————¦-----------------------| 51 * | WEEK | WEEK|| | WEEK | WE¦EK | WEEK | 52 * ————————————————————————————||———————————————————|———————¦-----------------------| 53 * || |DAY|DAY|DAY|DAY¦DAY|DAY|DAY|DAY|DAY|DAY| 54 * ————————————————————————————||———————————————————————————¦-----------------------| 55 * </pre> 56 * A request for data in the middle of a time interval will include that interval. 57 * <p/> 58 * <b>NOTE:</b> Most methods on this API require the permission 59 * android.permission.PACKAGE_USAGE_STATS. However, declaring the permission implies intention to 60 * use the API and the user of the device still needs to grant permission through the Settings 61 * application. 62 * See {@link android.provider.Settings#ACTION_USAGE_ACCESS_SETTINGS}. 63 * Methods which only return the information for the calling package do not require this permission. 64 * E.g. {@link #getAppStandbyBucket()} and {@link #queryEventsForSelf(long, long)}. 65 */ 66@SystemService(Context.USAGE_STATS_SERVICE) 67public final class UsageStatsManager { 68 69 /** 70 * An interval type that spans a day. See {@link #queryUsageStats(int, long, long)}. 71 */ 72 public static final int INTERVAL_DAILY = 0; 73 74 /** 75 * An interval type that spans a week. See {@link #queryUsageStats(int, long, long)}. 76 */ 77 public static final int INTERVAL_WEEKLY = 1; 78 79 /** 80 * An interval type that spans a month. See {@link #queryUsageStats(int, long, long)}. 81 */ 82 public static final int INTERVAL_MONTHLY = 2; 83 84 /** 85 * An interval type that spans a year. See {@link #queryUsageStats(int, long, long)}. 86 */ 87 public static final int INTERVAL_YEARLY = 3; 88 89 /** 90 * An interval type that will use the best fit interval for the given time range. 91 * See {@link #queryUsageStats(int, long, long)}. 92 */ 93 public static final int INTERVAL_BEST = 4; 94 95 /** 96 * The number of available intervals. Does not include {@link #INTERVAL_BEST}, since it 97 * is a pseudo interval (it actually selects a real interval). 98 * {@hide} 99 */ 100 public static final int INTERVAL_COUNT = 4; 101 102 103 /** 104 * The app is whitelisted for some reason and the bucket cannot be changed. 105 * {@hide} 106 */ 107 @SystemApi 108 public static final int STANDBY_BUCKET_EXEMPTED = 5; 109 110 /** 111 * The app was used very recently, currently in use or likely to be used very soon. Standby 112 * bucket values that are ≤ {@link #STANDBY_BUCKET_ACTIVE} will not be throttled by the 113 * system while they are in this bucket. Buckets > {@link #STANDBY_BUCKET_ACTIVE} will most 114 * likely be restricted in some way. For instance, jobs and alarms may be deferred. 115 * @see #getAppStandbyBucket() 116 */ 117 public static final int STANDBY_BUCKET_ACTIVE = 10; 118 119 /** 120 * The app was used recently and/or likely to be used in the next few hours. Restrictions will 121 * apply to these apps, such as deferral of jobs and alarms. 122 * @see #getAppStandbyBucket() 123 */ 124 public static final int STANDBY_BUCKET_WORKING_SET = 20; 125 126 /** 127 * The app was used in the last few days and/or likely to be used in the next few days. 128 * Restrictions will apply to these apps, such as deferral of jobs and alarms. The delays may be 129 * greater than for apps in higher buckets (lower bucket value). Bucket values > 130 * {@link #STANDBY_BUCKET_FREQUENT} may additionally have network access limited. 131 * @see #getAppStandbyBucket() 132 */ 133 public static final int STANDBY_BUCKET_FREQUENT = 30; 134 135 /** 136 * The app has not be used for several days and/or is unlikely to be used for several days. 137 * Apps in this bucket will have the most restrictions, including network restrictions, except 138 * during certain short periods (at a minimum, once a day) when they are allowed to execute 139 * jobs, access the network, etc. 140 * @see #getAppStandbyBucket() 141 */ 142 public static final int STANDBY_BUCKET_RARE = 40; 143 144 /** 145 * The app has never been used. 146 * {@hide} 147 */ 148 @SystemApi 149 public static final int STANDBY_BUCKET_NEVER = 50; 150 151 /** @hide */ 152 public static final int REASON_MAIN_MASK = 0xFF00; 153 /** @hide */ 154 public static final int REASON_MAIN_DEFAULT = 0x0100; 155 /** @hide */ 156 public static final int REASON_MAIN_TIMEOUT = 0x0200; 157 /** @hide */ 158 public static final int REASON_MAIN_USAGE = 0x0300; 159 /** @hide */ 160 public static final int REASON_MAIN_FORCED = 0x0400; 161 /** @hide */ 162 public static final int REASON_MAIN_PREDICTED = 0x0500; 163 164 /** @hide */ 165 public static final int REASON_SUB_MASK = 0x00FF; 166 /** @hide */ 167 public static final int REASON_SUB_USAGE_SYSTEM_INTERACTION = 0x0001; 168 /** @hide */ 169 public static final int REASON_SUB_USAGE_NOTIFICATION_SEEN = 0x0002; 170 /** @hide */ 171 public static final int REASON_SUB_USAGE_USER_INTERACTION = 0x0003; 172 /** @hide */ 173 public static final int REASON_SUB_USAGE_MOVE_TO_FOREGROUND = 0x0004; 174 /** @hide */ 175 public static final int REASON_SUB_USAGE_MOVE_TO_BACKGROUND = 0x0005; 176 /** @hide */ 177 public static final int REASON_SUB_USAGE_SYSTEM_UPDATE = 0x0006; 178 /** @hide */ 179 public static final int REASON_SUB_USAGE_ACTIVE_TIMEOUT = 0x0007; 180 /** @hide */ 181 public static final int REASON_SUB_USAGE_SYNC_ADAPTER = 0x0008; 182 /** @hide */ 183 public static final int REASON_SUB_USAGE_SLICE_PINNED = 0x0009; 184 /** @hide */ 185 public static final int REASON_SUB_USAGE_SLICE_PINNED_PRIV = 0x000A; 186 187 /** @hide */ 188 @IntDef(flag = false, prefix = { "STANDBY_BUCKET_" }, value = { 189 STANDBY_BUCKET_EXEMPTED, 190 STANDBY_BUCKET_ACTIVE, 191 STANDBY_BUCKET_WORKING_SET, 192 STANDBY_BUCKET_FREQUENT, 193 STANDBY_BUCKET_RARE, 194 STANDBY_BUCKET_NEVER, 195 }) 196 @Retention(RetentionPolicy.SOURCE) 197 public @interface StandbyBuckets {} 198 199 /** 200 * Observer id of the registered observer for the group of packages that reached the usage 201 * time limit. Included as an extra in the PendingIntent that was registered. 202 * @hide 203 */ 204 @SystemApi 205 public static final String EXTRA_OBSERVER_ID = "android.app.usage.extra.OBSERVER_ID"; 206 207 /** 208 * Original time limit in milliseconds specified by the registered observer for the group of 209 * packages that reached the usage time limit. Included as an extra in the PendingIntent that 210 * was registered. 211 * @hide 212 */ 213 @SystemApi 214 public static final String EXTRA_TIME_LIMIT = "android.app.usage.extra.TIME_LIMIT"; 215 216 /** 217 * Actual usage time in milliseconds for the group of packages that reached the specified time 218 * limit. Included as an extra in the PendingIntent that was registered. 219 * @hide 220 */ 221 @SystemApi 222 public static final String EXTRA_TIME_USED = "android.app.usage.extra.TIME_USED"; 223 224 private static final UsageEvents sEmptyResults = new UsageEvents(); 225 226 private final Context mContext; 227 private final IUsageStatsManager mService; 228 229 /** 230 * {@hide} 231 */ 232 public UsageStatsManager(Context context, IUsageStatsManager service) { 233 mContext = context; 234 mService = service; 235 } 236 237 /** 238 * Gets application usage stats for the given time range, aggregated by the specified interval. 239 * <p>The returned list will contain a {@link UsageStats} object for each package that 240 * has data for an interval that is a subset of the time range given. To illustrate:</p> 241 * <pre> 242 * intervalType = INTERVAL_YEARLY 243 * beginTime = 2013 244 * endTime = 2015 (exclusive) 245 * 246 * Results: 247 * 2013 - com.example.alpha 248 * 2013 - com.example.beta 249 * 2014 - com.example.alpha 250 * 2014 - com.example.beta 251 * 2014 - com.example.charlie 252 * </pre> 253 * 254 * <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} </p> 255 * 256 * @param intervalType The time interval by which the stats are aggregated. 257 * @param beginTime The inclusive beginning of the range of stats to include in the results. 258 * @param endTime The exclusive end of the range of stats to include in the results. 259 * @return A list of {@link UsageStats} 260 * 261 * @see #INTERVAL_DAILY 262 * @see #INTERVAL_WEEKLY 263 * @see #INTERVAL_MONTHLY 264 * @see #INTERVAL_YEARLY 265 * @see #INTERVAL_BEST 266 */ 267 public List<UsageStats> queryUsageStats(int intervalType, long beginTime, long endTime) { 268 try { 269 @SuppressWarnings("unchecked") 270 ParceledListSlice<UsageStats> slice = mService.queryUsageStats(intervalType, beginTime, 271 endTime, mContext.getOpPackageName()); 272 if (slice != null) { 273 return slice.getList(); 274 } 275 } catch (RemoteException e) { 276 // fallthrough and return the empty list. 277 } 278 return Collections.emptyList(); 279 } 280 281 /** 282 * Gets the hardware configurations the device was in for the given time range, aggregated by 283 * the specified interval. The results are ordered as in 284 * {@link #queryUsageStats(int, long, long)}. 285 * <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} </p> 286 * 287 * @param intervalType The time interval by which the stats are aggregated. 288 * @param beginTime The inclusive beginning of the range of stats to include in the results. 289 * @param endTime The exclusive end of the range of stats to include in the results. 290 * @return A list of {@link ConfigurationStats} 291 */ 292 public List<ConfigurationStats> queryConfigurations(int intervalType, long beginTime, 293 long endTime) { 294 try { 295 @SuppressWarnings("unchecked") 296 ParceledListSlice<ConfigurationStats> slice = mService.queryConfigurationStats( 297 intervalType, beginTime, endTime, mContext.getOpPackageName()); 298 if (slice != null) { 299 return slice.getList(); 300 } 301 } catch (RemoteException e) { 302 // fallthrough and return the empty list. 303 } 304 return Collections.emptyList(); 305 } 306 307 /** 308 * Query for events in the given time range. Events are only kept by the system for a few 309 * days. 310 * <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} </p> 311 * 312 * @param beginTime The inclusive beginning of the range of events to include in the results. 313 * @param endTime The exclusive end of the range of events to include in the results. 314 * @return A {@link UsageEvents}. 315 */ 316 public UsageEvents queryEvents(long beginTime, long endTime) { 317 try { 318 UsageEvents iter = mService.queryEvents(beginTime, endTime, 319 mContext.getOpPackageName()); 320 if (iter != null) { 321 return iter; 322 } 323 } catch (RemoteException e) { 324 // fallthrough and return empty result. 325 } 326 return sEmptyResults; 327 } 328 329 /** 330 * Like {@link #queryEvents(long, long)}, but only returns events for the calling package. 331 * 332 * @param beginTime The inclusive beginning of the range of events to include in the results. 333 * @param endTime The exclusive end of the range of events to include in the results. 334 * @return A {@link UsageEvents} object. 335 * 336 * @see #queryEvents(long, long) 337 */ 338 public UsageEvents queryEventsForSelf(long beginTime, long endTime) { 339 try { 340 final UsageEvents events = mService.queryEventsForPackage(beginTime, endTime, 341 mContext.getOpPackageName()); 342 if (events != null) { 343 return events; 344 } 345 } catch (RemoteException e) { 346 // fallthrough 347 } 348 return sEmptyResults; 349 } 350 351 /** 352 * A convenience method that queries for all stats in the given range (using the best interval 353 * for that range), merges the resulting data, and keys it by package name. 354 * See {@link #queryUsageStats(int, long, long)}. 355 * <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} </p> 356 * 357 * @param beginTime The inclusive beginning of the range of stats to include in the results. 358 * @param endTime The exclusive end of the range of stats to include in the results. 359 * @return A {@link java.util.Map} keyed by package name 360 */ 361 public Map<String, UsageStats> queryAndAggregateUsageStats(long beginTime, long endTime) { 362 List<UsageStats> stats = queryUsageStats(INTERVAL_BEST, beginTime, endTime); 363 if (stats.isEmpty()) { 364 return Collections.emptyMap(); 365 } 366 367 ArrayMap<String, UsageStats> aggregatedStats = new ArrayMap<>(); 368 final int statCount = stats.size(); 369 for (int i = 0; i < statCount; i++) { 370 UsageStats newStat = stats.get(i); 371 UsageStats existingStat = aggregatedStats.get(newStat.getPackageName()); 372 if (existingStat == null) { 373 aggregatedStats.put(newStat.mPackageName, newStat); 374 } else { 375 existingStat.add(newStat); 376 } 377 } 378 return aggregatedStats; 379 } 380 381 /** 382 * Returns whether the specified app is currently considered inactive. This will be true if the 383 * app hasn't been used directly or indirectly for a period of time defined by the system. This 384 * could be of the order of several hours or days. 385 * @param packageName The package name of the app to query 386 * @return whether the app is currently considered inactive 387 */ 388 public boolean isAppInactive(String packageName) { 389 try { 390 return mService.isAppInactive(packageName, mContext.getUserId()); 391 } catch (RemoteException e) { 392 // fall through and return default 393 } 394 return false; 395 } 396 397 /** 398 * {@hide} 399 */ 400 public void setAppInactive(String packageName, boolean inactive) { 401 try { 402 mService.setAppInactive(packageName, inactive, mContext.getUserId()); 403 } catch (RemoteException e) { 404 // fall through 405 } 406 } 407 408 /** 409 * Returns the current standby bucket of the calling app. The system determines the standby 410 * state of the app based on app usage patterns. Standby buckets determine how much an app will 411 * be restricted from running background tasks such as jobs and alarms. 412 * <p>Restrictions increase progressively from {@link #STANDBY_BUCKET_ACTIVE} to 413 * {@link #STANDBY_BUCKET_RARE}, with {@link #STANDBY_BUCKET_ACTIVE} being the least 414 * restrictive. The battery level of the device might also affect the restrictions. 415 * <p>Apps in buckets ≤ {@link #STANDBY_BUCKET_ACTIVE} have no standby restrictions imposed. 416 * Apps in buckets > {@link #STANDBY_BUCKET_FREQUENT} may have network access restricted when 417 * running in the background. 418 * <p>The standby state of an app can change at any time either due to a user interaction or a 419 * system interaction or some algorithm determining that the app can be restricted for a period 420 * of time before the user has a need for it. 421 * <p>You can also query the recent history of standby bucket changes by calling 422 * {@link #queryEventsForSelf(long, long)} and searching for 423 * {@link UsageEvents.Event#STANDBY_BUCKET_CHANGED}. 424 * 425 * @return the current standby bucket of the calling app. One of STANDBY_BUCKET_* constants. 426 */ 427 public @StandbyBuckets int getAppStandbyBucket() { 428 try { 429 return mService.getAppStandbyBucket(mContext.getOpPackageName(), 430 mContext.getOpPackageName(), 431 mContext.getUserId()); 432 } catch (RemoteException e) { 433 } 434 return STANDBY_BUCKET_ACTIVE; 435 } 436 437 /** 438 * {@hide} 439 * Returns the current standby bucket of the specified app. The caller must hold the permission 440 * android.permission.PACKAGE_USAGE_STATS. 441 * @param packageName the package for which to fetch the current standby bucket. 442 */ 443 @SystemApi 444 @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) 445 public @StandbyBuckets int getAppStandbyBucket(String packageName) { 446 try { 447 return mService.getAppStandbyBucket(packageName, mContext.getOpPackageName(), 448 mContext.getUserId()); 449 } catch (RemoteException e) { 450 } 451 return STANDBY_BUCKET_ACTIVE; 452 } 453 454 /** 455 * {@hide} 456 * Changes an app's standby bucket to the provided value. The caller can only set the standby 457 * bucket for a different app than itself. 458 * @param packageName the package name of the app to set the bucket for. A SecurityException 459 * will be thrown if the package name is that of the caller. 460 * @param bucket the standby bucket to set it to, which should be one of STANDBY_BUCKET_*. 461 * Setting a standby bucket outside of the range of STANDBY_BUCKET_ACTIVE to 462 * STANDBY_BUCKET_NEVER will result in a SecurityException. 463 */ 464 @SystemApi 465 @RequiresPermission(android.Manifest.permission.CHANGE_APP_IDLE_STATE) 466 public void setAppStandbyBucket(String packageName, @StandbyBuckets int bucket) { 467 try { 468 mService.setAppStandbyBucket(packageName, bucket, mContext.getUserId()); 469 } catch (RemoteException e) { 470 // Nothing to do 471 } 472 } 473 474 /** 475 * {@hide} 476 * Returns the current standby bucket of every app that has a bucket assigned to it. 477 * The caller must hold the permission android.permission.PACKAGE_USAGE_STATS. The key of the 478 * returned Map is the package name and the value is the bucket assigned to the package. 479 * @see #getAppStandbyBucket() 480 */ 481 @SystemApi 482 @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) 483 public Map<String, Integer> getAppStandbyBuckets() { 484 try { 485 final ParceledListSlice<AppStandbyInfo> slice = mService.getAppStandbyBuckets( 486 mContext.getOpPackageName(), mContext.getUserId()); 487 final List<AppStandbyInfo> bucketList = slice.getList(); 488 final ArrayMap<String, Integer> bucketMap = new ArrayMap<>(); 489 final int n = bucketList.size(); 490 for (int i = 0; i < n; i++) { 491 final AppStandbyInfo bucketInfo = bucketList.get(i); 492 bucketMap.put(bucketInfo.mPackageName, bucketInfo.mStandbyBucket); 493 } 494 return bucketMap; 495 } catch (RemoteException e) { 496 } 497 return Collections.EMPTY_MAP; 498 } 499 500 /** 501 * {@hide} 502 * Changes the app standby bucket for multiple apps at once. The Map is keyed by the package 503 * name and the value is one of STANDBY_BUCKET_*. 504 * @param appBuckets a map of package name to bucket value. 505 */ 506 @SystemApi 507 @RequiresPermission(android.Manifest.permission.CHANGE_APP_IDLE_STATE) 508 public void setAppStandbyBuckets(Map<String, Integer> appBuckets) { 509 if (appBuckets == null) { 510 return; 511 } 512 final List<AppStandbyInfo> bucketInfoList = new ArrayList<>(appBuckets.size()); 513 for (Map.Entry<String, Integer> bucketEntry : appBuckets.entrySet()) { 514 bucketInfoList.add(new AppStandbyInfo(bucketEntry.getKey(), bucketEntry.getValue())); 515 } 516 final ParceledListSlice<AppStandbyInfo> slice = new ParceledListSlice<>(bucketInfoList); 517 try { 518 mService.setAppStandbyBuckets(slice, mContext.getUserId()); 519 } catch (RemoteException e) { 520 } 521 } 522 523 /** 524 * @hide 525 * Register an app usage limit observer that receives a callback on the provided intent when 526 * the sum of usages of apps in the packages array exceeds the {@code timeLimit} specified. The 527 * observer will automatically be unregistered when the time limit is reached and the intent 528 * is delivered. Registering an {@code observerId} that was already registered will override 529 * the previous one. 530 * @param observerId A unique id associated with the group of apps to be monitored. There can 531 * be multiple groups with common packages and different time limits. 532 * @param packages The list of packages to observe for foreground activity time. Cannot be null 533 * and must include at least one package. 534 * @param timeLimit The total time the set of apps can be in the foreground before the 535 * callbackIntent is delivered. Must be greater than 0. 536 * @param timeUnit The unit for time specified in {@code timeLimit}. Cannot be null. 537 * @param callbackIntent The PendingIntent that will be dispatched when the time limit is 538 * exceeded by the group of apps. The delivered Intent will also contain 539 * the extras {@link #EXTRA_OBSERVER_ID}, {@link #EXTRA_TIME_LIMIT} and 540 * {@link #EXTRA_TIME_USED}. Cannot be null. 541 * @throws SecurityException if the caller doesn't have the OBSERVE_APP_USAGE permission or 542 * is not the profile owner of this user. 543 */ 544 @SystemApi 545 @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE) 546 public void registerAppUsageObserver(int observerId, @NonNull String[] packages, long timeLimit, 547 @NonNull TimeUnit timeUnit, @NonNull PendingIntent callbackIntent) { 548 try { 549 mService.registerAppUsageObserver(observerId, packages, timeUnit.toMillis(timeLimit), 550 callbackIntent, mContext.getOpPackageName()); 551 } catch (RemoteException e) { 552 } 553 } 554 555 /** 556 * @hide 557 * Unregister the app usage observer specified by the {@code observerId}. This will only apply 558 * to any observer registered by this application. Unregistering an observer that was already 559 * unregistered or never registered will have no effect. 560 * @param observerId The id of the observer that was previously registered. 561 * @throws SecurityException if the caller doesn't have the OBSERVE_APP_USAGE permission or is 562 * not the profile owner of this user. 563 */ 564 @SystemApi 565 @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE) 566 public void unregisterAppUsageObserver(int observerId) { 567 try { 568 mService.unregisterAppUsageObserver(observerId, mContext.getOpPackageName()); 569 } catch (RemoteException e) { 570 } 571 } 572 573 /** @hide */ 574 public static String reasonToString(int standbyReason) { 575 StringBuilder sb = new StringBuilder(); 576 switch (standbyReason & REASON_MAIN_MASK) { 577 case REASON_MAIN_DEFAULT: 578 sb.append("d"); 579 break; 580 case REASON_MAIN_FORCED: 581 sb.append("f"); 582 break; 583 case REASON_MAIN_PREDICTED: 584 sb.append("p"); 585 break; 586 case REASON_MAIN_TIMEOUT: 587 sb.append("t"); 588 break; 589 case REASON_MAIN_USAGE: 590 sb.append("u-"); 591 switch (standbyReason & REASON_SUB_MASK) { 592 case REASON_SUB_USAGE_SYSTEM_INTERACTION: 593 sb.append("si"); 594 break; 595 case REASON_SUB_USAGE_NOTIFICATION_SEEN: 596 sb.append("ns"); 597 break; 598 case REASON_SUB_USAGE_USER_INTERACTION: 599 sb.append("ui"); 600 break; 601 case REASON_SUB_USAGE_MOVE_TO_FOREGROUND: 602 sb.append("mf"); 603 break; 604 case REASON_SUB_USAGE_MOVE_TO_BACKGROUND: 605 sb.append("mb"); 606 break; 607 case REASON_SUB_USAGE_SYSTEM_UPDATE: 608 sb.append("su"); 609 break; 610 case REASON_SUB_USAGE_ACTIVE_TIMEOUT: 611 sb.append("at"); 612 break; 613 case REASON_SUB_USAGE_SYNC_ADAPTER: 614 sb.append("sa"); 615 break; 616 case REASON_SUB_USAGE_SLICE_PINNED: 617 sb.append("slp"); 618 break; 619 case REASON_SUB_USAGE_SLICE_PINNED_PRIV: 620 sb.append("slpp"); 621 break; 622 } 623 break; 624 } 625 return sb.toString(); 626 } 627 628 /** 629 * {@hide} 630 * Temporarily whitelist the specified app for a short duration. This is to allow an app 631 * receiving a high priority message to be able to access the network and acquire wakelocks 632 * even if the device is in power-save mode or the app is currently considered inactive. 633 * @param packageName The package name of the app to whitelist. 634 * @param duration Duration to whitelist the app for, in milliseconds. It is recommended that 635 * this be limited to 10s of seconds. Requested duration will be clamped to a few minutes. 636 * @param user The user for whom the package should be whitelisted. Passing in a user that is 637 * not the same as the caller's process will require the INTERACT_ACROSS_USERS permission. 638 * @see #isAppInactive(String) 639 */ 640 @SystemApi 641 @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST) 642 public void whitelistAppTemporarily(String packageName, long duration, UserHandle user) { 643 try { 644 mService.whitelistAppTemporarily(packageName, duration, user.getIdentifier()); 645 } catch (RemoteException re) { 646 } 647 } 648 649 /** 650 * Inform usage stats that the carrier privileged apps access rules have changed. 651 * @hide 652 */ 653 public void onCarrierPrivilegedAppsChanged() { 654 try { 655 mService.onCarrierPrivilegedAppsChanged(); 656 } catch (RemoteException re) { 657 } 658 } 659 660 /** 661 * Reports a Chooser action to the UsageStatsManager. 662 * 663 * @param packageName The package name of the app that is selected. 664 * @param userId The user id of who makes the selection. 665 * @param contentType The type of the content, e.g., Image, Video, App. 666 * @param annotations The annotations of the content, e.g., Game, Selfie. 667 * @param action The action type of Intent that invokes ChooserActivity. 668 * {@link UsageEvents} 669 * @hide 670 */ 671 public void reportChooserSelection(String packageName, int userId, String contentType, 672 String[] annotations, String action) { 673 try { 674 mService.reportChooserSelection(packageName, userId, contentType, annotations, action); 675 } catch (RemoteException re) { 676 } 677 } 678} 679