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