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 17 package android.app.usage; 18 19 import android.Manifest; 20 import android.annotation.CurrentTimeMillisLong; 21 import android.annotation.IntDef; 22 import android.annotation.IntRange; 23 import android.annotation.NonNull; 24 import android.annotation.Nullable; 25 import android.annotation.RequiresPermission; 26 import android.annotation.SystemApi; 27 import android.annotation.SystemService; 28 import android.annotation.TestApi; 29 import android.annotation.UserHandleAware; 30 import android.app.Activity; 31 import android.app.BroadcastOptions; 32 import android.app.PendingIntent; 33 import android.compat.annotation.UnsupportedAppUsage; 34 import android.content.Context; 35 import android.content.pm.ParceledListSlice; 36 import android.os.Build; 37 import android.os.PowerWhitelistManager; 38 import android.os.RemoteException; 39 import android.os.UserHandle; 40 import android.os.UserManager; 41 import android.util.ArrayMap; 42 43 import java.lang.annotation.Retention; 44 import java.lang.annotation.RetentionPolicy; 45 import java.time.Duration; 46 import java.util.ArrayList; 47 import java.util.Collections; 48 import java.util.List; 49 import java.util.Map; 50 import java.util.concurrent.TimeUnit; 51 52 /** 53 * Provides access to device usage history and statistics. Usage data is aggregated into 54 * time intervals: days, weeks, months, and years. 55 * <p /> 56 * When requesting usage data since a particular time, the request might look something like this: 57 * <pre> 58 * PAST REQUEST_TIME TODAY FUTURE 59 * ————————————————————————————||———————————————————————————¦-----------------------| 60 * YEAR || ¦ | 61 * ————————————————————————————||———————————————————————————¦-----------------------| 62 * MONTH | || MONTH ¦ | 63 * ——————————————————|—————————||———————————————————————————¦-----------------------| 64 * | WEEK | WEEK|| | WEEK | WE¦EK | WEEK | 65 * ————————————————————————————||———————————————————|———————¦-----------------------| 66 * || |DAY|DAY|DAY|DAY¦DAY|DAY|DAY|DAY|DAY|DAY| 67 * ————————————————————————————||———————————————————————————¦-----------------------| 68 * </pre> 69 * A request for data in the middle of a time interval will include that interval. 70 * <p/> 71 * <b>NOTE:</b> Most methods on this API require the permission 72 * android.permission.PACKAGE_USAGE_STATS. However, declaring the permission implies intention to 73 * use the API and the user of the device still needs to grant permission through the Settings 74 * application. 75 * See {@link android.provider.Settings#ACTION_USAGE_ACCESS_SETTINGS}. 76 * Methods which only return the information for the calling package do not require this permission. 77 * E.g. {@link #getAppStandbyBucket()} and {@link #queryEventsForSelf(long, long)}. 78 */ 79 @SystemService(Context.USAGE_STATS_SERVICE) 80 public final class UsageStatsManager { 81 82 /** 83 * An interval type that spans a day. See {@link #queryUsageStats(int, long, long)}. 84 */ 85 public static final int INTERVAL_DAILY = 0; 86 87 /** 88 * An interval type that spans a week. See {@link #queryUsageStats(int, long, long)}. 89 */ 90 public static final int INTERVAL_WEEKLY = 1; 91 92 /** 93 * An interval type that spans a month. See {@link #queryUsageStats(int, long, long)}. 94 */ 95 public static final int INTERVAL_MONTHLY = 2; 96 97 /** 98 * An interval type that spans a year. See {@link #queryUsageStats(int, long, long)}. 99 */ 100 public static final int INTERVAL_YEARLY = 3; 101 102 /** 103 * An interval type that will use the best fit interval for the given time range. 104 * See {@link #queryUsageStats(int, long, long)}. 105 */ 106 public static final int INTERVAL_BEST = 4; 107 108 /** 109 * The number of available intervals. Does not include {@link #INTERVAL_BEST}, since it 110 * is a pseudo interval (it actually selects a real interval). 111 * {@hide} 112 */ 113 public static final int INTERVAL_COUNT = 4; 114 115 116 /** 117 * The app is exempted for some reason and the bucket cannot be changed. 118 * {@hide} 119 */ 120 @SystemApi 121 public static final int STANDBY_BUCKET_EXEMPTED = 5; 122 123 /** 124 * The app was used very recently, currently in use or likely to be used very soon. Standby 125 * bucket values that are ≤ {@link #STANDBY_BUCKET_ACTIVE} will not be throttled by the 126 * system while they are in this bucket. Buckets > {@link #STANDBY_BUCKET_ACTIVE} will most 127 * likely be restricted in some way. For instance, jobs and alarms may be deferred. 128 * @see #getAppStandbyBucket() 129 */ 130 public static final int STANDBY_BUCKET_ACTIVE = 10; 131 132 /** 133 * The app was used recently and/or likely to be used in the next few hours. Restrictions will 134 * apply to these apps, such as deferral of jobs and alarms. 135 * @see #getAppStandbyBucket() 136 */ 137 public static final int STANDBY_BUCKET_WORKING_SET = 20; 138 139 /** 140 * The app was used in the last few days and/or likely to be used in the next few days. 141 * Restrictions will apply to these apps, such as deferral of jobs and alarms. The delays may be 142 * greater than for apps in higher buckets (lower bucket value). Bucket values > 143 * {@link #STANDBY_BUCKET_FREQUENT} may additionally have network access limited. 144 * @see #getAppStandbyBucket() 145 */ 146 public static final int STANDBY_BUCKET_FREQUENT = 30; 147 148 /** 149 * The app has not be used for several days and/or is unlikely to be used for several days. 150 * Apps in this bucket will have more restrictions, including network restrictions, except 151 * during certain short periods (at a minimum, once a day) when they are allowed to execute 152 * jobs, access the network, etc. 153 * @see #getAppStandbyBucket() 154 */ 155 public static final int STANDBY_BUCKET_RARE = 40; 156 157 /** 158 * The app has not be used for several days, is unlikely to be used for several days, and has 159 * been misbehaving in some manner. 160 * Apps in this bucket will have the most restrictions, including network restrictions and 161 * additional restrictions on jobs. 162 * <p> Note: this bucket is not enabled in {@link Build.VERSION_CODES#R}. 163 * @see #getAppStandbyBucket() 164 */ 165 public static final int STANDBY_BUCKET_RESTRICTED = 45; 166 167 /** 168 * The app has never been used. 169 * {@hide} 170 */ 171 @SystemApi 172 public static final int STANDBY_BUCKET_NEVER = 50; 173 174 /** @hide */ 175 public static final int REASON_MAIN_MASK = 0xFF00; 176 /** @hide */ 177 public static final int REASON_MAIN_DEFAULT = 0x0100; 178 /** 179 * The app spent sufficient time in the old bucket without any substantial event so it reached 180 * the timeout threshold to have its bucket lowered. 181 * @hide 182 */ 183 public static final int REASON_MAIN_TIMEOUT = 0x0200; 184 /** 185 * The app was used in some way. Look at the REASON_SUB_USAGE_ reason for more details. 186 * @hide 187 */ 188 public static final int REASON_MAIN_USAGE = 0x0300; 189 /** 190 * Forced by the user/developer, either explicitly or implicitly through some action. If user 191 * action was not involved and this is purely due to the system, 192 * {@link #REASON_MAIN_FORCED_BY_SYSTEM} should be used instead. 193 * @hide 194 */ 195 public static final int REASON_MAIN_FORCED_BY_USER = 0x0400; 196 /** 197 * Set by a privileged system app. This may be overridden by 198 * {@link #REASON_MAIN_FORCED_BY_SYSTEM} or user action. 199 * @hide 200 */ 201 public static final int REASON_MAIN_PREDICTED = 0x0500; 202 /** 203 * Forced by the system, independent of user action. If user action is involved, 204 * {@link #REASON_MAIN_FORCED_BY_USER} should be used instead. When this is used, only 205 * {@link #REASON_MAIN_FORCED_BY_SYSTEM} or user action can change the bucket. 206 * @hide 207 */ 208 public static final int REASON_MAIN_FORCED_BY_SYSTEM = 0x0600; 209 210 /** @hide */ 211 public static final int REASON_SUB_MASK = 0x00FF; 212 /** 213 * The reason for using the default main reason is unknown or undefined. 214 * @hide 215 */ 216 public static final int REASON_SUB_DEFAULT_UNDEFINED = 0x0000; 217 /** 218 * The app was updated. 219 * @hide 220 */ 221 public static final int REASON_SUB_DEFAULT_APP_UPDATE = 0x0001; 222 /** 223 * The app was restored. 224 * @hide 225 */ 226 public static final int REASON_SUB_DEFAULT_APP_RESTORED = 0x0002; 227 /** 228 * The app was interacted with in some way by the system. 229 * @hide 230 */ 231 public static final int REASON_SUB_USAGE_SYSTEM_INTERACTION = 0x0001; 232 /** 233 * A notification was viewed by the user. This does not mean the user interacted with the 234 * notification. 235 * @hide 236 */ 237 public static final int REASON_SUB_USAGE_NOTIFICATION_SEEN = 0x0002; 238 /** 239 * The app was interacted with in some way by the user. This includes interacting with 240 * notification. 241 * @hide 242 */ 243 public static final int REASON_SUB_USAGE_USER_INTERACTION = 0x0003; 244 /** 245 * An {@link android.app.Activity} moved to the foreground. 246 * @hide 247 */ 248 public static final int REASON_SUB_USAGE_MOVE_TO_FOREGROUND = 0x0004; 249 /** 250 * An {@link android.app.Activity} moved to the background. 251 * @hide 252 */ 253 public static final int REASON_SUB_USAGE_MOVE_TO_BACKGROUND = 0x0005; 254 /** 255 * There was a system update. 256 * @hide 257 */ 258 public static final int REASON_SUB_USAGE_SYSTEM_UPDATE = 0x0006; 259 /** 260 * An app is in an elevated bucket because of an active timeout preventing it from being placed 261 * in a lower bucket. 262 * @hide 263 */ 264 public static final int REASON_SUB_USAGE_ACTIVE_TIMEOUT = 0x0007; 265 /** 266 * This system package's sync adapter has been used for another package's content provider. 267 * @hide 268 */ 269 public static final int REASON_SUB_USAGE_SYNC_ADAPTER = 0x0008; 270 /** 271 * A slice was pinned by an app. 272 * @hide 273 */ 274 public static final int REASON_SUB_USAGE_SLICE_PINNED = 0x0009; 275 /** /** 276 * A slice was pinned by the default launcher or the default assistant. 277 * @hide 278 */ 279 public static final int REASON_SUB_USAGE_SLICE_PINNED_PRIV = 0x000A; 280 /** 281 * A sync operation that is exempt from app standby was scheduled when the device wasn't Dozing. 282 * @hide 283 */ 284 public static final int REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_NON_DOZE = 0x000B; 285 /** 286 * A sync operation that is exempt from app standby was scheduled while the device was Dozing. 287 * @hide 288 */ 289 public static final int REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_DOZE = 0x000C; 290 /** 291 * A sync operation that is exempt from app standby started. 292 * @hide 293 */ 294 public static final int REASON_SUB_USAGE_EXEMPTED_SYNC_START = 0x000D; 295 /** 296 * A sync operation that is not exempt from app standby was scheduled. 297 * @hide 298 */ 299 public static final int REASON_SUB_USAGE_UNEXEMPTED_SYNC_SCHEDULED = 0x000E; 300 /** 301 * A foreground service started. 302 * @hide 303 */ 304 public static final int REASON_SUB_USAGE_FOREGROUND_SERVICE_START = 0x000F; 305 /** 306 * The predicted bucket was restored after the app's temporary elevation to the ACTIVE bucket 307 * ended. 308 * @hide 309 */ 310 public static final int REASON_SUB_PREDICTED_RESTORED = 0x0001; 311 /** 312 * The reason the system forced the app into the bucket is unknown or undefined. 313 * @hide 314 */ 315 public static final int REASON_SUB_FORCED_SYSTEM_FLAG_UNDEFINED = 0; 316 /** 317 * The app was unnecessarily using system resources (battery, memory, etc) in the background. 318 * @hide 319 */ 320 public static final int REASON_SUB_FORCED_SYSTEM_FLAG_BACKGROUND_RESOURCE_USAGE = 1 << 0; 321 /** 322 * The app was deemed to be intentionally abusive. 323 * @hide 324 */ 325 public static final int REASON_SUB_FORCED_SYSTEM_FLAG_ABUSE = 1 << 1; 326 /** 327 * The app was displaying buggy behavior. 328 * @hide 329 */ 330 public static final int REASON_SUB_FORCED_SYSTEM_FLAG_BUGGY = 1 << 2; 331 /** 332 * The app was moved to restricted bucket due to user interaction, i.e., toggling FAS. 333 * 334 * <p> 335 * Note: This should be coming from the more end-user facing UX, not from developer 336 * options nor adb command. 337 </p> 338 * 339 * @hide 340 */ 341 public static final int REASON_SUB_FORCED_USER_FLAG_INTERACTION = 1 << 1; 342 343 344 /** @hide */ 345 @IntDef(flag = false, prefix = { "STANDBY_BUCKET_" }, value = { 346 STANDBY_BUCKET_EXEMPTED, 347 STANDBY_BUCKET_ACTIVE, 348 STANDBY_BUCKET_WORKING_SET, 349 STANDBY_BUCKET_FREQUENT, 350 STANDBY_BUCKET_RARE, 351 STANDBY_BUCKET_RESTRICTED, 352 STANDBY_BUCKET_NEVER, 353 }) 354 @Retention(RetentionPolicy.SOURCE) 355 public @interface StandbyBuckets {} 356 357 /** @hide */ 358 @IntDef(flag = true, prefix = {"REASON_SUB_FORCED_"}, value = { 359 REASON_SUB_FORCED_SYSTEM_FLAG_UNDEFINED, 360 REASON_SUB_FORCED_SYSTEM_FLAG_BACKGROUND_RESOURCE_USAGE, 361 REASON_SUB_FORCED_SYSTEM_FLAG_ABUSE, 362 REASON_SUB_FORCED_SYSTEM_FLAG_BUGGY, 363 REASON_SUB_FORCED_USER_FLAG_INTERACTION, 364 }) 365 @Retention(RetentionPolicy.SOURCE) 366 public @interface ForcedReasons { 367 } 368 369 /** 370 * Observer id of the registered observer for the group of packages that reached the usage 371 * time limit. Included as an extra in the PendingIntent that was registered. 372 * @hide 373 */ 374 @SystemApi 375 public static final String EXTRA_OBSERVER_ID = "android.app.usage.extra.OBSERVER_ID"; 376 377 /** 378 * Original time limit in milliseconds specified by the registered observer for the group of 379 * packages that reached the usage time limit. Included as an extra in the PendingIntent that 380 * was registered. 381 * @hide 382 */ 383 @SystemApi 384 public static final String EXTRA_TIME_LIMIT = "android.app.usage.extra.TIME_LIMIT"; 385 386 /** 387 * Actual usage time in milliseconds for the group of packages that reached the specified time 388 * limit. Included as an extra in the PendingIntent that was registered. 389 * @hide 390 */ 391 @SystemApi 392 public static final String EXTRA_TIME_USED = "android.app.usage.extra.TIME_USED"; 393 394 395 /** 396 * App usage observers will consider the task root package the source of usage. 397 * @hide 398 */ 399 @SystemApi 400 public static final int USAGE_SOURCE_TASK_ROOT_ACTIVITY = 1; 401 402 /** 403 * App usage observers will consider the visible activity's package the source of usage. 404 * @hide 405 */ 406 @SystemApi 407 public static final int USAGE_SOURCE_CURRENT_ACTIVITY = 2; 408 409 /** @hide */ 410 @IntDef(prefix = { "USAGE_SOURCE_" }, value = { 411 USAGE_SOURCE_TASK_ROOT_ACTIVITY, 412 USAGE_SOURCE_CURRENT_ACTIVITY, 413 }) 414 @Retention(RetentionPolicy.SOURCE) 415 public @interface UsageSource {} 416 417 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) 418 private static final UsageEvents sEmptyResults = new UsageEvents(); 419 420 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) 421 private final Context mContext; 422 @UnsupportedAppUsage 423 private final IUsageStatsManager mService; 424 425 /** 426 * {@hide} 427 */ UsageStatsManager(Context context, IUsageStatsManager service)428 public UsageStatsManager(Context context, IUsageStatsManager service) { 429 mContext = context; 430 mService = service; 431 } 432 433 /** 434 * Gets application usage stats for the given time range, aggregated by the specified interval. 435 * 436 * <p> 437 * The returned list will contain one or more {@link UsageStats} objects for each package, with 438 * usage data that covers at least the given time range. 439 * Note: The begin and end times of the time range may be expanded to the nearest whole interval 440 * period. 441 * </p> 442 * 443 * <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} </p> 444 * <em>Note: Starting from {@link android.os.Build.VERSION_CODES#R Android R}, if the user's 445 * device is not in an unlocked state (as defined by {@link UserManager#isUserUnlocked()}), 446 * then {@code null} will be returned.</em> 447 * 448 * @param intervalType The time interval by which the stats are aggregated. 449 * @param beginTime The inclusive beginning of the range of stats to include in the results. 450 * Defined in terms of "Unix time", see 451 * {@link java.lang.System#currentTimeMillis}. 452 * @param endTime The exclusive end of the range of stats to include in the results. Defined 453 * in terms of "Unix time", see {@link java.lang.System#currentTimeMillis}. 454 * @return A list of {@link UsageStats} 455 * 456 * @see #INTERVAL_DAILY 457 * @see #INTERVAL_WEEKLY 458 * @see #INTERVAL_MONTHLY 459 * @see #INTERVAL_YEARLY 460 * @see #INTERVAL_BEST 461 */ 462 @UserHandleAware queryUsageStats(int intervalType, long beginTime, long endTime)463 public List<UsageStats> queryUsageStats(int intervalType, long beginTime, long endTime) { 464 try { 465 @SuppressWarnings("unchecked") 466 ParceledListSlice<UsageStats> slice = mService.queryUsageStats(intervalType, beginTime, 467 endTime, mContext.getOpPackageName(), mContext.getUserId()); 468 if (slice != null) { 469 return slice.getList(); 470 } 471 } catch (RemoteException e) { 472 // fallthrough and return the empty list. 473 } 474 return Collections.emptyList(); 475 } 476 477 /** 478 * Gets the hardware configurations the device was in for the given time range, aggregated by 479 * the specified interval. The results are ordered as in 480 * {@link #queryUsageStats(int, long, long)}. 481 * <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} </p> 482 * <em>Note: Starting from {@link android.os.Build.VERSION_CODES#R Android R}, if the user's 483 * device is not in an unlocked state (as defined by {@link UserManager#isUserUnlocked()}), 484 * then {@code null} will be returned.</em> 485 * 486 * @param intervalType The time interval by which the stats are aggregated. 487 * @param beginTime The inclusive beginning of the range of stats to include in the results. 488 * Defined in terms of "Unix time", see 489 * {@link java.lang.System#currentTimeMillis}. 490 * @param endTime The exclusive end of the range of stats to include in the results. Defined 491 * in terms of "Unix time", see {@link java.lang.System#currentTimeMillis}. 492 * @return A list of {@link ConfigurationStats} 493 */ queryConfigurations(int intervalType, long beginTime, long endTime)494 public List<ConfigurationStats> queryConfigurations(int intervalType, long beginTime, 495 long endTime) { 496 try { 497 @SuppressWarnings("unchecked") 498 ParceledListSlice<ConfigurationStats> slice = mService.queryConfigurationStats( 499 intervalType, beginTime, endTime, mContext.getOpPackageName()); 500 if (slice != null) { 501 return slice.getList(); 502 } 503 } catch (RemoteException e) { 504 // fallthrough and return the empty list. 505 } 506 return Collections.emptyList(); 507 } 508 509 /** 510 * Gets aggregated event stats for the given time range, aggregated by the specified interval. 511 * <p>The returned list will contain a {@link EventStats} object for each event type that 512 * is being aggregated and has data for an interval that is a subset of the time range given. 513 * 514 * <p>The current event types that will be aggregated here are:</p> 515 * <ul> 516 * <li>{@link UsageEvents.Event#SCREEN_INTERACTIVE}</li> 517 * <li>{@link UsageEvents.Event#SCREEN_NON_INTERACTIVE}</li> 518 * <li>{@link UsageEvents.Event#KEYGUARD_SHOWN}</li> 519 * <li>{@link UsageEvents.Event#KEYGUARD_HIDDEN}</li> 520 * </ul> 521 * 522 * <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} </p> 523 * <em>Note: Starting from {@link android.os.Build.VERSION_CODES#R Android R}, if the user's 524 * device is not in an unlocked state (as defined by {@link UserManager#isUserUnlocked()}), 525 * then {@code null} will be returned.</em> 526 * 527 * @param intervalType The time interval by which the stats are aggregated. 528 * @param beginTime The inclusive beginning of the range of stats to include in the results. 529 * Defined in terms of "Unix time", see 530 * {@link java.lang.System#currentTimeMillis}. 531 * @param endTime The exclusive end of the range of stats to include in the results. Defined 532 * in terms of "Unix time", see {@link java.lang.System#currentTimeMillis}. 533 * @return A list of {@link EventStats} 534 * 535 * @see #INTERVAL_DAILY 536 * @see #INTERVAL_WEEKLY 537 * @see #INTERVAL_MONTHLY 538 * @see #INTERVAL_YEARLY 539 * @see #INTERVAL_BEST 540 */ queryEventStats(int intervalType, long beginTime, long endTime)541 public List<EventStats> queryEventStats(int intervalType, long beginTime, long endTime) { 542 try { 543 @SuppressWarnings("unchecked") 544 ParceledListSlice<EventStats> slice = mService.queryEventStats(intervalType, beginTime, 545 endTime, mContext.getOpPackageName()); 546 if (slice != null) { 547 return slice.getList(); 548 } 549 } catch (RemoteException e) { 550 // fallthrough and return the empty list. 551 } 552 return Collections.emptyList(); 553 } 554 555 /** 556 * Query for events in the given time range. Events are only kept by the system for a few 557 * days. 558 * <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} </p> 559 * <em>Note: Starting from {@link android.os.Build.VERSION_CODES#R Android R}, if the user's 560 * device is not in an unlocked state (as defined by {@link UserManager#isUserUnlocked()}), 561 * then {@code null} will be returned.</em> 562 * 563 * @param beginTime The inclusive beginning of the range of events to include in the results. 564 * Defined in terms of "Unix time", see 565 * {@link java.lang.System#currentTimeMillis}. 566 * @param endTime The exclusive end of the range of events to include in the results. Defined 567 * in terms of "Unix time", see {@link java.lang.System#currentTimeMillis}. 568 * @return A {@link UsageEvents}. 569 */ queryEvents(long beginTime, long endTime)570 public UsageEvents queryEvents(long beginTime, long endTime) { 571 try { 572 UsageEvents iter = mService.queryEvents(beginTime, endTime, 573 mContext.getOpPackageName()); 574 if (iter != null) { 575 return iter; 576 } 577 } catch (RemoteException e) { 578 // fallthrough and return empty result. 579 } 580 return sEmptyResults; 581 } 582 583 /** 584 * Like {@link #queryEvents(long, long)}, but only returns events for the calling package. 585 * <em>Note: Starting from {@link android.os.Build.VERSION_CODES#R Android R}, if the user's 586 * device is not in an unlocked state (as defined by {@link UserManager#isUserUnlocked()}), 587 * then {@code null} will be returned.</em> 588 * 589 * @param beginTime The inclusive beginning of the range of events to include in the results. 590 * Defined in terms of "Unix time", see 591 * {@link java.lang.System#currentTimeMillis}. 592 * @param endTime The exclusive end of the range of events to include in the results. Defined 593 * in terms of "Unix time", see {@link java.lang.System#currentTimeMillis}. 594 * @return A {@link UsageEvents} object. 595 * 596 * @see #queryEvents(long, long) 597 */ queryEventsForSelf(long beginTime, long endTime)598 public UsageEvents queryEventsForSelf(long beginTime, long endTime) { 599 try { 600 final UsageEvents events = mService.queryEventsForPackage(beginTime, endTime, 601 mContext.getOpPackageName()); 602 if (events != null) { 603 return events; 604 } 605 } catch (RemoteException e) { 606 // fallthrough 607 } 608 return sEmptyResults; 609 } 610 611 /** 612 * A convenience method that queries for all stats in the given range (using the best interval 613 * for that range), merges the resulting data, and keys it by package name. 614 * See {@link #queryUsageStats(int, long, long)}. 615 * <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} </p> 616 * 617 * @param beginTime The inclusive beginning of the range of stats to include in the results. 618 * Defined in terms of "Unix time", see 619 * {@link java.lang.System#currentTimeMillis}. 620 * @param endTime The exclusive end of the range of stats to include in the results. Defined 621 * in terms of "Unix time", see {@link java.lang.System#currentTimeMillis}. 622 * @return A {@link java.util.Map} keyed by package name 623 */ queryAndAggregateUsageStats(long beginTime, long endTime)624 public Map<String, UsageStats> queryAndAggregateUsageStats(long beginTime, long endTime) { 625 List<UsageStats> stats = queryUsageStats(INTERVAL_BEST, beginTime, endTime); 626 if (stats.isEmpty()) { 627 return Collections.emptyMap(); 628 } 629 630 ArrayMap<String, UsageStats> aggregatedStats = new ArrayMap<>(); 631 final int statCount = stats.size(); 632 for (int i = 0; i < statCount; i++) { 633 UsageStats newStat = stats.get(i); 634 UsageStats existingStat = aggregatedStats.get(newStat.getPackageName()); 635 if (existingStat == null) { 636 aggregatedStats.put(newStat.mPackageName, newStat); 637 } else { 638 existingStat.add(newStat); 639 } 640 } 641 return aggregatedStats; 642 } 643 644 /** 645 * Returns whether the specified app is currently considered inactive. This will be true if the 646 * app hasn't been used directly or indirectly for a period of time defined by the system. This 647 * could be of the order of several hours or days. Apps are not considered inactive when the 648 * device is charging. 649 * <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} to query the 650 * inactive state of other apps</p> 651 * 652 * @param packageName The package name of the app to query 653 * @return whether the app is currently considered inactive or false if querying another app 654 * without {@link android.Manifest.permission#PACKAGE_USAGE_STATS} 655 */ isAppInactive(String packageName)656 public boolean isAppInactive(String packageName) { 657 try { 658 return mService.isAppInactive(packageName, mContext.getUserId(), 659 mContext.getOpPackageName()); 660 } catch (RemoteException e) { 661 // fall through and return default 662 } 663 return false; 664 } 665 666 /** 667 * {@hide} 668 */ setAppInactive(String packageName, boolean inactive)669 public void setAppInactive(String packageName, boolean inactive) { 670 try { 671 mService.setAppInactive(packageName, inactive, mContext.getUserId()); 672 } catch (RemoteException e) { 673 // fall through 674 } 675 } 676 677 /** 678 * Returns the current standby bucket of the calling app. The system determines the standby 679 * state of the app based on app usage patterns. Standby buckets determine how much an app will 680 * be restricted from running background tasks such as jobs and alarms. 681 * <p>Restrictions increase progressively from {@link #STANDBY_BUCKET_ACTIVE} to 682 * {@link #STANDBY_BUCKET_RESTRICTED}, with {@link #STANDBY_BUCKET_ACTIVE} being the least 683 * restrictive. The battery level of the device might also affect the restrictions. 684 * <p>Apps in buckets ≤ {@link #STANDBY_BUCKET_ACTIVE} have no standby restrictions imposed. 685 * Apps in buckets > {@link #STANDBY_BUCKET_FREQUENT} may have network access restricted when 686 * running in the background. 687 * <p>The standby state of an app can change at any time either due to a user interaction or a 688 * system interaction or some algorithm determining that the app can be restricted for a period 689 * of time before the user has a need for it. 690 * <p>You can also query the recent history of standby bucket changes by calling 691 * {@link #queryEventsForSelf(long, long)} and searching for 692 * {@link UsageEvents.Event#STANDBY_BUCKET_CHANGED}. 693 * 694 * @return the current standby bucket of the calling app. One of STANDBY_BUCKET_* constants. 695 */ getAppStandbyBucket()696 public @StandbyBuckets int getAppStandbyBucket() { 697 try { 698 return mService.getAppStandbyBucket(mContext.getOpPackageName(), 699 mContext.getOpPackageName(), 700 mContext.getUserId()); 701 } catch (RemoteException e) { 702 } 703 return STANDBY_BUCKET_ACTIVE; 704 } 705 706 /** 707 * {@hide} 708 * Returns the current standby bucket of the specified app. The caller must hold the permission 709 * android.permission.PACKAGE_USAGE_STATS. 710 * @param packageName the package for which to fetch the current standby bucket. 711 */ 712 @SystemApi 713 @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) getAppStandbyBucket(String packageName)714 public @StandbyBuckets int getAppStandbyBucket(String packageName) { 715 try { 716 return mService.getAppStandbyBucket(packageName, mContext.getOpPackageName(), 717 mContext.getUserId()); 718 } catch (RemoteException e) { 719 } 720 return STANDBY_BUCKET_ACTIVE; 721 } 722 723 /** 724 * {@hide} 725 * Changes an app's standby bucket to the provided value. The caller can only set the standby 726 * bucket for a different app than itself. The caller will not be able to change an app's 727 * standby bucket if that app is in the {@link #STANDBY_BUCKET_RESTRICTED} bucket. 728 * @param packageName the package name of the app to set the bucket for. A SecurityException 729 * will be thrown if the package name is that of the caller. 730 * @param bucket the standby bucket to set it to, which should be one of STANDBY_BUCKET_*. 731 * Setting a standby bucket outside of the range of STANDBY_BUCKET_ACTIVE to 732 * STANDBY_BUCKET_NEVER will result in a SecurityException. 733 */ 734 @SystemApi 735 @RequiresPermission(android.Manifest.permission.CHANGE_APP_IDLE_STATE) setAppStandbyBucket(String packageName, @StandbyBuckets int bucket)736 public void setAppStandbyBucket(String packageName, @StandbyBuckets int bucket) { 737 try { 738 mService.setAppStandbyBucket(packageName, bucket, mContext.getUserId()); 739 } catch (RemoteException e) { 740 throw e.rethrowFromSystemServer(); 741 } 742 } 743 744 /** 745 * {@hide} 746 * Returns the current standby bucket of every app that has a bucket assigned to it. 747 * The caller must hold the permission android.permission.PACKAGE_USAGE_STATS. The key of the 748 * returned Map is the package name and the value is the bucket assigned to the package. 749 * @see #getAppStandbyBucket() 750 */ 751 @SystemApi 752 @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) getAppStandbyBuckets()753 public Map<String, Integer> getAppStandbyBuckets() { 754 try { 755 final ParceledListSlice<AppStandbyInfo> slice = mService.getAppStandbyBuckets( 756 mContext.getOpPackageName(), mContext.getUserId()); 757 final List<AppStandbyInfo> bucketList = slice.getList(); 758 final ArrayMap<String, Integer> bucketMap = new ArrayMap<>(); 759 final int n = bucketList.size(); 760 for (int i = 0; i < n; i++) { 761 final AppStandbyInfo bucketInfo = bucketList.get(i); 762 bucketMap.put(bucketInfo.mPackageName, bucketInfo.mStandbyBucket); 763 } 764 return bucketMap; 765 } catch (RemoteException e) { 766 throw e.rethrowFromSystemServer(); 767 } 768 } 769 770 /** 771 * {@hide} 772 * Changes the app standby bucket for multiple apps at once. The Map is keyed by the package 773 * name and the value is one of STANDBY_BUCKET_*. The caller will not be able to change an 774 * app's standby bucket if that app is in the {@link #STANDBY_BUCKET_RESTRICTED} bucket. 775 * @param appBuckets a map of package name to bucket value. 776 */ 777 @SystemApi 778 @RequiresPermission(android.Manifest.permission.CHANGE_APP_IDLE_STATE) setAppStandbyBuckets(Map<String, Integer> appBuckets)779 public void setAppStandbyBuckets(Map<String, Integer> appBuckets) { 780 if (appBuckets == null) { 781 return; 782 } 783 final List<AppStandbyInfo> bucketInfoList = new ArrayList<>(appBuckets.size()); 784 for (Map.Entry<String, Integer> bucketEntry : appBuckets.entrySet()) { 785 bucketInfoList.add(new AppStandbyInfo(bucketEntry.getKey(), bucketEntry.getValue())); 786 } 787 final ParceledListSlice<AppStandbyInfo> slice = new ParceledListSlice<>(bucketInfoList); 788 try { 789 mService.setAppStandbyBuckets(slice, mContext.getUserId()); 790 } catch (RemoteException e) { 791 throw e.rethrowFromSystemServer(); 792 } 793 } 794 795 /** 796 * Return the lowest bucket this app can ever enter. 797 * 798 * @param packageName the package for which to fetch the minimum allowed standby bucket. 799 * {@hide} 800 */ 801 @StandbyBuckets 802 @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) getAppMinStandbyBucket(String packageName)803 public int getAppMinStandbyBucket(String packageName) { 804 try { 805 return mService.getAppMinStandbyBucket(packageName, mContext.getOpPackageName(), 806 mContext.getUserId()); 807 } catch (RemoteException e) { 808 throw e.rethrowFromSystemServer(); 809 } 810 } 811 812 /** 813 * Changes an app's estimated launch time. An app is considered "launched" when a user opens 814 * one of its {@link android.app.Activity Activities}. The provided time is persisted across 815 * reboots and is used unless 1) the time is more than a week in the future and the platform 816 * thinks the app will be launched sooner, 2) the estimated time has passed. Passing in 817 * {@link Long#MAX_VALUE} effectively clears the previously set launch time for the app. 818 * 819 * @param packageName The package name of the app to set the bucket for. 820 * @param estimatedLaunchTimeMillis The next time the app is expected to be launched. Units are 821 * in milliseconds since epoch (the same as 822 * {@link System#currentTimeMillis()}). 823 * @hide 824 */ 825 @SystemApi 826 @RequiresPermission(android.Manifest.permission.CHANGE_APP_LAUNCH_TIME_ESTIMATE) setEstimatedLaunchTimeMillis(@onNull String packageName, @CurrentTimeMillisLong long estimatedLaunchTimeMillis)827 public void setEstimatedLaunchTimeMillis(@NonNull String packageName, 828 @CurrentTimeMillisLong long estimatedLaunchTimeMillis) { 829 if (packageName == null) { 830 throw new NullPointerException("package name cannot be null"); 831 } 832 if (estimatedLaunchTimeMillis <= 0) { 833 throw new IllegalArgumentException("estimated launch time must be positive"); 834 } 835 try { 836 mService.setEstimatedLaunchTime( 837 packageName, estimatedLaunchTimeMillis, mContext.getUserId()); 838 } catch (RemoteException e) { 839 throw e.rethrowFromSystemServer(); 840 } 841 } 842 843 /** 844 * Changes the estimated launch times for multiple apps at once. The map is keyed by the 845 * package name and the value is the estimated launch time. 846 * 847 * @param estimatedLaunchTimesMillis A map of package name to estimated launch time. 848 * @see #setEstimatedLaunchTimeMillis(String, long) 849 * @hide 850 */ 851 @SystemApi 852 @RequiresPermission(android.Manifest.permission.CHANGE_APP_LAUNCH_TIME_ESTIMATE) setEstimatedLaunchTimesMillis( @onNull Map<String, Long> estimatedLaunchTimesMillis)853 public void setEstimatedLaunchTimesMillis( 854 @NonNull Map<String, Long> estimatedLaunchTimesMillis) { 855 if (estimatedLaunchTimesMillis == null) { 856 throw new NullPointerException("estimatedLaunchTimesMillis cannot be null"); 857 } 858 final List<AppLaunchEstimateInfo> estimateList = 859 new ArrayList<>(estimatedLaunchTimesMillis.size()); 860 for (Map.Entry<String, Long> estimateEntry : estimatedLaunchTimesMillis.entrySet()) { 861 final String pkgName = estimateEntry.getKey(); 862 if (pkgName == null) { 863 throw new NullPointerException("package name cannot be null"); 864 } 865 final Long estimatedLaunchTime = estimateEntry.getValue(); 866 if (estimatedLaunchTime == null || estimatedLaunchTime <= 0) { 867 throw new IllegalArgumentException("estimated launch time must be positive"); 868 } 869 estimateList.add(new AppLaunchEstimateInfo(pkgName, estimatedLaunchTime)); 870 } 871 final ParceledListSlice<AppLaunchEstimateInfo> slice = 872 new ParceledListSlice<>(estimateList); 873 try { 874 mService.setEstimatedLaunchTimes(slice, mContext.getUserId()); 875 } catch (RemoteException e) { 876 throw e.rethrowFromSystemServer(); 877 } 878 } 879 880 /** 881 * @hide 882 * Register an app usage limit observer that receives a callback on the provided intent when 883 * the sum of usages of apps and tokens in the {@code observed} array exceeds the 884 * {@code timeLimit} specified. The structure of a token is a String with the reporting 885 * package's name and a token the reporting app will use, separated by the forward slash 886 * character. Example: com.reporting.package/5OM3*0P4QU3-7OK3N 887 * The observer will automatically be unregistered when the time limit is reached and the 888 * intent is delivered. Registering an {@code observerId} that was already registered will 889 * override the previous one. No more than 1000 unique {@code observerId} may be registered by 890 * a single uid at any one time. 891 * @param observerId A unique id associated with the group of apps to be monitored. There can 892 * be multiple groups with common packages and different time limits. 893 * @param observedEntities The list of packages and token to observe for usage time. Cannot be 894 * null and must include at least one package or token. 895 * @param timeLimit The total time the set of apps can be in the foreground before the 896 * callbackIntent is delivered. Must be at least one minute. 897 * @param timeUnit The unit for time specified in {@code timeLimit}. Cannot be null. 898 * @param callbackIntent The PendingIntent that will be dispatched when the usage limit is 899 * exceeded by the group of apps. The delivered Intent will also contain 900 * the extras {@link #EXTRA_OBSERVER_ID}, {@link #EXTRA_TIME_LIMIT} and 901 * {@link #EXTRA_TIME_USED}. Cannot be null. 902 * @throws SecurityException if the caller doesn't have the OBSERVE_APP_USAGE permission and 903 * is not the profile owner of this user. 904 */ 905 @SystemApi 906 @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE) registerAppUsageObserver(int observerId, @NonNull String[] observedEntities, long timeLimit, @NonNull TimeUnit timeUnit, @NonNull PendingIntent callbackIntent)907 public void registerAppUsageObserver(int observerId, @NonNull String[] observedEntities, 908 long timeLimit, @NonNull TimeUnit timeUnit, @NonNull PendingIntent callbackIntent) { 909 try { 910 mService.registerAppUsageObserver(observerId, observedEntities, 911 timeUnit.toMillis(timeLimit), callbackIntent, mContext.getOpPackageName()); 912 } catch (RemoteException e) { 913 throw e.rethrowFromSystemServer(); 914 } 915 } 916 917 /** 918 * @hide 919 * Unregister the app usage observer specified by the {@code observerId}. This will only apply 920 * to any observer registered by this application. Unregistering an observer that was already 921 * unregistered or never registered will have no effect. 922 * @param observerId The id of the observer that was previously registered. 923 * @throws SecurityException if the caller doesn't have the OBSERVE_APP_USAGE permission and is 924 * not the profile owner of this user. 925 */ 926 @SystemApi 927 @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE) unregisterAppUsageObserver(int observerId)928 public void unregisterAppUsageObserver(int observerId) { 929 try { 930 mService.unregisterAppUsageObserver(observerId, mContext.getOpPackageName()); 931 } catch (RemoteException e) { 932 throw e.rethrowFromSystemServer(); 933 } 934 } 935 936 /** 937 * Register a usage session observer that receives a callback on the provided {@code 938 * limitReachedCallbackIntent} when the sum of usages of apps and tokens in the {@code 939 * observed} array exceeds the {@code timeLimit} specified within a usage session. The 940 * structure of a token is a String with the reporting packages' name and a token the 941 * reporting app will use, separated by the forward slash character. 942 * Example: com.reporting.package/5OM3*0P4QU3-7OK3N 943 * After the {@code timeLimit} has been reached, the usage session observer will receive a 944 * callback on the provided {@code sessionEndCallbackIntent} when the usage session ends. 945 * Registering another session observer against a {@code sessionObserverId} that has already 946 * been registered will override the previous session observer. 947 * 948 * @param sessionObserverId A unique id associated with the group of apps to be 949 * monitored. There can be multiple groups with common 950 * packages and different time limits. 951 * @param observedEntities The list of packages and token to observe for usage time. Cannot be 952 * null and must include at least one package or token. 953 * @param timeLimit The total time the set of apps can be used continuously before the {@code 954 * limitReachedCallbackIntent} is delivered. Must be at least one minute. 955 * @param sessionThresholdTime The time that can take place between usage sessions before the 956 * next session is considered a new session. Must be non-negative. 957 * @param limitReachedCallbackIntent The {@link PendingIntent} that will be dispatched when the 958 * usage limit is exceeded by the group of apps. The 959 * delivered Intent will also contain the extras {@link 960 * #EXTRA_OBSERVER_ID}, {@link #EXTRA_TIME_LIMIT} and {@link 961 * #EXTRA_TIME_USED}. Cannot be null. 962 * @param sessionEndCallbackIntent The {@link PendingIntent} that will be dispatched when the 963 * session has ended after the usage limit has been exceeded. 964 * The session is considered at its end after the {@code 965 * observed} usage has stopped and an additional {@code 966 * sessionThresholdTime} has passed. The delivered Intent will 967 * also contain the extras {@link #EXTRA_OBSERVER_ID} and {@link 968 * #EXTRA_TIME_USED}. Can be null. 969 * @throws SecurityException if the caller doesn't have the OBSERVE_APP_USAGE permission and 970 * is not the profile owner of this user. 971 * @hide 972 */ 973 @SystemApi 974 @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE) registerUsageSessionObserver(int sessionObserverId, @NonNull String[] observedEntities, @NonNull Duration timeLimit, @NonNull Duration sessionThresholdTime, @NonNull PendingIntent limitReachedCallbackIntent, @Nullable PendingIntent sessionEndCallbackIntent)975 public void registerUsageSessionObserver(int sessionObserverId, 976 @NonNull String[] observedEntities, @NonNull Duration timeLimit, 977 @NonNull Duration sessionThresholdTime, 978 @NonNull PendingIntent limitReachedCallbackIntent, 979 @Nullable PendingIntent sessionEndCallbackIntent) { 980 try { 981 mService.registerUsageSessionObserver(sessionObserverId, observedEntities, 982 timeLimit.toMillis(), sessionThresholdTime.toMillis(), 983 limitReachedCallbackIntent, sessionEndCallbackIntent, 984 mContext.getOpPackageName()); 985 } catch (RemoteException e) { 986 throw e.rethrowFromSystemServer(); 987 } 988 } 989 990 /** 991 * Unregister the usage session observer specified by the {@code sessionObserverId}. This will 992 * only apply to any app session observer registered by this application. Unregistering an 993 * observer that was already unregistered or never registered will have no effect. 994 * 995 * @param sessionObserverId The id of the observer that was previously registered. 996 * @throws SecurityException if the caller doesn't have the OBSERVE_APP_USAGE permission and 997 * is not the profile owner of this user. 998 * @hide 999 */ 1000 @SystemApi 1001 @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE) unregisterUsageSessionObserver(int sessionObserverId)1002 public void unregisterUsageSessionObserver(int sessionObserverId) { 1003 try { 1004 mService.unregisterUsageSessionObserver(sessionObserverId, mContext.getOpPackageName()); 1005 } catch (RemoteException e) { 1006 throw e.rethrowFromSystemServer(); 1007 } 1008 } 1009 1010 /** 1011 * Register a usage limit observer that receives a callback on the provided intent when the 1012 * sum of usages of apps and tokens in the provided {@code observedEntities} array exceeds the 1013 * {@code timeLimit} specified. The structure of a token is a {@link String} with the reporting 1014 * package's name and a token that the calling app will use, separated by the forward slash 1015 * character. Example: com.reporting.package/5OM3*0P4QU3-7OK3N 1016 * <p> 1017 * Registering an {@code observerId} that was already registered will override the previous one. 1018 * No more than 1000 unique {@code observerId} may be registered by a single uid 1019 * at any one time. 1020 * A limit is not cleared when the usage time is exceeded. It needs to be unregistered via 1021 * {@link #unregisterAppUsageLimitObserver}. 1022 * <p> 1023 * Note: usage limits are not persisted in the system and are cleared on reboots. Callers 1024 * must reset any limits that they need on reboots. 1025 * <p> 1026 * This method is similar to {@link #registerAppUsageObserver}, but the usage limit set here 1027 * will be visible to the launcher so that it can report the limit to the user and how much 1028 * of it is remaining. 1029 * @see android.content.pm.LauncherApps#getAppUsageLimit 1030 * 1031 * @param observerId A unique id associated with the group of apps to be monitored. There can 1032 * be multiple groups with common packages and different time limits. 1033 * @param observedEntities The list of packages and token to observe for usage time. Cannot be 1034 * null and must include at least one package or token. 1035 * @param timeLimit The total time the set of apps can be in the foreground before the 1036 * {@code callbackIntent} is delivered. Must be at least one minute. 1037 * @param timeUsed The time that has already been used by the set of apps in 1038 * {@code observedEntities}. Note: a time used equal to or greater than 1039 * {@code timeLimit} can be set to indicate that the user has already exhausted 1040 * the limit for a group, in which case, the given {@code callbackIntent} will 1041 * be ignored. 1042 * @param callbackIntent The PendingIntent that will be dispatched when the usage limit is 1043 * exceeded by the group of apps. The delivered Intent will also contain 1044 * the extras {@link #EXTRA_OBSERVER_ID}, {@link #EXTRA_TIME_LIMIT} and 1045 * {@link #EXTRA_TIME_USED}. Cannot be {@code null} unless the observer is 1046 * being registered with a {@code timeUsed} equal to or greater than 1047 * {@code timeLimit}. 1048 * @throws SecurityException if the caller is neither the active supervision app nor does it 1049 * have both SUSPEND_APPS and OBSERVE_APP_USAGE permissions. 1050 * @hide 1051 */ 1052 @SystemApi 1053 @RequiresPermission(allOf = { 1054 android.Manifest.permission.SUSPEND_APPS, 1055 android.Manifest.permission.OBSERVE_APP_USAGE}) registerAppUsageLimitObserver(int observerId, @NonNull String[] observedEntities, @NonNull Duration timeLimit, @NonNull Duration timeUsed, @Nullable PendingIntent callbackIntent)1056 public void registerAppUsageLimitObserver(int observerId, @NonNull String[] observedEntities, 1057 @NonNull Duration timeLimit, @NonNull Duration timeUsed, 1058 @Nullable PendingIntent callbackIntent) { 1059 try { 1060 mService.registerAppUsageLimitObserver(observerId, observedEntities, 1061 timeLimit.toMillis(), timeUsed.toMillis(), callbackIntent, 1062 mContext.getOpPackageName()); 1063 } catch (RemoteException e) { 1064 throw e.rethrowFromSystemServer(); 1065 } 1066 } 1067 1068 /** 1069 * Unregister the app usage limit observer specified by the {@code observerId}. 1070 * This will only apply to any observer registered by this application. Unregistering 1071 * an observer that was already unregistered or never registered will have no effect. 1072 * 1073 * @param observerId The id of the observer that was previously registered. 1074 * @throws SecurityException if the caller is neither the active supervision app nor does it 1075 * have both SUSPEND_APPS and OBSERVE_APP_USAGE permissions. 1076 * @hide 1077 */ 1078 @SystemApi 1079 @RequiresPermission(allOf = { 1080 android.Manifest.permission.SUSPEND_APPS, 1081 android.Manifest.permission.OBSERVE_APP_USAGE}) unregisterAppUsageLimitObserver(int observerId)1082 public void unregisterAppUsageLimitObserver(int observerId) { 1083 try { 1084 mService.unregisterAppUsageLimitObserver(observerId, mContext.getOpPackageName()); 1085 } catch (RemoteException e) { 1086 throw e.rethrowFromSystemServer(); 1087 } 1088 } 1089 1090 /** 1091 * Reports user interaction with a given package in the given user. 1092 * 1093 * <p><em>This method is only for use by the system</em> 1094 * @hide 1095 */ reportUserInteraction(@onNull String packageName, int userId)1096 public void reportUserInteraction(@NonNull String packageName, int userId) { 1097 try { 1098 mService.reportUserInteraction(packageName, userId); 1099 } catch (RemoteException re) { 1100 throw re.rethrowFromSystemServer(); 1101 } 1102 } 1103 1104 /** 1105 * Report usage associated with a particular {@code token} has started. Tokens are app defined 1106 * strings used to represent usage of in-app features. Apps with the {@link 1107 * android.Manifest.permission#OBSERVE_APP_USAGE} permission can register time limit observers 1108 * to monitor the usage of a token. In app usage can only associated with an {@code activity} 1109 * and usage will be considered stopped if the activity stops or crashes. 1110 * @see #registerAppUsageObserver 1111 * @see #registerUsageSessionObserver 1112 * @see #registerAppUsageLimitObserver 1113 * 1114 * @param activity The activity {@code token} is associated with. 1115 * @param token The token to report usage against. 1116 * @hide 1117 */ 1118 @SystemApi reportUsageStart(@onNull Activity activity, @NonNull String token)1119 public void reportUsageStart(@NonNull Activity activity, @NonNull String token) { 1120 try { 1121 mService.reportUsageStart(activity.getActivityToken(), token, 1122 mContext.getOpPackageName()); 1123 } catch (RemoteException e) { 1124 throw e.rethrowFromSystemServer(); 1125 } 1126 } 1127 1128 /** 1129 * Report usage associated with a particular {@code token} had started some amount of time in 1130 * the past. Tokens are app defined strings used to represent usage of in-app features. Apps 1131 * with the {@link android.Manifest.permission#OBSERVE_APP_USAGE} permission can register time 1132 * limit observers to monitor the usage of a token. In app usage can only associated with an 1133 * {@code activity} and usage will be considered stopped if the activity stops or crashes. 1134 * @see #registerAppUsageObserver 1135 * @see #registerUsageSessionObserver 1136 * @see #registerAppUsageLimitObserver 1137 * 1138 * @param activity The activity {@code token} is associated with. 1139 * @param token The token to report usage against. 1140 * @param timeAgoMs How long ago the start of usage took place 1141 * @hide 1142 */ 1143 @SystemApi reportUsageStart(@onNull Activity activity, @NonNull String token, long timeAgoMs)1144 public void reportUsageStart(@NonNull Activity activity, @NonNull String token, 1145 long timeAgoMs) { 1146 try { 1147 mService.reportPastUsageStart(activity.getActivityToken(), token, timeAgoMs, 1148 mContext.getOpPackageName()); 1149 } catch (RemoteException e) { 1150 throw e.rethrowFromSystemServer(); 1151 } 1152 } 1153 1154 /** 1155 * Report the usage associated with a particular {@code token} has stopped. 1156 * 1157 * @param activity The activity {@code token} is associated with. 1158 * @param token The token to report usage against. 1159 * @hide 1160 */ 1161 @SystemApi reportUsageStop(@onNull Activity activity, @NonNull String token)1162 public void reportUsageStop(@NonNull Activity activity, @NonNull String token) { 1163 try { 1164 mService.reportUsageStop(activity.getActivityToken(), token, 1165 mContext.getOpPackageName()); 1166 } catch (RemoteException e) { 1167 throw e.rethrowFromSystemServer(); 1168 } 1169 } 1170 1171 /** 1172 * Get what App Usage Observers will consider the source of usage for an activity. Usage Source 1173 * is decided at boot and will not change until next boot. 1174 * @see #USAGE_SOURCE_TASK_ROOT_ACTIVITY 1175 * @see #USAGE_SOURCE_CURRENT_ACTIVITY 1176 * 1177 * @throws SecurityException if the caller doesn't have the OBSERVE_APP_USAGE permission and 1178 * is not the profile owner of this user. 1179 * @hide 1180 */ 1181 @SystemApi getUsageSource()1182 public @UsageSource int getUsageSource() { 1183 try { 1184 return mService.getUsageSource(); 1185 } catch (RemoteException e) { 1186 throw e.rethrowFromSystemServer(); 1187 } 1188 } 1189 1190 /** 1191 * Force the Usage Source be reread from global settings. 1192 * @hide 1193 */ 1194 @TestApi forceUsageSourceSettingRead()1195 public void forceUsageSourceSettingRead() { 1196 try { 1197 mService.forceUsageSourceSettingRead(); 1198 } catch (RemoteException e) { 1199 throw e.rethrowFromSystemServer(); 1200 } 1201 } 1202 1203 /** @hide */ reasonToString(int standbyReason)1204 public static String reasonToString(int standbyReason) { 1205 final int subReason = standbyReason & REASON_SUB_MASK; 1206 StringBuilder sb = new StringBuilder(); 1207 switch (standbyReason & REASON_MAIN_MASK) { 1208 case REASON_MAIN_DEFAULT: 1209 sb.append("d"); 1210 switch (subReason) { 1211 case REASON_SUB_DEFAULT_UNDEFINED: 1212 // Historically, undefined didn't have a string, so don't add anything here. 1213 break; 1214 case REASON_SUB_DEFAULT_APP_UPDATE: 1215 sb.append("-au"); 1216 break; 1217 case REASON_SUB_DEFAULT_APP_RESTORED: 1218 sb.append("-ar"); 1219 break; 1220 } 1221 break; 1222 case REASON_MAIN_FORCED_BY_SYSTEM: 1223 sb.append("s"); 1224 if (subReason > 0) { 1225 sb.append("-").append(Integer.toBinaryString(subReason)); 1226 } 1227 break; 1228 case REASON_MAIN_FORCED_BY_USER: 1229 sb.append("f"); 1230 if (subReason > 0) { 1231 sb.append("-").append(Integer.toBinaryString(subReason)); 1232 } 1233 break; 1234 case REASON_MAIN_PREDICTED: 1235 sb.append("p"); 1236 switch (subReason) { 1237 case REASON_SUB_PREDICTED_RESTORED: 1238 sb.append("-r"); 1239 break; 1240 } 1241 break; 1242 case REASON_MAIN_TIMEOUT: 1243 sb.append("t"); 1244 break; 1245 case REASON_MAIN_USAGE: 1246 sb.append("u"); 1247 switch (subReason) { 1248 case REASON_SUB_USAGE_SYSTEM_INTERACTION: 1249 sb.append("-si"); 1250 break; 1251 case REASON_SUB_USAGE_NOTIFICATION_SEEN: 1252 sb.append("-ns"); 1253 break; 1254 case REASON_SUB_USAGE_USER_INTERACTION: 1255 sb.append("-ui"); 1256 break; 1257 case REASON_SUB_USAGE_MOVE_TO_FOREGROUND: 1258 sb.append("-mf"); 1259 break; 1260 case REASON_SUB_USAGE_MOVE_TO_BACKGROUND: 1261 sb.append("-mb"); 1262 break; 1263 case REASON_SUB_USAGE_SYSTEM_UPDATE: 1264 sb.append("-su"); 1265 break; 1266 case REASON_SUB_USAGE_ACTIVE_TIMEOUT: 1267 sb.append("-at"); 1268 break; 1269 case REASON_SUB_USAGE_SYNC_ADAPTER: 1270 sb.append("-sa"); 1271 break; 1272 case REASON_SUB_USAGE_SLICE_PINNED: 1273 sb.append("-lp"); 1274 break; 1275 case REASON_SUB_USAGE_SLICE_PINNED_PRIV: 1276 sb.append("-lv"); 1277 break; 1278 case REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_NON_DOZE: 1279 sb.append("-en"); 1280 break; 1281 case REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_DOZE: 1282 sb.append("-ed"); 1283 break; 1284 case REASON_SUB_USAGE_EXEMPTED_SYNC_START: 1285 sb.append("-es"); 1286 break; 1287 case REASON_SUB_USAGE_UNEXEMPTED_SYNC_SCHEDULED: 1288 sb.append("-uss"); 1289 break; 1290 case REASON_SUB_USAGE_FOREGROUND_SERVICE_START: 1291 sb.append("-fss"); 1292 break; 1293 } 1294 break; 1295 } 1296 return sb.toString(); 1297 } 1298 1299 /** @hide */ usageSourceToString(int usageSource)1300 public static String usageSourceToString(int usageSource) { 1301 switch (usageSource) { 1302 case USAGE_SOURCE_TASK_ROOT_ACTIVITY: 1303 return "TASK_ROOT_ACTIVITY"; 1304 case USAGE_SOURCE_CURRENT_ACTIVITY: 1305 return "CURRENT_ACTIVITY"; 1306 default: 1307 StringBuilder sb = new StringBuilder(); 1308 sb.append("UNKNOWN("); 1309 sb.append(usageSource); 1310 sb.append(")"); 1311 return sb.toString(); 1312 } 1313 } 1314 1315 /** @hide */ standbyBucketToString(int standbyBucket)1316 public static String standbyBucketToString(int standbyBucket) { 1317 switch (standbyBucket) { 1318 case STANDBY_BUCKET_EXEMPTED: 1319 return "EXEMPTED"; 1320 case STANDBY_BUCKET_ACTIVE: 1321 return "ACTIVE"; 1322 case STANDBY_BUCKET_WORKING_SET: 1323 return "WORKING_SET"; 1324 case STANDBY_BUCKET_FREQUENT: 1325 return "FREQUENT"; 1326 case STANDBY_BUCKET_RARE: 1327 return "RARE"; 1328 case STANDBY_BUCKET_RESTRICTED: 1329 return "RESTRICTED"; 1330 case STANDBY_BUCKET_NEVER: 1331 return "NEVER"; 1332 default: 1333 return String.valueOf(standbyBucket); 1334 } 1335 } 1336 1337 /** 1338 * {@hide} 1339 * Temporarily allowlist the specified app for a short duration. This is to allow an app 1340 * receiving a high priority message to be able to access the network and acquire wakelocks 1341 * even if the device is in power-save mode or the app is currently considered inactive. 1342 * @param packageName The package name of the app to allowlist. 1343 * @param duration Duration to allowlist the app for, in milliseconds. It is recommended that 1344 * this be limited to 10s of seconds. Requested duration will be clamped to a few minutes. 1345 * @param user The user for whom the package should be allowlisted. Passing in a user that is 1346 * not the same as the caller's process will require the INTERACT_ACROSS_USERS permission. 1347 * @see #isAppInactive(String) 1348 * 1349 * @deprecated Use 1350 * {@link android.os.PowerWhitelistManager#whitelistAppTemporarily(String, long)} instead. 1351 */ 1352 @SystemApi 1353 @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST) 1354 @Deprecated whitelistAppTemporarily(String packageName, long duration, UserHandle user)1355 public void whitelistAppTemporarily(String packageName, long duration, UserHandle user) { 1356 mContext.getSystemService(PowerWhitelistManager.class) 1357 .whitelistAppTemporarily(packageName, duration); 1358 } 1359 1360 /** 1361 * Inform usage stats that the carrier privileged apps access rules have changed. 1362 * <p> The caller must have {@link android.Manifest.permission#BIND_CARRIER_SERVICES} </p> 1363 * @hide 1364 */ 1365 @SystemApi 1366 @RequiresPermission(android.Manifest.permission.BIND_CARRIER_SERVICES) onCarrierPrivilegedAppsChanged()1367 public void onCarrierPrivilegedAppsChanged() { 1368 try { 1369 mService.onCarrierPrivilegedAppsChanged(); 1370 } catch (RemoteException re) { 1371 throw re.rethrowFromSystemServer(); 1372 } 1373 } 1374 1375 /** 1376 * Reports a Chooser action to the UsageStatsManager. 1377 * 1378 * @param packageName The package name of the app that is selected. 1379 * @param userId The user id of who makes the selection. 1380 * @param contentType The type of the content, e.g., Image, Video, App. 1381 * @param annotations The annotations of the content, e.g., Game, Selfie. 1382 * @param action The action type of Intent that invokes ChooserActivity. 1383 * {@link UsageEvents} 1384 * @hide 1385 */ reportChooserSelection(String packageName, int userId, String contentType, String[] annotations, String action)1386 public void reportChooserSelection(String packageName, int userId, String contentType, 1387 String[] annotations, String action) { 1388 try { 1389 mService.reportChooserSelection(packageName, userId, contentType, annotations, action); 1390 } catch (RemoteException re) { 1391 } 1392 } 1393 1394 /** 1395 * Get the last time a package is used by any users including explicit user interaction and 1396 * component usage, measured in milliseconds since the epoch and truncated to the boundary of 1397 * last day before the exact time. For packages that are never used, the time will be the epoch. 1398 * <p> Note that this usage stats is user-agnostic. </p> 1399 * <p> 1400 * Also note that component usage is only reported for component bindings (e.g. broadcast 1401 * receiver, service, content provider) and only when such a binding would cause an app to leave 1402 * the stopped state. 1403 * See {@link UsageEvents.Event.USER_INTERACTION}, {@link UsageEvents.Event.APP_COMPONENT_USED}. 1404 * </p> 1405 * 1406 * @param packageName The name of the package to be queried. 1407 * @return last time the queried package is used since the epoch. 1408 * @hide 1409 */ 1410 @SystemApi 1411 @RequiresPermission(allOf = { 1412 android.Manifest.permission.INTERACT_ACROSS_USERS, 1413 android.Manifest.permission.PACKAGE_USAGE_STATS}) getLastTimeAnyComponentUsed(@onNull String packageName)1414 public long getLastTimeAnyComponentUsed(@NonNull String packageName) { 1415 try { 1416 return mService.getLastTimeAnyComponentUsed(packageName, mContext.getOpPackageName()); 1417 } catch (RemoteException re) { 1418 throw re.rethrowFromSystemServer(); 1419 } 1420 } 1421 1422 /** 1423 * Returns the broadcast response stats since the last boot corresponding to 1424 * {@code packageName} and {@code id}. 1425 * 1426 * <p> Broadcast response stats will include the aggregated data of what actions an app took 1427 * upon receiving a broadcast. This data will consider the broadcasts that the caller sent to 1428 * {@code packageName} and explicitly requested to record the response events using 1429 * {@link BroadcastOptions#recordResponseEventWhileInBackground(long)}. 1430 * 1431 * <p> The returned list could one or more {@link BroadcastResponseStats} objects or be empty 1432 * depending on the {@code packageName} and {@code id} and whether there is any data 1433 * corresponding to these. If the {@code packageName} is not {@code null} and {@code id} is 1434 * {@code > 0}, then the returned list would contain at most one {@link BroadcastResponseStats} 1435 * object. Otherwise, the returned list could contain more than one 1436 * {@link BroadcastResponseStats} object in no particular order. 1437 * 1438 * <p> Note: It is possible that same {@code id} was used for broadcasts sent to different 1439 * packages. So, callers can query the data corresponding to 1440 * all broadcasts with a particular {@code id} by passing {@code packageName} as {@code null}. 1441 * 1442 * @param packageName The name of the package that the caller wants to query for 1443 * or {@code null} to indicate that data corresponding to all packages 1444 * should be returned. 1445 * @param id The ID corresponding to the broadcasts that the caller wants to query for, or 1446 * {@code 0} to indicate that data corresponding to all IDs should be returned. 1447 * This is the ID the caller specifies when requesting a broadcast response event 1448 * to be recorded using 1449 * {@link BroadcastOptions#recordResponseEventWhileInBackground(long)}. 1450 * 1451 * @return the list of broadcast response stats corresponding to {@code packageName} 1452 * and {@code id}. 1453 * 1454 * @see #clearBroadcastResponseStats(String, long) 1455 * @hide 1456 */ 1457 @SystemApi 1458 @RequiresPermission(android.Manifest.permission.ACCESS_BROADCAST_RESPONSE_STATS) 1459 @UserHandleAware 1460 @NonNull queryBroadcastResponseStats( @ullable String packageName, @IntRange(from = 0) long id)1461 public List<BroadcastResponseStats> queryBroadcastResponseStats( 1462 @Nullable String packageName, @IntRange(from = 0) long id) { 1463 try { 1464 return mService.queryBroadcastResponseStats(packageName, id, 1465 mContext.getOpPackageName(), mContext.getUserId()).getList(); 1466 } catch (RemoteException re) { 1467 throw re.rethrowFromSystemServer(); 1468 } 1469 } 1470 1471 /** 1472 * Clears the broadcast response stats corresponding to {@code packageName} and {@code id}. 1473 * 1474 * <p> When a caller uses this API, stats related to the events occurring till that point will 1475 * be cleared and subsequent calls to {@link #queryBroadcastResponseStats(String, long)} will 1476 * return stats related to events occurring after this. 1477 * 1478 * @param packageName The name of the package that the caller wants to clear the data for or 1479 * {@code null} to indicate that data corresponding to all packages should 1480 * be cleared. 1481 * @param id The ID corresponding to the broadcasts that the caller wants to clear the data 1482 * for, or {code 0} to indicate that data corresponding to all IDs should be deleted. 1483 * This is the ID the caller specifies when requesting a broadcast response event 1484 * to be recorded using 1485 * {@link BroadcastOptions#recordResponseEventWhileInBackground(long)}. 1486 * 1487 * @see #queryBroadcastResponseStats(String, long) 1488 * @hide 1489 */ 1490 @SystemApi 1491 @RequiresPermission(android.Manifest.permission.ACCESS_BROADCAST_RESPONSE_STATS) 1492 @UserHandleAware clearBroadcastResponseStats(@ullable String packageName, @IntRange(from = 0) long id)1493 public void clearBroadcastResponseStats(@Nullable String packageName, 1494 @IntRange(from = 0) long id) { 1495 try { 1496 mService.clearBroadcastResponseStats(packageName, id, 1497 mContext.getOpPackageName(), mContext.getUserId()); 1498 } catch (RemoteException re) { 1499 throw re.rethrowFromSystemServer(); 1500 } 1501 } 1502 1503 /** 1504 * Clears the broadcast events that were sent by the caller uid. 1505 * 1506 * @hide 1507 */ 1508 @RequiresPermission(android.Manifest.permission.ACCESS_BROADCAST_RESPONSE_STATS) 1509 @UserHandleAware clearBroadcastEvents()1510 public void clearBroadcastEvents() { 1511 try { 1512 mService.clearBroadcastEvents(mContext.getOpPackageName(), mContext.getUserId()); 1513 } catch (RemoteException re) { 1514 throw re.rethrowFromSystemServer(); 1515 } 1516 } 1517 1518 /** @hide */ 1519 @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG) 1520 @Nullable getAppStandbyConstant(@onNull String key)1521 public String getAppStandbyConstant(@NonNull String key) { 1522 try { 1523 return mService.getAppStandbyConstant(key); 1524 } catch (RemoteException re) { 1525 throw re.rethrowFromSystemServer(); 1526 } 1527 } 1528 } 1529