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 app standby bucket feature is enabled. 646 * @hide 647 */ 648 @TestApi isAppStandbyEnabled()649 public boolean isAppStandbyEnabled() { 650 try { 651 return mService.isAppStandbyEnabled(); 652 } catch (RemoteException e) { 653 throw e.rethrowFromSystemServer(); 654 } 655 } 656 657 /** 658 * Returns whether the specified app is currently considered inactive. This will be true if the 659 * app hasn't been used directly or indirectly for a period of time defined by the system. This 660 * could be of the order of several hours or days. Apps are not considered inactive when the 661 * device is charging. 662 * <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} to query the 663 * inactive state of other apps</p> 664 * 665 * @param packageName The package name of the app to query 666 * @return whether the app is currently considered inactive or false if querying another app 667 * without {@link android.Manifest.permission#PACKAGE_USAGE_STATS} 668 */ isAppInactive(String packageName)669 public boolean isAppInactive(String packageName) { 670 try { 671 return mService.isAppInactive(packageName, mContext.getUserId(), 672 mContext.getOpPackageName()); 673 } catch (RemoteException e) { 674 // fall through and return default 675 } 676 return false; 677 } 678 679 /** 680 * {@hide} 681 */ setAppInactive(String packageName, boolean inactive)682 public void setAppInactive(String packageName, boolean inactive) { 683 try { 684 mService.setAppInactive(packageName, inactive, mContext.getUserId()); 685 } catch (RemoteException e) { 686 // fall through 687 } 688 } 689 690 /** 691 * Returns the current standby bucket of the calling app. The system determines the standby 692 * state of the app based on app usage patterns. Standby buckets determine how much an app will 693 * be restricted from running background tasks such as jobs and alarms. 694 * <p>Restrictions increase progressively from {@link #STANDBY_BUCKET_ACTIVE} to 695 * {@link #STANDBY_BUCKET_RESTRICTED}, with {@link #STANDBY_BUCKET_ACTIVE} being the least 696 * restrictive. The battery level of the device might also affect the restrictions. 697 * <p>Apps in buckets ≤ {@link #STANDBY_BUCKET_ACTIVE} have no standby restrictions imposed. 698 * Apps in buckets > {@link #STANDBY_BUCKET_FREQUENT} may have network access restricted when 699 * running in the background. 700 * <p>The standby state of an app can change at any time either due to a user interaction or a 701 * system interaction or some algorithm determining that the app can be restricted for a period 702 * of time before the user has a need for it. 703 * <p>You can also query the recent history of standby bucket changes by calling 704 * {@link #queryEventsForSelf(long, long)} and searching for 705 * {@link UsageEvents.Event#STANDBY_BUCKET_CHANGED}. 706 * 707 * @return the current standby bucket of the calling app. One of STANDBY_BUCKET_* constants. 708 */ getAppStandbyBucket()709 public @StandbyBuckets int getAppStandbyBucket() { 710 try { 711 return mService.getAppStandbyBucket(mContext.getOpPackageName(), 712 mContext.getOpPackageName(), 713 mContext.getUserId()); 714 } catch (RemoteException e) { 715 } 716 return STANDBY_BUCKET_ACTIVE; 717 } 718 719 /** 720 * {@hide} 721 * Returns the current standby bucket of the specified app. The caller must hold the permission 722 * android.permission.PACKAGE_USAGE_STATS. 723 * @param packageName the package for which to fetch the current standby bucket. 724 */ 725 @SystemApi 726 @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) getAppStandbyBucket(String packageName)727 public @StandbyBuckets int getAppStandbyBucket(String packageName) { 728 try { 729 return mService.getAppStandbyBucket(packageName, mContext.getOpPackageName(), 730 mContext.getUserId()); 731 } catch (RemoteException e) { 732 } 733 return STANDBY_BUCKET_ACTIVE; 734 } 735 736 /** 737 * {@hide} 738 * Changes an app's standby bucket to the provided value. The caller can only set the standby 739 * bucket for a different app than itself. The caller will not be able to change an app's 740 * standby bucket if that app is in the {@link #STANDBY_BUCKET_RESTRICTED} bucket. 741 * @param packageName the package name of the app to set the bucket for. A SecurityException 742 * will be thrown if the package name is that of the caller. 743 * @param bucket the standby bucket to set it to, which should be one of STANDBY_BUCKET_*. 744 * Setting a standby bucket outside of the range of STANDBY_BUCKET_ACTIVE to 745 * STANDBY_BUCKET_NEVER will result in a SecurityException. 746 */ 747 @SystemApi 748 @RequiresPermission(android.Manifest.permission.CHANGE_APP_IDLE_STATE) setAppStandbyBucket(String packageName, @StandbyBuckets int bucket)749 public void setAppStandbyBucket(String packageName, @StandbyBuckets int bucket) { 750 try { 751 mService.setAppStandbyBucket(packageName, bucket, mContext.getUserId()); 752 } catch (RemoteException e) { 753 throw e.rethrowFromSystemServer(); 754 } 755 } 756 757 /** 758 * {@hide} 759 * Returns the current standby bucket of every app that has a bucket assigned to it. 760 * The caller must hold the permission android.permission.PACKAGE_USAGE_STATS. The key of the 761 * returned Map is the package name and the value is the bucket assigned to the package. 762 * @see #getAppStandbyBucket() 763 */ 764 @SystemApi 765 @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) getAppStandbyBuckets()766 public Map<String, Integer> getAppStandbyBuckets() { 767 try { 768 final ParceledListSlice<AppStandbyInfo> slice = mService.getAppStandbyBuckets( 769 mContext.getOpPackageName(), mContext.getUserId()); 770 final List<AppStandbyInfo> bucketList = slice.getList(); 771 final ArrayMap<String, Integer> bucketMap = new ArrayMap<>(); 772 final int n = bucketList.size(); 773 for (int i = 0; i < n; i++) { 774 final AppStandbyInfo bucketInfo = bucketList.get(i); 775 bucketMap.put(bucketInfo.mPackageName, bucketInfo.mStandbyBucket); 776 } 777 return bucketMap; 778 } catch (RemoteException e) { 779 throw e.rethrowFromSystemServer(); 780 } 781 } 782 783 /** 784 * {@hide} 785 * Changes the app standby bucket for multiple apps at once. The Map is keyed by the package 786 * name and the value is one of STANDBY_BUCKET_*. The caller will not be able to change an 787 * app's standby bucket if that app is in the {@link #STANDBY_BUCKET_RESTRICTED} bucket. 788 * @param appBuckets a map of package name to bucket value. 789 */ 790 @SystemApi 791 @RequiresPermission(android.Manifest.permission.CHANGE_APP_IDLE_STATE) setAppStandbyBuckets(Map<String, Integer> appBuckets)792 public void setAppStandbyBuckets(Map<String, Integer> appBuckets) { 793 if (appBuckets == null) { 794 return; 795 } 796 final List<AppStandbyInfo> bucketInfoList = new ArrayList<>(appBuckets.size()); 797 for (Map.Entry<String, Integer> bucketEntry : appBuckets.entrySet()) { 798 bucketInfoList.add(new AppStandbyInfo(bucketEntry.getKey(), bucketEntry.getValue())); 799 } 800 final ParceledListSlice<AppStandbyInfo> slice = new ParceledListSlice<>(bucketInfoList); 801 try { 802 mService.setAppStandbyBuckets(slice, mContext.getUserId()); 803 } catch (RemoteException e) { 804 throw e.rethrowFromSystemServer(); 805 } 806 } 807 808 /** 809 * Return the lowest bucket this app can ever enter. 810 * 811 * @param packageName the package for which to fetch the minimum allowed standby bucket. 812 * {@hide} 813 */ 814 @StandbyBuckets 815 @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) getAppMinStandbyBucket(String packageName)816 public int getAppMinStandbyBucket(String packageName) { 817 try { 818 return mService.getAppMinStandbyBucket(packageName, mContext.getOpPackageName(), 819 mContext.getUserId()); 820 } catch (RemoteException e) { 821 throw e.rethrowFromSystemServer(); 822 } 823 } 824 825 /** 826 * Changes an app's estimated launch time. An app is considered "launched" when a user opens 827 * one of its {@link android.app.Activity Activities}. The provided time is persisted across 828 * reboots and is used unless 1) the time is more than a week in the future and the platform 829 * thinks the app will be launched sooner, 2) the estimated time has passed. Passing in 830 * {@link Long#MAX_VALUE} effectively clears the previously set launch time for the app. 831 * 832 * @param packageName The package name of the app to set the bucket for. 833 * @param estimatedLaunchTimeMillis The next time the app is expected to be launched. Units are 834 * in milliseconds since epoch (the same as 835 * {@link System#currentTimeMillis()}). 836 * @hide 837 */ 838 @SystemApi 839 @RequiresPermission(android.Manifest.permission.CHANGE_APP_LAUNCH_TIME_ESTIMATE) setEstimatedLaunchTimeMillis(@onNull String packageName, @CurrentTimeMillisLong long estimatedLaunchTimeMillis)840 public void setEstimatedLaunchTimeMillis(@NonNull String packageName, 841 @CurrentTimeMillisLong long estimatedLaunchTimeMillis) { 842 if (packageName == null) { 843 throw new NullPointerException("package name cannot be null"); 844 } 845 if (estimatedLaunchTimeMillis <= 0) { 846 throw new IllegalArgumentException("estimated launch time must be positive"); 847 } 848 try { 849 mService.setEstimatedLaunchTime( 850 packageName, estimatedLaunchTimeMillis, mContext.getUserId()); 851 } catch (RemoteException e) { 852 throw e.rethrowFromSystemServer(); 853 } 854 } 855 856 /** 857 * Changes the estimated launch times for multiple apps at once. The map is keyed by the 858 * package name and the value is the estimated launch time. 859 * 860 * @param estimatedLaunchTimesMillis A map of package name to estimated launch time. 861 * @see #setEstimatedLaunchTimeMillis(String, long) 862 * @hide 863 */ 864 @SystemApi 865 @RequiresPermission(android.Manifest.permission.CHANGE_APP_LAUNCH_TIME_ESTIMATE) setEstimatedLaunchTimesMillis( @onNull Map<String, Long> estimatedLaunchTimesMillis)866 public void setEstimatedLaunchTimesMillis( 867 @NonNull Map<String, Long> estimatedLaunchTimesMillis) { 868 if (estimatedLaunchTimesMillis == null) { 869 throw new NullPointerException("estimatedLaunchTimesMillis cannot be null"); 870 } 871 final List<AppLaunchEstimateInfo> estimateList = 872 new ArrayList<>(estimatedLaunchTimesMillis.size()); 873 for (Map.Entry<String, Long> estimateEntry : estimatedLaunchTimesMillis.entrySet()) { 874 final String pkgName = estimateEntry.getKey(); 875 if (pkgName == null) { 876 throw new NullPointerException("package name cannot be null"); 877 } 878 final Long estimatedLaunchTime = estimateEntry.getValue(); 879 if (estimatedLaunchTime == null || estimatedLaunchTime <= 0) { 880 throw new IllegalArgumentException("estimated launch time must be positive"); 881 } 882 estimateList.add(new AppLaunchEstimateInfo(pkgName, estimatedLaunchTime)); 883 } 884 final ParceledListSlice<AppLaunchEstimateInfo> slice = 885 new ParceledListSlice<>(estimateList); 886 try { 887 mService.setEstimatedLaunchTimes(slice, mContext.getUserId()); 888 } catch (RemoteException e) { 889 throw e.rethrowFromSystemServer(); 890 } 891 } 892 893 /** 894 * @hide 895 * Register an app usage limit observer that receives a callback on the provided intent when 896 * the sum of usages of apps and tokens in the {@code observed} array exceeds the 897 * {@code timeLimit} specified. The structure of a token is a String with the reporting 898 * package's name and a token the reporting app will use, separated by the forward slash 899 * character. Example: com.reporting.package/5OM3*0P4QU3-7OK3N 900 * The observer will automatically be unregistered when the time limit is reached and the 901 * intent is delivered. Registering an {@code observerId} that was already registered will 902 * override the previous one. No more than 1000 unique {@code observerId} may be registered by 903 * a single uid at any one time. 904 * @param observerId A unique id associated with the group of apps to be monitored. There can 905 * be multiple groups with common packages and different time limits. 906 * @param observedEntities The list of packages and token to observe for usage time. Cannot be 907 * null and must include at least one package or token. 908 * @param timeLimit The total time the set of apps can be in the foreground before the 909 * callbackIntent is delivered. Must be at least one minute. 910 * @param timeUnit The unit for time specified in {@code timeLimit}. Cannot be null. 911 * @param callbackIntent The PendingIntent that will be dispatched when the usage limit is 912 * exceeded by the group of apps. The delivered Intent will also contain 913 * the extras {@link #EXTRA_OBSERVER_ID}, {@link #EXTRA_TIME_LIMIT} and 914 * {@link #EXTRA_TIME_USED}. Cannot be null. 915 * @throws SecurityException if the caller doesn't have the OBSERVE_APP_USAGE permission and 916 * is not the profile owner of this user. 917 */ 918 @SystemApi 919 @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE) registerAppUsageObserver(int observerId, @NonNull String[] observedEntities, long timeLimit, @NonNull TimeUnit timeUnit, @NonNull PendingIntent callbackIntent)920 public void registerAppUsageObserver(int observerId, @NonNull String[] observedEntities, 921 long timeLimit, @NonNull TimeUnit timeUnit, @NonNull PendingIntent callbackIntent) { 922 try { 923 mService.registerAppUsageObserver(observerId, observedEntities, 924 timeUnit.toMillis(timeLimit), callbackIntent, mContext.getOpPackageName()); 925 } catch (RemoteException e) { 926 throw e.rethrowFromSystemServer(); 927 } 928 } 929 930 /** 931 * @hide 932 * Unregister the app usage observer specified by the {@code observerId}. This will only apply 933 * to any observer registered by this application. Unregistering an observer that was already 934 * unregistered or never registered will have no effect. 935 * @param observerId The id of the observer that was previously registered. 936 * @throws SecurityException if the caller doesn't have the OBSERVE_APP_USAGE permission and is 937 * not the profile owner of this user. 938 */ 939 @SystemApi 940 @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE) unregisterAppUsageObserver(int observerId)941 public void unregisterAppUsageObserver(int observerId) { 942 try { 943 mService.unregisterAppUsageObserver(observerId, mContext.getOpPackageName()); 944 } catch (RemoteException e) { 945 throw e.rethrowFromSystemServer(); 946 } 947 } 948 949 /** 950 * Register a usage session observer that receives a callback on the provided {@code 951 * limitReachedCallbackIntent} when the sum of usages of apps and tokens in the {@code 952 * observed} array exceeds the {@code timeLimit} specified within a usage session. The 953 * structure of a token is a String with the reporting packages' name and a token the 954 * reporting app will use, separated by the forward slash character. 955 * Example: com.reporting.package/5OM3*0P4QU3-7OK3N 956 * After the {@code timeLimit} has been reached, the usage session observer will receive a 957 * callback on the provided {@code sessionEndCallbackIntent} when the usage session ends. 958 * Registering another session observer against a {@code sessionObserverId} that has already 959 * been registered will override the previous session observer. 960 * 961 * @param sessionObserverId A unique id associated with the group of apps to be 962 * monitored. There can be multiple groups with common 963 * packages and different time limits. 964 * @param observedEntities The list of packages and token to observe for usage time. Cannot be 965 * null and must include at least one package or token. 966 * @param timeLimit The total time the set of apps can be used continuously before the {@code 967 * limitReachedCallbackIntent} is delivered. Must be at least one minute. 968 * @param sessionThresholdTime The time that can take place between usage sessions before the 969 * next session is considered a new session. Must be non-negative. 970 * @param limitReachedCallbackIntent The {@link PendingIntent} that will be dispatched when the 971 * usage limit is exceeded by the group of apps. The 972 * delivered Intent will also contain the extras {@link 973 * #EXTRA_OBSERVER_ID}, {@link #EXTRA_TIME_LIMIT} and {@link 974 * #EXTRA_TIME_USED}. Cannot be null. 975 * @param sessionEndCallbackIntent The {@link PendingIntent} that will be dispatched when the 976 * session has ended after the usage limit has been exceeded. 977 * The session is considered at its end after the {@code 978 * observed} usage has stopped and an additional {@code 979 * sessionThresholdTime} has passed. The delivered Intent will 980 * also contain the extras {@link #EXTRA_OBSERVER_ID} and {@link 981 * #EXTRA_TIME_USED}. Can be null. 982 * @throws SecurityException if the caller doesn't have the OBSERVE_APP_USAGE permission and 983 * is not the profile owner of this user. 984 * @hide 985 */ 986 @SystemApi 987 @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)988 public void registerUsageSessionObserver(int sessionObserverId, 989 @NonNull String[] observedEntities, @NonNull Duration timeLimit, 990 @NonNull Duration sessionThresholdTime, 991 @NonNull PendingIntent limitReachedCallbackIntent, 992 @Nullable PendingIntent sessionEndCallbackIntent) { 993 try { 994 mService.registerUsageSessionObserver(sessionObserverId, observedEntities, 995 timeLimit.toMillis(), sessionThresholdTime.toMillis(), 996 limitReachedCallbackIntent, sessionEndCallbackIntent, 997 mContext.getOpPackageName()); 998 } catch (RemoteException e) { 999 throw e.rethrowFromSystemServer(); 1000 } 1001 } 1002 1003 /** 1004 * Unregister the usage session observer specified by the {@code sessionObserverId}. This will 1005 * only apply to any app session observer registered by this application. Unregistering an 1006 * observer that was already unregistered or never registered will have no effect. 1007 * 1008 * @param sessionObserverId The id of the observer that was previously registered. 1009 * @throws SecurityException if the caller doesn't have the OBSERVE_APP_USAGE permission and 1010 * is not the profile owner of this user. 1011 * @hide 1012 */ 1013 @SystemApi 1014 @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE) unregisterUsageSessionObserver(int sessionObserverId)1015 public void unregisterUsageSessionObserver(int sessionObserverId) { 1016 try { 1017 mService.unregisterUsageSessionObserver(sessionObserverId, mContext.getOpPackageName()); 1018 } catch (RemoteException e) { 1019 throw e.rethrowFromSystemServer(); 1020 } 1021 } 1022 1023 /** 1024 * Register a usage limit observer that receives a callback on the provided intent when the 1025 * sum of usages of apps and tokens in the provided {@code observedEntities} array exceeds the 1026 * {@code timeLimit} specified. The structure of a token is a {@link String} with the reporting 1027 * package's name and a token that the calling app will use, separated by the forward slash 1028 * character. Example: com.reporting.package/5OM3*0P4QU3-7OK3N 1029 * <p> 1030 * Registering an {@code observerId} that was already registered will override the previous one. 1031 * No more than 1000 unique {@code observerId} may be registered by a single uid 1032 * at any one time. 1033 * A limit is not cleared when the usage time is exceeded. It needs to be unregistered via 1034 * {@link #unregisterAppUsageLimitObserver}. 1035 * <p> 1036 * Note: usage limits are not persisted in the system and are cleared on reboots. Callers 1037 * must reset any limits that they need on reboots. 1038 * <p> 1039 * This method is similar to {@link #registerAppUsageObserver}, but the usage limit set here 1040 * will be visible to the launcher so that it can report the limit to the user and how much 1041 * of it is remaining. 1042 * @see android.content.pm.LauncherApps#getAppUsageLimit 1043 * 1044 * @param observerId A unique id associated with the group of apps to be monitored. There can 1045 * be multiple groups with common packages and different time limits. 1046 * @param observedEntities The list of packages and token to observe for usage time. Cannot be 1047 * null and must include at least one package or token. 1048 * @param timeLimit The total time the set of apps can be in the foreground before the 1049 * {@code callbackIntent} is delivered. Must be at least one minute. 1050 * @param timeUsed The time that has already been used by the set of apps in 1051 * {@code observedEntities}. Note: a time used equal to or greater than 1052 * {@code timeLimit} can be set to indicate that the user has already exhausted 1053 * the limit for a group, in which case, the given {@code callbackIntent} will 1054 * be ignored. 1055 * @param callbackIntent The PendingIntent that will be dispatched when the usage limit is 1056 * exceeded by the group of apps. The delivered Intent will also contain 1057 * the extras {@link #EXTRA_OBSERVER_ID}, {@link #EXTRA_TIME_LIMIT} and 1058 * {@link #EXTRA_TIME_USED}. Cannot be {@code null} unless the observer is 1059 * being registered with a {@code timeUsed} equal to or greater than 1060 * {@code timeLimit}. 1061 * @throws SecurityException if the caller is neither the active supervision app nor does it 1062 * have both SUSPEND_APPS and OBSERVE_APP_USAGE permissions. 1063 * @hide 1064 */ 1065 @SystemApi 1066 @RequiresPermission(allOf = { 1067 android.Manifest.permission.SUSPEND_APPS, 1068 android.Manifest.permission.OBSERVE_APP_USAGE}) registerAppUsageLimitObserver(int observerId, @NonNull String[] observedEntities, @NonNull Duration timeLimit, @NonNull Duration timeUsed, @Nullable PendingIntent callbackIntent)1069 public void registerAppUsageLimitObserver(int observerId, @NonNull String[] observedEntities, 1070 @NonNull Duration timeLimit, @NonNull Duration timeUsed, 1071 @Nullable PendingIntent callbackIntent) { 1072 try { 1073 mService.registerAppUsageLimitObserver(observerId, observedEntities, 1074 timeLimit.toMillis(), timeUsed.toMillis(), callbackIntent, 1075 mContext.getOpPackageName()); 1076 } catch (RemoteException e) { 1077 throw e.rethrowFromSystemServer(); 1078 } 1079 } 1080 1081 /** 1082 * Unregister the app usage limit observer specified by the {@code observerId}. 1083 * This will only apply to any observer registered by this application. Unregistering 1084 * an observer that was already unregistered or never registered will have no effect. 1085 * 1086 * @param observerId The id of the observer that was previously registered. 1087 * @throws SecurityException if the caller is neither the active supervision app nor does it 1088 * have both SUSPEND_APPS and OBSERVE_APP_USAGE permissions. 1089 * @hide 1090 */ 1091 @SystemApi 1092 @RequiresPermission(allOf = { 1093 android.Manifest.permission.SUSPEND_APPS, 1094 android.Manifest.permission.OBSERVE_APP_USAGE}) unregisterAppUsageLimitObserver(int observerId)1095 public void unregisterAppUsageLimitObserver(int observerId) { 1096 try { 1097 mService.unregisterAppUsageLimitObserver(observerId, mContext.getOpPackageName()); 1098 } catch (RemoteException e) { 1099 throw e.rethrowFromSystemServer(); 1100 } 1101 } 1102 1103 /** 1104 * Reports user interaction with a given package in the given user. 1105 * 1106 * <p><em>This method is only for use by the system</em> 1107 * @hide 1108 */ reportUserInteraction(@onNull String packageName, int userId)1109 public void reportUserInteraction(@NonNull String packageName, int userId) { 1110 try { 1111 mService.reportUserInteraction(packageName, userId); 1112 } catch (RemoteException re) { 1113 throw re.rethrowFromSystemServer(); 1114 } 1115 } 1116 1117 /** 1118 * Report usage associated with a particular {@code token} has started. Tokens are app defined 1119 * strings used to represent usage of in-app features. Apps with the {@link 1120 * android.Manifest.permission#OBSERVE_APP_USAGE} permission can register time limit observers 1121 * to monitor the usage of a token. In app usage can only associated with an {@code activity} 1122 * and usage will be considered stopped if the activity stops or crashes. 1123 * @see #registerAppUsageObserver 1124 * @see #registerUsageSessionObserver 1125 * @see #registerAppUsageLimitObserver 1126 * 1127 * @param activity The activity {@code token} is associated with. 1128 * @param token The token to report usage against. 1129 * @hide 1130 */ 1131 @SystemApi reportUsageStart(@onNull Activity activity, @NonNull String token)1132 public void reportUsageStart(@NonNull Activity activity, @NonNull String token) { 1133 try { 1134 mService.reportUsageStart(activity.getActivityToken(), token, 1135 mContext.getOpPackageName()); 1136 } catch (RemoteException e) { 1137 throw e.rethrowFromSystemServer(); 1138 } 1139 } 1140 1141 /** 1142 * Report usage associated with a particular {@code token} had started some amount of time in 1143 * the past. Tokens are app defined strings used to represent usage of in-app features. Apps 1144 * with the {@link android.Manifest.permission#OBSERVE_APP_USAGE} permission can register time 1145 * limit observers to monitor the usage of a token. In app usage can only associated with an 1146 * {@code activity} and usage will be considered stopped if the activity stops or crashes. 1147 * @see #registerAppUsageObserver 1148 * @see #registerUsageSessionObserver 1149 * @see #registerAppUsageLimitObserver 1150 * 1151 * @param activity The activity {@code token} is associated with. 1152 * @param token The token to report usage against. 1153 * @param timeAgoMs How long ago the start of usage took place 1154 * @hide 1155 */ 1156 @SystemApi reportUsageStart(@onNull Activity activity, @NonNull String token, long timeAgoMs)1157 public void reportUsageStart(@NonNull Activity activity, @NonNull String token, 1158 long timeAgoMs) { 1159 try { 1160 mService.reportPastUsageStart(activity.getActivityToken(), token, timeAgoMs, 1161 mContext.getOpPackageName()); 1162 } catch (RemoteException e) { 1163 throw e.rethrowFromSystemServer(); 1164 } 1165 } 1166 1167 /** 1168 * Report the usage associated with a particular {@code token} has stopped. 1169 * 1170 * @param activity The activity {@code token} is associated with. 1171 * @param token The token to report usage against. 1172 * @hide 1173 */ 1174 @SystemApi reportUsageStop(@onNull Activity activity, @NonNull String token)1175 public void reportUsageStop(@NonNull Activity activity, @NonNull String token) { 1176 try { 1177 mService.reportUsageStop(activity.getActivityToken(), token, 1178 mContext.getOpPackageName()); 1179 } catch (RemoteException e) { 1180 throw e.rethrowFromSystemServer(); 1181 } 1182 } 1183 1184 /** 1185 * Get what App Usage Observers will consider the source of usage for an activity. Usage Source 1186 * is decided at boot and will not change until next boot. 1187 * @see #USAGE_SOURCE_TASK_ROOT_ACTIVITY 1188 * @see #USAGE_SOURCE_CURRENT_ACTIVITY 1189 * 1190 * @throws SecurityException if the caller doesn't have the OBSERVE_APP_USAGE permission and 1191 * is not the profile owner of this user. 1192 * @hide 1193 */ 1194 @SystemApi getUsageSource()1195 public @UsageSource int getUsageSource() { 1196 try { 1197 return mService.getUsageSource(); 1198 } catch (RemoteException e) { 1199 throw e.rethrowFromSystemServer(); 1200 } 1201 } 1202 1203 /** 1204 * Force the Usage Source be reread from global settings. 1205 * @hide 1206 */ 1207 @TestApi forceUsageSourceSettingRead()1208 public void forceUsageSourceSettingRead() { 1209 try { 1210 mService.forceUsageSourceSettingRead(); 1211 } catch (RemoteException e) { 1212 throw e.rethrowFromSystemServer(); 1213 } 1214 } 1215 1216 /** @hide */ reasonToString(int standbyReason)1217 public static String reasonToString(int standbyReason) { 1218 final int subReason = standbyReason & REASON_SUB_MASK; 1219 StringBuilder sb = new StringBuilder(); 1220 switch (standbyReason & REASON_MAIN_MASK) { 1221 case REASON_MAIN_DEFAULT: 1222 sb.append("d"); 1223 switch (subReason) { 1224 case REASON_SUB_DEFAULT_UNDEFINED: 1225 // Historically, undefined didn't have a string, so don't add anything here. 1226 break; 1227 case REASON_SUB_DEFAULT_APP_UPDATE: 1228 sb.append("-au"); 1229 break; 1230 case REASON_SUB_DEFAULT_APP_RESTORED: 1231 sb.append("-ar"); 1232 break; 1233 } 1234 break; 1235 case REASON_MAIN_FORCED_BY_SYSTEM: 1236 sb.append("s"); 1237 if (subReason > 0) { 1238 sb.append("-").append(Integer.toBinaryString(subReason)); 1239 } 1240 break; 1241 case REASON_MAIN_FORCED_BY_USER: 1242 sb.append("f"); 1243 if (subReason > 0) { 1244 sb.append("-").append(Integer.toBinaryString(subReason)); 1245 } 1246 break; 1247 case REASON_MAIN_PREDICTED: 1248 sb.append("p"); 1249 switch (subReason) { 1250 case REASON_SUB_PREDICTED_RESTORED: 1251 sb.append("-r"); 1252 break; 1253 } 1254 break; 1255 case REASON_MAIN_TIMEOUT: 1256 sb.append("t"); 1257 break; 1258 case REASON_MAIN_USAGE: 1259 sb.append("u"); 1260 switch (subReason) { 1261 case REASON_SUB_USAGE_SYSTEM_INTERACTION: 1262 sb.append("-si"); 1263 break; 1264 case REASON_SUB_USAGE_NOTIFICATION_SEEN: 1265 sb.append("-ns"); 1266 break; 1267 case REASON_SUB_USAGE_USER_INTERACTION: 1268 sb.append("-ui"); 1269 break; 1270 case REASON_SUB_USAGE_MOVE_TO_FOREGROUND: 1271 sb.append("-mf"); 1272 break; 1273 case REASON_SUB_USAGE_MOVE_TO_BACKGROUND: 1274 sb.append("-mb"); 1275 break; 1276 case REASON_SUB_USAGE_SYSTEM_UPDATE: 1277 sb.append("-su"); 1278 break; 1279 case REASON_SUB_USAGE_ACTIVE_TIMEOUT: 1280 sb.append("-at"); 1281 break; 1282 case REASON_SUB_USAGE_SYNC_ADAPTER: 1283 sb.append("-sa"); 1284 break; 1285 case REASON_SUB_USAGE_SLICE_PINNED: 1286 sb.append("-lp"); 1287 break; 1288 case REASON_SUB_USAGE_SLICE_PINNED_PRIV: 1289 sb.append("-lv"); 1290 break; 1291 case REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_NON_DOZE: 1292 sb.append("-en"); 1293 break; 1294 case REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_DOZE: 1295 sb.append("-ed"); 1296 break; 1297 case REASON_SUB_USAGE_EXEMPTED_SYNC_START: 1298 sb.append("-es"); 1299 break; 1300 case REASON_SUB_USAGE_UNEXEMPTED_SYNC_SCHEDULED: 1301 sb.append("-uss"); 1302 break; 1303 case REASON_SUB_USAGE_FOREGROUND_SERVICE_START: 1304 sb.append("-fss"); 1305 break; 1306 } 1307 break; 1308 } 1309 return sb.toString(); 1310 } 1311 1312 /** @hide */ usageSourceToString(int usageSource)1313 public static String usageSourceToString(int usageSource) { 1314 switch (usageSource) { 1315 case USAGE_SOURCE_TASK_ROOT_ACTIVITY: 1316 return "TASK_ROOT_ACTIVITY"; 1317 case USAGE_SOURCE_CURRENT_ACTIVITY: 1318 return "CURRENT_ACTIVITY"; 1319 default: 1320 StringBuilder sb = new StringBuilder(); 1321 sb.append("UNKNOWN("); 1322 sb.append(usageSource); 1323 sb.append(")"); 1324 return sb.toString(); 1325 } 1326 } 1327 1328 /** @hide */ standbyBucketToString(int standbyBucket)1329 public static String standbyBucketToString(int standbyBucket) { 1330 switch (standbyBucket) { 1331 case STANDBY_BUCKET_EXEMPTED: 1332 return "EXEMPTED"; 1333 case STANDBY_BUCKET_ACTIVE: 1334 return "ACTIVE"; 1335 case STANDBY_BUCKET_WORKING_SET: 1336 return "WORKING_SET"; 1337 case STANDBY_BUCKET_FREQUENT: 1338 return "FREQUENT"; 1339 case STANDBY_BUCKET_RARE: 1340 return "RARE"; 1341 case STANDBY_BUCKET_RESTRICTED: 1342 return "RESTRICTED"; 1343 case STANDBY_BUCKET_NEVER: 1344 return "NEVER"; 1345 default: 1346 return String.valueOf(standbyBucket); 1347 } 1348 } 1349 1350 /** 1351 * {@hide} 1352 * Temporarily allowlist the specified app for a short duration. This is to allow an app 1353 * receiving a high priority message to be able to access the network and acquire wakelocks 1354 * even if the device is in power-save mode or the app is currently considered inactive. 1355 * @param packageName The package name of the app to allowlist. 1356 * @param duration Duration to allowlist the app for, in milliseconds. It is recommended that 1357 * this be limited to 10s of seconds. Requested duration will be clamped to a few minutes. 1358 * @param user The user for whom the package should be allowlisted. Passing in a user that is 1359 * not the same as the caller's process will require the INTERACT_ACROSS_USERS permission. 1360 * @see #isAppInactive(String) 1361 * 1362 * @deprecated Use 1363 * {@link android.os.PowerWhitelistManager#whitelistAppTemporarily(String, long)} instead. 1364 */ 1365 @SystemApi 1366 @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST) 1367 @Deprecated whitelistAppTemporarily(String packageName, long duration, UserHandle user)1368 public void whitelistAppTemporarily(String packageName, long duration, UserHandle user) { 1369 mContext.getSystemService(PowerWhitelistManager.class) 1370 .whitelistAppTemporarily(packageName, duration); 1371 } 1372 1373 /** 1374 * Inform usage stats that the carrier privileged apps access rules have changed. 1375 * <p> The caller must have {@link android.Manifest.permission#BIND_CARRIER_SERVICES} </p> 1376 * @hide 1377 */ 1378 @SystemApi 1379 @RequiresPermission(android.Manifest.permission.BIND_CARRIER_SERVICES) onCarrierPrivilegedAppsChanged()1380 public void onCarrierPrivilegedAppsChanged() { 1381 try { 1382 mService.onCarrierPrivilegedAppsChanged(); 1383 } catch (RemoteException re) { 1384 throw re.rethrowFromSystemServer(); 1385 } 1386 } 1387 1388 /** 1389 * Reports a Chooser action to the UsageStatsManager. 1390 * 1391 * @param packageName The package name of the app that is selected. 1392 * @param userId The user id of who makes the selection. 1393 * @param contentType The type of the content, e.g., Image, Video, App. 1394 * @param annotations The annotations of the content, e.g., Game, Selfie. 1395 * @param action The action type of Intent that invokes ChooserActivity. 1396 * {@link UsageEvents} 1397 * @hide 1398 */ reportChooserSelection(String packageName, int userId, String contentType, String[] annotations, String action)1399 public void reportChooserSelection(String packageName, int userId, String contentType, 1400 String[] annotations, String action) { 1401 try { 1402 mService.reportChooserSelection(packageName, userId, contentType, annotations, action); 1403 } catch (RemoteException re) { 1404 } 1405 } 1406 1407 /** 1408 * Get the last time a package is used by any users including explicit user interaction and 1409 * component usage, measured in milliseconds since the epoch and truncated to the boundary of 1410 * last day before the exact time. For packages that are never used, the time will be the epoch. 1411 * <p> Note that this usage stats is user-agnostic. </p> 1412 * <p> 1413 * Also note that component usage is only reported for component bindings (e.g. broadcast 1414 * receiver, service, content provider) and only when such a binding would cause an app to leave 1415 * the stopped state. 1416 * See {@link UsageEvents.Event.USER_INTERACTION}, {@link UsageEvents.Event.APP_COMPONENT_USED}. 1417 * </p> 1418 * 1419 * @param packageName The name of the package to be queried. 1420 * @return last time the queried package is used since the epoch. 1421 * @hide 1422 */ 1423 @SystemApi 1424 @RequiresPermission(allOf = { 1425 android.Manifest.permission.INTERACT_ACROSS_USERS, 1426 android.Manifest.permission.PACKAGE_USAGE_STATS}) getLastTimeAnyComponentUsed(@onNull String packageName)1427 public long getLastTimeAnyComponentUsed(@NonNull String packageName) { 1428 try { 1429 return mService.getLastTimeAnyComponentUsed(packageName, mContext.getOpPackageName()); 1430 } catch (RemoteException re) { 1431 throw re.rethrowFromSystemServer(); 1432 } 1433 } 1434 1435 /** 1436 * Returns the broadcast response stats since the last boot corresponding to 1437 * {@code packageName} and {@code id}. 1438 * 1439 * <p> Broadcast response stats will include the aggregated data of what actions an app took 1440 * upon receiving a broadcast. This data will consider the broadcasts that the caller sent to 1441 * {@code packageName} and explicitly requested to record the response events using 1442 * {@link BroadcastOptions#recordResponseEventWhileInBackground(long)}. 1443 * 1444 * <p> The returned list could one or more {@link BroadcastResponseStats} objects or be empty 1445 * depending on the {@code packageName} and {@code id} and whether there is any data 1446 * corresponding to these. If the {@code packageName} is not {@code null} and {@code id} is 1447 * {@code > 0}, then the returned list would contain at most one {@link BroadcastResponseStats} 1448 * object. Otherwise, the returned list could contain more than one 1449 * {@link BroadcastResponseStats} object in no particular order. 1450 * 1451 * <p> Note: It is possible that same {@code id} was used for broadcasts sent to different 1452 * packages. So, callers can query the data corresponding to 1453 * all broadcasts with a particular {@code id} by passing {@code packageName} as {@code null}. 1454 * 1455 * @param packageName The name of the package that the caller wants to query for 1456 * or {@code null} to indicate that data corresponding to all packages 1457 * should be returned. 1458 * @param id The ID corresponding to the broadcasts that the caller wants to query for, or 1459 * {@code 0} to indicate that data corresponding to all IDs should be returned. 1460 * This is the ID the caller specifies when requesting a broadcast response event 1461 * to be recorded using 1462 * {@link BroadcastOptions#recordResponseEventWhileInBackground(long)}. 1463 * 1464 * @return the list of broadcast response stats corresponding to {@code packageName} 1465 * and {@code id}. 1466 * 1467 * @see #clearBroadcastResponseStats(String, long) 1468 * @hide 1469 */ 1470 @SystemApi 1471 @RequiresPermission(android.Manifest.permission.ACCESS_BROADCAST_RESPONSE_STATS) 1472 @UserHandleAware 1473 @NonNull queryBroadcastResponseStats( @ullable String packageName, @IntRange(from = 0) long id)1474 public List<BroadcastResponseStats> queryBroadcastResponseStats( 1475 @Nullable String packageName, @IntRange(from = 0) long id) { 1476 try { 1477 return mService.queryBroadcastResponseStats(packageName, id, 1478 mContext.getOpPackageName(), mContext.getUserId()).getList(); 1479 } catch (RemoteException re) { 1480 throw re.rethrowFromSystemServer(); 1481 } 1482 } 1483 1484 /** 1485 * Clears the broadcast response stats corresponding to {@code packageName} and {@code id}. 1486 * 1487 * <p> When a caller uses this API, stats related to the events occurring till that point will 1488 * be cleared and subsequent calls to {@link #queryBroadcastResponseStats(String, long)} will 1489 * return stats related to events occurring after this. 1490 * 1491 * @param packageName The name of the package that the caller wants to clear the data for or 1492 * {@code null} to indicate that data corresponding to all packages should 1493 * be cleared. 1494 * @param id The ID corresponding to the broadcasts that the caller wants to clear the data 1495 * for, or {code 0} to indicate that data corresponding to all IDs should be deleted. 1496 * This is the ID the caller specifies when requesting a broadcast response event 1497 * to be recorded using 1498 * {@link BroadcastOptions#recordResponseEventWhileInBackground(long)}. 1499 * 1500 * @see #queryBroadcastResponseStats(String, long) 1501 * @hide 1502 */ 1503 @SystemApi 1504 @RequiresPermission(android.Manifest.permission.ACCESS_BROADCAST_RESPONSE_STATS) 1505 @UserHandleAware clearBroadcastResponseStats(@ullable String packageName, @IntRange(from = 0) long id)1506 public void clearBroadcastResponseStats(@Nullable String packageName, 1507 @IntRange(from = 0) long id) { 1508 try { 1509 mService.clearBroadcastResponseStats(packageName, id, 1510 mContext.getOpPackageName(), mContext.getUserId()); 1511 } catch (RemoteException re) { 1512 throw re.rethrowFromSystemServer(); 1513 } 1514 } 1515 1516 /** 1517 * Clears the broadcast events that were sent by the caller uid. 1518 * 1519 * @hide 1520 */ 1521 @RequiresPermission(android.Manifest.permission.ACCESS_BROADCAST_RESPONSE_STATS) 1522 @UserHandleAware clearBroadcastEvents()1523 public void clearBroadcastEvents() { 1524 try { 1525 mService.clearBroadcastEvents(mContext.getOpPackageName(), mContext.getUserId()); 1526 } catch (RemoteException re) { 1527 throw re.rethrowFromSystemServer(); 1528 } 1529 } 1530 1531 /** @hide */ 1532 @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG) 1533 @Nullable getAppStandbyConstant(@onNull String key)1534 public String getAppStandbyConstant(@NonNull String key) { 1535 try { 1536 return mService.getAppStandbyConstant(key); 1537 } catch (RemoteException re) { 1538 throw re.rethrowFromSystemServer(); 1539 } 1540 } 1541 } 1542