1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy 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, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.app; 18 19 import android.Manifest; 20 import android.annotation.IntDef; 21 import android.annotation.IntRange; 22 import android.annotation.NonNull; 23 import android.annotation.Nullable; 24 import android.annotation.RequiresPermission; 25 import android.annotation.SystemApi; 26 import android.annotation.SystemService; 27 import android.annotation.TestApi; 28 import android.app.usage.UsageStatsManager; 29 import android.compat.annotation.UnsupportedAppUsage; 30 import android.content.Context; 31 import android.content.pm.PackageManager; 32 import android.content.pm.ParceledListSlice; 33 import android.media.AudioAttributes.AttributeUsage; 34 import android.os.Binder; 35 import android.os.IBinder; 36 import android.os.Parcel; 37 import android.os.Parcelable; 38 import android.os.Process; 39 import android.os.RemoteCallback; 40 import android.os.RemoteException; 41 import android.os.UserManager; 42 import android.util.ArrayMap; 43 import android.util.LongSparseArray; 44 import android.util.LongSparseLongArray; 45 import android.util.SparseArray; 46 47 import com.android.internal.annotations.GuardedBy; 48 import com.android.internal.annotations.Immutable; 49 import com.android.internal.app.IAppOpsActiveCallback; 50 import com.android.internal.app.IAppOpsCallback; 51 import com.android.internal.app.IAppOpsNotedCallback; 52 import com.android.internal.app.IAppOpsService; 53 import com.android.internal.util.ArrayUtils; 54 import com.android.internal.util.Preconditions; 55 56 import java.lang.annotation.ElementType; 57 import java.lang.annotation.Retention; 58 import java.lang.annotation.RetentionPolicy; 59 import java.lang.annotation.Target; 60 import java.math.BigDecimal; 61 import java.math.RoundingMode; 62 import java.util.ArrayList; 63 import java.util.Arrays; 64 import java.util.Collections; 65 import java.util.HashMap; 66 import java.util.List; 67 import java.util.Objects; 68 import java.util.concurrent.Executor; 69 import java.util.function.Consumer; 70 import java.util.function.Supplier; 71 72 /** 73 * API for interacting with "application operation" tracking. 74 * 75 * <p>This API is not generally intended for third party application developers; most 76 * features are only available to system applications. 77 */ 78 @SystemService(Context.APP_OPS_SERVICE) 79 public class AppOpsManager { 80 /** 81 * <p>App ops allows callers to:</p> 82 * 83 * <ul> 84 * <li> Note when operations are happening, and find out if they are allowed for the current 85 * caller.</li> 86 * <li> Disallow specific apps from doing specific operations.</li> 87 * <li> Collect all of the current information about operations that have been executed or 88 * are not being allowed.</li> 89 * <li> Monitor for changes in whether an operation is allowed.</li> 90 * </ul> 91 * 92 * <p>Each operation is identified by a single integer; these integers are a fixed set of 93 * operations, enumerated by the OP_* constants. 94 * 95 * <p></p>When checking operations, the result is a "mode" integer indicating the current 96 * setting for the operation under that caller: MODE_ALLOWED, MODE_IGNORED (don't execute 97 * the operation but fake its behavior enough so that the caller doesn't crash), 98 * MODE_ERRORED (throw a SecurityException back to the caller; the normal operation calls 99 * will do this for you). 100 */ 101 102 final Context mContext; 103 104 @UnsupportedAppUsage 105 final IAppOpsService mService; 106 107 @GuardedBy("mModeWatchers") 108 private final ArrayMap<OnOpChangedListener, IAppOpsCallback> mModeWatchers = 109 new ArrayMap<>(); 110 111 @GuardedBy("mActiveWatchers") 112 private final ArrayMap<OnOpActiveChangedListener, IAppOpsActiveCallback> mActiveWatchers = 113 new ArrayMap<>(); 114 115 @GuardedBy("mNotedWatchers") 116 private final ArrayMap<OnOpNotedListener, IAppOpsNotedCallback> mNotedWatchers = 117 new ArrayMap<>(); 118 119 static IBinder sToken; 120 121 /** @hide */ 122 @Retention(RetentionPolicy.SOURCE) 123 @IntDef(flag = true, prefix = { "HISTORICAL_MODE_" }, value = { 124 HISTORICAL_MODE_DISABLED, 125 HISTORICAL_MODE_ENABLED_ACTIVE, 126 HISTORICAL_MODE_ENABLED_PASSIVE 127 }) 128 public @interface HistoricalMode {} 129 130 /** 131 * Mode in which app op history is completely disabled. 132 * @hide 133 */ 134 @TestApi 135 public static final int HISTORICAL_MODE_DISABLED = 0; 136 137 /** 138 * Mode in which app op history is enabled and app ops performed by apps would 139 * be tracked. This is the mode in which the feature is completely enabled. 140 * @hide 141 */ 142 @TestApi 143 public static final int HISTORICAL_MODE_ENABLED_ACTIVE = 1; 144 145 /** 146 * Mode in which app op history is enabled but app ops performed by apps would 147 * not be tracked and the only way to add ops to the history is via explicit calls 148 * to dedicated APIs. This mode is useful for testing to allow full control of 149 * the historical content. 150 * @hide 151 */ 152 @TestApi 153 public static final int HISTORICAL_MODE_ENABLED_PASSIVE = 2; 154 155 /** @hide */ 156 @Retention(RetentionPolicy.SOURCE) 157 @IntDef(flag = true, prefix = { "MODE_" }, value = { 158 MODE_ALLOWED, 159 MODE_IGNORED, 160 MODE_ERRORED, 161 MODE_DEFAULT, 162 MODE_FOREGROUND 163 }) 164 public @interface Mode {} 165 166 /** 167 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is 168 * allowed to perform the given operation. 169 */ 170 public static final int MODE_ALLOWED = 0; 171 172 /** 173 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is 174 * not allowed to perform the given operation, and this attempt should 175 * <em>silently fail</em> (it should not cause the app to crash). 176 */ 177 public static final int MODE_IGNORED = 1; 178 179 /** 180 * Result from {@link #checkOpNoThrow}, {@link #noteOpNoThrow}, {@link #startOpNoThrow}: the 181 * given caller is not allowed to perform the given operation, and this attempt should 182 * cause it to have a fatal error, typically a {@link SecurityException}. 183 */ 184 public static final int MODE_ERRORED = 2; 185 186 /** 187 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller should 188 * use its default security check. This mode is not normally used; it should only be used 189 * with appop permissions, and callers must explicitly check for it and deal with it. 190 */ 191 public static final int MODE_DEFAULT = 3; 192 193 /** 194 * Special mode that means "allow only when app is in foreground." This is <b>not</b> 195 * returned from {@link #unsafeCheckOp}, {@link #noteOp}, {@link #startOp}. Rather, 196 * {@link #unsafeCheckOp} will always return {@link #MODE_ALLOWED} (because it is always 197 * possible for it to be ultimately allowed, depending on the app's background state), 198 * and {@link #noteOp} and {@link #startOp} will return {@link #MODE_ALLOWED} when the app 199 * being checked is currently in the foreground, otherwise {@link #MODE_IGNORED}. 200 * 201 * <p>The only place you will this normally see this value is through 202 * {@link #unsafeCheckOpRaw}, which returns the actual raw mode of the op. Note that because 203 * you can't know the current state of the app being checked (and it can change at any 204 * point), you can only treat the result here as an indication that it will vary between 205 * {@link #MODE_ALLOWED} and {@link #MODE_IGNORED} depending on changes in the background 206 * state of the app. You thus must always use {@link #noteOp} or {@link #startOp} to do 207 * the actual check for access to the op.</p> 208 */ 209 public static final int MODE_FOREGROUND = 4; 210 211 /** 212 * Flag for {@link #startWatchingMode(String, String, int, OnOpChangedListener)}: 213 * Also get reports if the foreground state of an op's uid changes. This only works 214 * when watching a particular op, not when watching a package. 215 */ 216 public static final int WATCH_FOREGROUND_CHANGES = 1 << 0; 217 218 /** 219 * @hide 220 */ 221 public static final String[] MODE_NAMES = new String[] { 222 "allow", // MODE_ALLOWED 223 "ignore", // MODE_IGNORED 224 "deny", // MODE_ERRORED 225 "default", // MODE_DEFAULT 226 "foreground", // MODE_FOREGROUND 227 }; 228 229 /** @hide */ 230 @Retention(RetentionPolicy.SOURCE) 231 @IntDef(prefix = { "UID_STATE_" }, value = { 232 UID_STATE_PERSISTENT, 233 UID_STATE_TOP, 234 UID_STATE_FOREGROUND_SERVICE_LOCATION, 235 UID_STATE_FOREGROUND_SERVICE, 236 UID_STATE_FOREGROUND, 237 UID_STATE_BACKGROUND, 238 UID_STATE_CACHED 239 }) 240 public @interface UidState {} 241 242 /** 243 * Uid state: The UID is a foreground persistent app. The lower the UID 244 * state the more important the UID is for the user. 245 * @hide 246 */ 247 @TestApi 248 @SystemApi 249 public static final int UID_STATE_PERSISTENT = 100; 250 251 /** 252 * Uid state: The UID is top foreground app. The lower the UID 253 * state the more important the UID is for the user. 254 * @hide 255 */ 256 @TestApi 257 @SystemApi 258 public static final int UID_STATE_TOP = 200; 259 260 /** 261 * Uid state: The UID is running a foreground service of location type. 262 * The lower the UID state the more important the UID is for the user. 263 * @hide 264 */ 265 @TestApi 266 @SystemApi 267 public static final int UID_STATE_FOREGROUND_SERVICE_LOCATION = 300; 268 269 /** 270 * Uid state: The UID is running a foreground service. The lower the UID 271 * state the more important the UID is for the user. 272 * @hide 273 */ 274 @TestApi 275 @SystemApi 276 public static final int UID_STATE_FOREGROUND_SERVICE = 400; 277 278 /** 279 * The max, which is min priority, UID state for which any app op 280 * would be considered as performed in the foreground. 281 * @hide 282 */ 283 public static final int UID_STATE_MAX_LAST_NON_RESTRICTED = UID_STATE_FOREGROUND_SERVICE; 284 285 /** 286 * Uid state: The UID is a foreground app. The lower the UID 287 * state the more important the UID is for the user. 288 * @hide 289 */ 290 @TestApi 291 @SystemApi 292 public static final int UID_STATE_FOREGROUND = 500; 293 294 /** 295 * Uid state: The UID is a background app. The lower the UID 296 * state the more important the UID is for the user. 297 * @hide 298 */ 299 @TestApi 300 @SystemApi 301 public static final int UID_STATE_BACKGROUND = 600; 302 303 /** 304 * Uid state: The UID is a cached app. The lower the UID 305 * state the more important the UID is for the user. 306 * @hide 307 */ 308 @TestApi 309 @SystemApi 310 public static final int UID_STATE_CACHED = 700; 311 312 /** 313 * Uid state: The UID state with the highest priority. 314 * @hide 315 */ 316 public static final int MAX_PRIORITY_UID_STATE = UID_STATE_PERSISTENT; 317 318 /** 319 * Uid state: The UID state with the lowest priority. 320 * @hide 321 */ 322 public static final int MIN_PRIORITY_UID_STATE = UID_STATE_CACHED; 323 324 /** 325 * Resolves the first unrestricted state given an app op. Location is 326 * special as we want to allow its access only if a dedicated location 327 * foreground service is running. For other ops we consider any foreground 328 * service as a foreground state. 329 * 330 * @param op The op to resolve. 331 * @return The last restricted UID state. 332 * 333 * @hide 334 */ resolveFirstUnrestrictedUidState(int op)335 public static int resolveFirstUnrestrictedUidState(int op) { 336 switch (op) { 337 case OP_FINE_LOCATION: 338 case OP_COARSE_LOCATION: 339 case OP_MONITOR_LOCATION: 340 case OP_MONITOR_HIGH_POWER_LOCATION: { 341 return UID_STATE_FOREGROUND_SERVICE_LOCATION; 342 } 343 } 344 return UID_STATE_FOREGROUND_SERVICE; 345 } 346 347 /** 348 * Resolves the last restricted state given an app op. Location is 349 * special as we want to allow its access only if a dedicated location 350 * foreground service is running. For other ops we consider any foreground 351 * service as a foreground state. 352 * 353 * @param op The op to resolve. 354 * @return The last restricted UID state. 355 * 356 * @hide 357 */ resolveLastRestrictedUidState(int op)358 public static int resolveLastRestrictedUidState(int op) { 359 switch (op) { 360 case OP_FINE_LOCATION: 361 case OP_COARSE_LOCATION: { 362 return UID_STATE_FOREGROUND_SERVICE; 363 } 364 } 365 return UID_STATE_FOREGROUND; 366 } 367 368 /** @hide Note: Keep these sorted */ 369 public static final int[] UID_STATES = { 370 UID_STATE_PERSISTENT, 371 UID_STATE_TOP, 372 UID_STATE_FOREGROUND_SERVICE_LOCATION, 373 UID_STATE_FOREGROUND_SERVICE, 374 UID_STATE_FOREGROUND, 375 UID_STATE_BACKGROUND, 376 UID_STATE_CACHED 377 }; 378 379 /** @hide */ getUidStateName(@idState int uidState)380 public static String getUidStateName(@UidState int uidState) { 381 switch (uidState) { 382 case UID_STATE_PERSISTENT: 383 return "pers"; 384 case UID_STATE_TOP: 385 return "top"; 386 case UID_STATE_FOREGROUND_SERVICE_LOCATION: 387 return "fgsvcl"; 388 case UID_STATE_FOREGROUND_SERVICE: 389 return "fgsvc"; 390 case UID_STATE_FOREGROUND: 391 return "fg"; 392 case UID_STATE_BACKGROUND: 393 return "bg"; 394 case UID_STATE_CACHED: 395 return "cch"; 396 default: 397 return "unknown"; 398 } 399 } 400 401 /** 402 * Flag: non proxy operations. These are operations 403 * performed on behalf of the app itself and not on behalf of 404 * another one. 405 * 406 * @hide 407 */ 408 @TestApi 409 @SystemApi 410 public static final int OP_FLAG_SELF = 0x1; 411 412 /** 413 * Flag: trusted proxy operations. These are operations 414 * performed on behalf of another app by a trusted app. 415 * Which is work a trusted app blames on another app. 416 * 417 * @hide 418 */ 419 @TestApi 420 @SystemApi 421 public static final int OP_FLAG_TRUSTED_PROXY = 0x2; 422 423 /** 424 * Flag: untrusted proxy operations. These are operations 425 * performed on behalf of another app by an untrusted app. 426 * Which is work an untrusted app blames on another app. 427 * 428 * @hide 429 */ 430 @TestApi 431 @SystemApi 432 public static final int OP_FLAG_UNTRUSTED_PROXY = 0x4; 433 434 /** 435 * Flag: trusted proxied operations. These are operations 436 * performed by a trusted other app on behalf of an app. 437 * Which is work an app was blamed for by a trusted app. 438 * 439 * @hide 440 */ 441 @TestApi 442 @SystemApi 443 public static final int OP_FLAG_TRUSTED_PROXIED = 0x8; 444 445 /** 446 * Flag: untrusted proxied operations. These are operations 447 * performed by an untrusted other app on behalf of an app. 448 * Which is work an app was blamed for by an untrusted app. 449 * 450 * @hide 451 */ 452 @TestApi 453 @SystemApi 454 public static final int OP_FLAG_UNTRUSTED_PROXIED = 0x10; 455 456 /** 457 * Flags: all operations. These include operations matched 458 * by {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXIED}, 459 * {@link #OP_FLAG_UNTRUSTED_PROXIED}, {@link #OP_FLAG_TRUSTED_PROXIED}, 460 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. 461 * 462 * @hide 463 */ 464 @TestApi 465 @SystemApi 466 public static final int OP_FLAGS_ALL = 467 OP_FLAG_SELF 468 | OP_FLAG_TRUSTED_PROXY 469 | OP_FLAG_UNTRUSTED_PROXY 470 | OP_FLAG_TRUSTED_PROXIED 471 | OP_FLAG_UNTRUSTED_PROXIED; 472 473 /** 474 * Flags: all trusted operations which is ones either the app did {@link #OP_FLAG_SELF}, 475 * or it was blamed for by a trusted app {@link #OP_FLAG_TRUSTED_PROXIED}, or ones the 476 * app if untrusted blamed on other apps {@link #OP_FLAG_UNTRUSTED_PROXY}. 477 * 478 * @hide 479 */ 480 @SystemApi 481 public static final int OP_FLAGS_ALL_TRUSTED = AppOpsManager.OP_FLAG_SELF 482 | AppOpsManager.OP_FLAG_UNTRUSTED_PROXY 483 | AppOpsManager.OP_FLAG_TRUSTED_PROXIED; 484 485 /** @hide */ 486 @Retention(RetentionPolicy.SOURCE) 487 @IntDef(flag = true, prefix = { "FLAG_" }, value = { 488 OP_FLAG_SELF, 489 OP_FLAG_TRUSTED_PROXY, 490 OP_FLAG_UNTRUSTED_PROXY, 491 OP_FLAG_TRUSTED_PROXIED, 492 OP_FLAG_UNTRUSTED_PROXIED 493 }) 494 public @interface OpFlags {} 495 496 497 /** @hide */ getFlagName(@pFlags int flag)498 public static final String getFlagName(@OpFlags int flag) { 499 switch (flag) { 500 case OP_FLAG_SELF: 501 return "s"; 502 case OP_FLAG_TRUSTED_PROXY: 503 return "tp"; 504 case OP_FLAG_UNTRUSTED_PROXY: 505 return "up"; 506 case OP_FLAG_TRUSTED_PROXIED: 507 return "tpd"; 508 case OP_FLAG_UNTRUSTED_PROXIED: 509 return "upd"; 510 default: 511 return "unknown"; 512 } 513 } 514 515 private static final int UID_STATE_OFFSET = 31; 516 private static final int FLAGS_MASK = 0xFFFFFFFF; 517 518 /** 519 * Key for a data bucket storing app op state. The bucket 520 * is composed of the uid state and state flags. This way 521 * we can query data for given uid state and a set of flags where 522 * the flags control which type of data to get. For example, 523 * one can get the ops an app did on behalf of other apps 524 * while in the background. 525 * 526 * @hide 527 */ 528 @Retention(RetentionPolicy.SOURCE) 529 @Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD}) 530 public @interface DataBucketKey { 531 } 532 533 /** @hide */ keyToString(@ataBucketKey long key)534 public static String keyToString(@DataBucketKey long key) { 535 final int uidState = extractUidStateFromKey(key); 536 final int flags = extractFlagsFromKey(key); 537 return "[" + getUidStateName(uidState) + "-" + flagsToString(flags) + "]"; 538 } 539 540 /** @hide */ makeKey(@idState int uidState, @OpFlags int flags)541 public static @DataBucketKey long makeKey(@UidState int uidState, @OpFlags int flags) { 542 return ((long) uidState << UID_STATE_OFFSET) | flags; 543 } 544 545 /** @hide */ extractUidStateFromKey(@ataBucketKey long key)546 public static int extractUidStateFromKey(@DataBucketKey long key) { 547 return (int) (key >> UID_STATE_OFFSET); 548 } 549 550 /** @hide */ extractFlagsFromKey(@ataBucketKey long key)551 public static int extractFlagsFromKey(@DataBucketKey long key) { 552 return (int) (key & FLAGS_MASK); 553 } 554 555 /** @hide */ flagsToString(@pFlags int flags)556 public static String flagsToString(@OpFlags int flags) { 557 final StringBuilder flagsBuilder = new StringBuilder(); 558 while (flags != 0) { 559 final int flag = 1 << Integer.numberOfTrailingZeros(flags); 560 flags &= ~flag; 561 if (flagsBuilder.length() > 0) { 562 flagsBuilder.append('|'); 563 } 564 flagsBuilder.append(getFlagName(flag)); 565 } 566 return flagsBuilder.toString(); 567 } 568 569 // when adding one of these: 570 // - increment _NUM_OP 571 // - define an OPSTR_* constant (marked as @SystemApi) 572 // - add rows to sOpToSwitch, sOpToString, sOpNames, sOpToPerms, sOpDefault 573 // - add descriptive strings to Settings/res/values/arrays.xml 574 // - add the op to the appropriate template in AppOpsState.OpsTemplate (settings app) 575 576 /** @hide No operation specified. */ 577 @UnsupportedAppUsage 578 public static final int OP_NONE = -1; 579 /** @hide Access to coarse location information. */ 580 @UnsupportedAppUsage 581 @TestApi 582 public static final int OP_COARSE_LOCATION = 0; 583 /** @hide Access to fine location information. */ 584 @UnsupportedAppUsage 585 public static final int OP_FINE_LOCATION = 1; 586 /** @hide Causing GPS to run. */ 587 @UnsupportedAppUsage 588 public static final int OP_GPS = 2; 589 /** @hide */ 590 @UnsupportedAppUsage 591 public static final int OP_VIBRATE = 3; 592 /** @hide */ 593 @UnsupportedAppUsage 594 public static final int OP_READ_CONTACTS = 4; 595 /** @hide */ 596 @UnsupportedAppUsage 597 public static final int OP_WRITE_CONTACTS = 5; 598 /** @hide */ 599 @UnsupportedAppUsage 600 public static final int OP_READ_CALL_LOG = 6; 601 /** @hide */ 602 @UnsupportedAppUsage 603 public static final int OP_WRITE_CALL_LOG = 7; 604 /** @hide */ 605 @UnsupportedAppUsage 606 public static final int OP_READ_CALENDAR = 8; 607 /** @hide */ 608 @UnsupportedAppUsage 609 public static final int OP_WRITE_CALENDAR = 9; 610 /** @hide */ 611 @UnsupportedAppUsage 612 public static final int OP_WIFI_SCAN = 10; 613 /** @hide */ 614 @UnsupportedAppUsage 615 public static final int OP_POST_NOTIFICATION = 11; 616 /** @hide */ 617 @UnsupportedAppUsage 618 public static final int OP_NEIGHBORING_CELLS = 12; 619 /** @hide */ 620 @UnsupportedAppUsage 621 public static final int OP_CALL_PHONE = 13; 622 /** @hide */ 623 @UnsupportedAppUsage 624 public static final int OP_READ_SMS = 14; 625 /** @hide */ 626 @UnsupportedAppUsage 627 public static final int OP_WRITE_SMS = 15; 628 /** @hide */ 629 @UnsupportedAppUsage 630 public static final int OP_RECEIVE_SMS = 16; 631 /** @hide */ 632 @UnsupportedAppUsage 633 public static final int OP_RECEIVE_EMERGECY_SMS = 17; 634 /** @hide */ 635 @UnsupportedAppUsage 636 public static final int OP_RECEIVE_MMS = 18; 637 /** @hide */ 638 @UnsupportedAppUsage 639 public static final int OP_RECEIVE_WAP_PUSH = 19; 640 /** @hide */ 641 @UnsupportedAppUsage 642 public static final int OP_SEND_SMS = 20; 643 /** @hide */ 644 @UnsupportedAppUsage 645 public static final int OP_READ_ICC_SMS = 21; 646 /** @hide */ 647 @UnsupportedAppUsage 648 public static final int OP_WRITE_ICC_SMS = 22; 649 /** @hide */ 650 @UnsupportedAppUsage 651 public static final int OP_WRITE_SETTINGS = 23; 652 /** @hide Required to draw on top of other apps. */ 653 @UnsupportedAppUsage 654 @TestApi 655 public static final int OP_SYSTEM_ALERT_WINDOW = 24; 656 /** @hide */ 657 @UnsupportedAppUsage 658 public static final int OP_ACCESS_NOTIFICATIONS = 25; 659 /** @hide */ 660 @UnsupportedAppUsage 661 public static final int OP_CAMERA = 26; 662 /** @hide */ 663 @UnsupportedAppUsage 664 @TestApi 665 public static final int OP_RECORD_AUDIO = 27; 666 /** @hide */ 667 @UnsupportedAppUsage 668 public static final int OP_PLAY_AUDIO = 28; 669 /** @hide */ 670 @UnsupportedAppUsage 671 public static final int OP_READ_CLIPBOARD = 29; 672 /** @hide */ 673 @UnsupportedAppUsage 674 public static final int OP_WRITE_CLIPBOARD = 30; 675 /** @hide */ 676 @UnsupportedAppUsage 677 public static final int OP_TAKE_MEDIA_BUTTONS = 31; 678 /** @hide */ 679 @UnsupportedAppUsage 680 public static final int OP_TAKE_AUDIO_FOCUS = 32; 681 /** @hide */ 682 @UnsupportedAppUsage 683 public static final int OP_AUDIO_MASTER_VOLUME = 33; 684 /** @hide */ 685 @UnsupportedAppUsage 686 public static final int OP_AUDIO_VOICE_VOLUME = 34; 687 /** @hide */ 688 @UnsupportedAppUsage 689 public static final int OP_AUDIO_RING_VOLUME = 35; 690 /** @hide */ 691 @UnsupportedAppUsage 692 public static final int OP_AUDIO_MEDIA_VOLUME = 36; 693 /** @hide */ 694 @UnsupportedAppUsage 695 public static final int OP_AUDIO_ALARM_VOLUME = 37; 696 /** @hide */ 697 @UnsupportedAppUsage 698 public static final int OP_AUDIO_NOTIFICATION_VOLUME = 38; 699 /** @hide */ 700 @UnsupportedAppUsage 701 public static final int OP_AUDIO_BLUETOOTH_VOLUME = 39; 702 /** @hide */ 703 @UnsupportedAppUsage 704 public static final int OP_WAKE_LOCK = 40; 705 /** @hide Continually monitoring location data. */ 706 @UnsupportedAppUsage 707 public static final int OP_MONITOR_LOCATION = 41; 708 /** @hide Continually monitoring location data with a relatively high power request. */ 709 @UnsupportedAppUsage 710 public static final int OP_MONITOR_HIGH_POWER_LOCATION = 42; 711 /** @hide Retrieve current usage stats via {@link UsageStatsManager}. */ 712 @UnsupportedAppUsage 713 public static final int OP_GET_USAGE_STATS = 43; 714 /** @hide */ 715 @UnsupportedAppUsage 716 public static final int OP_MUTE_MICROPHONE = 44; 717 /** @hide */ 718 @UnsupportedAppUsage 719 public static final int OP_TOAST_WINDOW = 45; 720 /** @hide Capture the device's display contents and/or audio */ 721 @UnsupportedAppUsage 722 public static final int OP_PROJECT_MEDIA = 46; 723 724 /** 725 * Start (without additional user intervention) a VPN connection, as used by {@link 726 * android.net.VpnService} along with as Platform VPN connections, as used by {@link 727 * android.net.VpnManager} 728 * 729 * <p>This appop is granted to apps that have already been given user consent to start 730 * VpnService based VPN connections. As this is a superset of OP_ACTIVATE_PLATFORM_VPN, this 731 * appop also allows the starting of Platform VPNs. 732 * 733 * @hide 734 */ 735 @UnsupportedAppUsage 736 public static final int OP_ACTIVATE_VPN = 47; 737 /** @hide Access the WallpaperManagerAPI to write wallpapers. */ 738 @UnsupportedAppUsage 739 public static final int OP_WRITE_WALLPAPER = 48; 740 /** @hide Received the assist structure from an app. */ 741 @UnsupportedAppUsage 742 public static final int OP_ASSIST_STRUCTURE = 49; 743 /** @hide Received a screenshot from assist. */ 744 @UnsupportedAppUsage 745 public static final int OP_ASSIST_SCREENSHOT = 50; 746 /** @hide Read the phone state. */ 747 @UnsupportedAppUsage 748 public static final int OP_READ_PHONE_STATE = 51; 749 /** @hide Add voicemail messages to the voicemail content provider. */ 750 @UnsupportedAppUsage 751 public static final int OP_ADD_VOICEMAIL = 52; 752 /** @hide Access APIs for SIP calling over VOIP or WiFi. */ 753 @UnsupportedAppUsage 754 public static final int OP_USE_SIP = 53; 755 /** @hide Intercept outgoing calls. */ 756 @UnsupportedAppUsage 757 public static final int OP_PROCESS_OUTGOING_CALLS = 54; 758 /** @hide User the fingerprint API. */ 759 @UnsupportedAppUsage 760 public static final int OP_USE_FINGERPRINT = 55; 761 /** @hide Access to body sensors such as heart rate, etc. */ 762 @UnsupportedAppUsage 763 public static final int OP_BODY_SENSORS = 56; 764 /** @hide Read previously received cell broadcast messages. */ 765 @UnsupportedAppUsage 766 public static final int OP_READ_CELL_BROADCASTS = 57; 767 /** @hide Inject mock location into the system. */ 768 @UnsupportedAppUsage 769 public static final int OP_MOCK_LOCATION = 58; 770 /** @hide Read external storage. */ 771 @UnsupportedAppUsage 772 public static final int OP_READ_EXTERNAL_STORAGE = 59; 773 /** @hide Write external storage. */ 774 @UnsupportedAppUsage 775 public static final int OP_WRITE_EXTERNAL_STORAGE = 60; 776 /** @hide Turned on the screen. */ 777 @UnsupportedAppUsage 778 public static final int OP_TURN_SCREEN_ON = 61; 779 /** @hide Get device accounts. */ 780 @UnsupportedAppUsage 781 public static final int OP_GET_ACCOUNTS = 62; 782 /** @hide Control whether an application is allowed to run in the background. */ 783 @UnsupportedAppUsage 784 public static final int OP_RUN_IN_BACKGROUND = 63; 785 /** @hide */ 786 @UnsupportedAppUsage 787 public static final int OP_AUDIO_ACCESSIBILITY_VOLUME = 64; 788 /** @hide Read the phone number. */ 789 @UnsupportedAppUsage 790 public static final int OP_READ_PHONE_NUMBERS = 65; 791 /** @hide Request package installs through package installer */ 792 @UnsupportedAppUsage 793 public static final int OP_REQUEST_INSTALL_PACKAGES = 66; 794 /** @hide Enter picture-in-picture. */ 795 @UnsupportedAppUsage 796 public static final int OP_PICTURE_IN_PICTURE = 67; 797 /** @hide Instant app start foreground service. */ 798 @UnsupportedAppUsage 799 public static final int OP_INSTANT_APP_START_FOREGROUND = 68; 800 /** @hide Answer incoming phone calls */ 801 @UnsupportedAppUsage 802 public static final int OP_ANSWER_PHONE_CALLS = 69; 803 /** @hide Run jobs when in background */ 804 @UnsupportedAppUsage 805 public static final int OP_RUN_ANY_IN_BACKGROUND = 70; 806 /** @hide Change Wi-Fi connectivity state */ 807 @UnsupportedAppUsage 808 public static final int OP_CHANGE_WIFI_STATE = 71; 809 /** @hide Request package deletion through package installer */ 810 @UnsupportedAppUsage 811 public static final int OP_REQUEST_DELETE_PACKAGES = 72; 812 /** @hide Bind an accessibility service. */ 813 @UnsupportedAppUsage 814 public static final int OP_BIND_ACCESSIBILITY_SERVICE = 73; 815 /** @hide Continue handover of a call from another app */ 816 @UnsupportedAppUsage 817 public static final int OP_ACCEPT_HANDOVER = 74; 818 /** @hide Create and Manage IPsec Tunnels */ 819 @UnsupportedAppUsage 820 public static final int OP_MANAGE_IPSEC_TUNNELS = 75; 821 /** @hide Any app start foreground service. */ 822 @UnsupportedAppUsage 823 @TestApi 824 public static final int OP_START_FOREGROUND = 76; 825 /** @hide */ 826 @UnsupportedAppUsage 827 public static final int OP_BLUETOOTH_SCAN = 77; 828 /** @hide Use the BiometricPrompt/BiometricManager APIs. */ 829 public static final int OP_USE_BIOMETRIC = 78; 830 /** @hide Physical activity recognition. */ 831 public static final int OP_ACTIVITY_RECOGNITION = 79; 832 /** @hide Financial app sms read. */ 833 public static final int OP_SMS_FINANCIAL_TRANSACTIONS = 80; 834 /** @hide Read media of audio type. */ 835 public static final int OP_READ_MEDIA_AUDIO = 81; 836 /** @hide Write media of audio type. */ 837 public static final int OP_WRITE_MEDIA_AUDIO = 82; 838 /** @hide Read media of video type. */ 839 public static final int OP_READ_MEDIA_VIDEO = 83; 840 /** @hide Write media of video type. */ 841 public static final int OP_WRITE_MEDIA_VIDEO = 84; 842 /** @hide Read media of image type. */ 843 public static final int OP_READ_MEDIA_IMAGES = 85; 844 /** @hide Write media of image type. */ 845 public static final int OP_WRITE_MEDIA_IMAGES = 86; 846 /** @hide Has a legacy (non-isolated) view of storage. */ 847 public static final int OP_LEGACY_STORAGE = 87; 848 /** @hide Accessing accessibility features */ 849 public static final int OP_ACCESS_ACCESSIBILITY = 88; 850 /** @hide Read the device identifiers (IMEI / MEID, IMSI, SIM / Build serial) */ 851 public static final int OP_READ_DEVICE_IDENTIFIERS = 89; 852 /** @hide Read location metadata from media */ 853 public static final int OP_ACCESS_MEDIA_LOCATION = 90; 854 /** 855 * Start (without additional user intervention) a Platform VPN connection, as used by {@link 856 * android.net.VpnManager} 857 * 858 * <p>This appop is granted to apps that have already been given user consent to start Platform 859 * VPN connections. This appop is insufficient to start VpnService based VPNs (but the opposite 860 * is true). 861 * 862 * @hide 863 */ 864 public static final int OP_ACTIVATE_PLATFORM_VPN = 91; 865 866 /** @hide */ 867 @UnsupportedAppUsage 868 public static final int _NUM_OP = 92; 869 870 /** Access to coarse location information. */ 871 public static final String OPSTR_COARSE_LOCATION = "android:coarse_location"; 872 /** Access to fine location information. */ 873 public static final String OPSTR_FINE_LOCATION = 874 "android:fine_location"; 875 /** Continually monitoring location data. */ 876 public static final String OPSTR_MONITOR_LOCATION 877 = "android:monitor_location"; 878 /** Continually monitoring location data with a relatively high power request. */ 879 public static final String OPSTR_MONITOR_HIGH_POWER_LOCATION 880 = "android:monitor_location_high_power"; 881 /** Access to {@link android.app.usage.UsageStatsManager}. */ 882 public static final String OPSTR_GET_USAGE_STATS 883 = "android:get_usage_stats"; 884 /** Activate a VPN connection without user intervention. @hide */ 885 @SystemApi @TestApi 886 public static final String OPSTR_ACTIVATE_VPN 887 = "android:activate_vpn"; 888 /** Allows an application to read the user's contacts data. */ 889 public static final String OPSTR_READ_CONTACTS 890 = "android:read_contacts"; 891 /** Allows an application to write to the user's contacts data. */ 892 public static final String OPSTR_WRITE_CONTACTS 893 = "android:write_contacts"; 894 /** Allows an application to read the user's call log. */ 895 public static final String OPSTR_READ_CALL_LOG 896 = "android:read_call_log"; 897 /** Allows an application to write to the user's call log. */ 898 public static final String OPSTR_WRITE_CALL_LOG 899 = "android:write_call_log"; 900 /** Allows an application to read the user's calendar data. */ 901 public static final String OPSTR_READ_CALENDAR 902 = "android:read_calendar"; 903 /** Allows an application to write to the user's calendar data. */ 904 public static final String OPSTR_WRITE_CALENDAR 905 = "android:write_calendar"; 906 /** Allows an application to initiate a phone call. */ 907 public static final String OPSTR_CALL_PHONE 908 = "android:call_phone"; 909 /** Allows an application to read SMS messages. */ 910 public static final String OPSTR_READ_SMS 911 = "android:read_sms"; 912 /** Allows an application to receive SMS messages. */ 913 public static final String OPSTR_RECEIVE_SMS 914 = "android:receive_sms"; 915 /** Allows an application to receive MMS messages. */ 916 public static final String OPSTR_RECEIVE_MMS 917 = "android:receive_mms"; 918 /** Allows an application to receive WAP push messages. */ 919 public static final String OPSTR_RECEIVE_WAP_PUSH 920 = "android:receive_wap_push"; 921 /** Allows an application to send SMS messages. */ 922 public static final String OPSTR_SEND_SMS 923 = "android:send_sms"; 924 /** Required to be able to access the camera device. */ 925 public static final String OPSTR_CAMERA 926 = "android:camera"; 927 /** Required to be able to access the microphone device. */ 928 public static final String OPSTR_RECORD_AUDIO 929 = "android:record_audio"; 930 /** Required to access phone state related information. */ 931 public static final String OPSTR_READ_PHONE_STATE 932 = "android:read_phone_state"; 933 /** Required to access phone state related information. */ 934 public static final String OPSTR_ADD_VOICEMAIL 935 = "android:add_voicemail"; 936 /** Access APIs for SIP calling over VOIP or WiFi */ 937 public static final String OPSTR_USE_SIP 938 = "android:use_sip"; 939 /** Access APIs for diverting outgoing calls */ 940 public static final String OPSTR_PROCESS_OUTGOING_CALLS 941 = "android:process_outgoing_calls"; 942 /** Use the fingerprint API. */ 943 public static final String OPSTR_USE_FINGERPRINT 944 = "android:use_fingerprint"; 945 /** Access to body sensors such as heart rate, etc. */ 946 public static final String OPSTR_BODY_SENSORS 947 = "android:body_sensors"; 948 /** Read previously received cell broadcast messages. */ 949 public static final String OPSTR_READ_CELL_BROADCASTS 950 = "android:read_cell_broadcasts"; 951 /** Inject mock location into the system. */ 952 public static final String OPSTR_MOCK_LOCATION 953 = "android:mock_location"; 954 /** Read external storage. */ 955 public static final String OPSTR_READ_EXTERNAL_STORAGE 956 = "android:read_external_storage"; 957 /** Write external storage. */ 958 public static final String OPSTR_WRITE_EXTERNAL_STORAGE 959 = "android:write_external_storage"; 960 /** Required to draw on top of other apps. */ 961 public static final String OPSTR_SYSTEM_ALERT_WINDOW 962 = "android:system_alert_window"; 963 /** Required to write/modify/update system settingss. */ 964 public static final String OPSTR_WRITE_SETTINGS 965 = "android:write_settings"; 966 /** @hide Get device accounts. */ 967 @SystemApi @TestApi 968 public static final String OPSTR_GET_ACCOUNTS 969 = "android:get_accounts"; 970 public static final String OPSTR_READ_PHONE_NUMBERS 971 = "android:read_phone_numbers"; 972 /** Access to picture-in-picture. */ 973 public static final String OPSTR_PICTURE_IN_PICTURE 974 = "android:picture_in_picture"; 975 /** @hide */ 976 @SystemApi @TestApi 977 public static final String OPSTR_INSTANT_APP_START_FOREGROUND 978 = "android:instant_app_start_foreground"; 979 /** Answer incoming phone calls */ 980 public static final String OPSTR_ANSWER_PHONE_CALLS 981 = "android:answer_phone_calls"; 982 /** 983 * Accept call handover 984 * @hide 985 */ 986 @SystemApi @TestApi 987 public static final String OPSTR_ACCEPT_HANDOVER 988 = "android:accept_handover"; 989 /** @hide */ 990 @SystemApi @TestApi 991 public static final String OPSTR_GPS = "android:gps"; 992 /** @hide */ 993 @SystemApi @TestApi 994 public static final String OPSTR_VIBRATE = "android:vibrate"; 995 /** @hide */ 996 @SystemApi @TestApi 997 public static final String OPSTR_WIFI_SCAN = "android:wifi_scan"; 998 /** @hide */ 999 @SystemApi @TestApi 1000 public static final String OPSTR_POST_NOTIFICATION = "android:post_notification"; 1001 /** @hide */ 1002 @SystemApi @TestApi 1003 public static final String OPSTR_NEIGHBORING_CELLS = "android:neighboring_cells"; 1004 /** @hide */ 1005 @SystemApi @TestApi 1006 public static final String OPSTR_WRITE_SMS = "android:write_sms"; 1007 /** @hide */ 1008 @SystemApi @TestApi 1009 public static final String OPSTR_RECEIVE_EMERGENCY_BROADCAST = 1010 "android:receive_emergency_broadcast"; 1011 /** @hide */ 1012 @SystemApi @TestApi 1013 public static final String OPSTR_READ_ICC_SMS = "android:read_icc_sms"; 1014 /** @hide */ 1015 @SystemApi @TestApi 1016 public static final String OPSTR_WRITE_ICC_SMS = "android:write_icc_sms"; 1017 /** @hide */ 1018 @SystemApi @TestApi 1019 public static final String OPSTR_ACCESS_NOTIFICATIONS = "android:access_notifications"; 1020 /** @hide */ 1021 @SystemApi @TestApi 1022 public static final String OPSTR_PLAY_AUDIO = "android:play_audio"; 1023 /** @hide */ 1024 @SystemApi @TestApi 1025 public static final String OPSTR_READ_CLIPBOARD = "android:read_clipboard"; 1026 /** @hide */ 1027 @SystemApi @TestApi 1028 public static final String OPSTR_WRITE_CLIPBOARD = "android:write_clipboard"; 1029 /** @hide */ 1030 @SystemApi @TestApi 1031 public static final String OPSTR_TAKE_MEDIA_BUTTONS = "android:take_media_buttons"; 1032 /** @hide */ 1033 @SystemApi @TestApi 1034 public static final String OPSTR_TAKE_AUDIO_FOCUS = "android:take_audio_focus"; 1035 /** @hide */ 1036 @SystemApi @TestApi 1037 public static final String OPSTR_AUDIO_MASTER_VOLUME = "android:audio_master_volume"; 1038 /** @hide */ 1039 @SystemApi @TestApi 1040 public static final String OPSTR_AUDIO_VOICE_VOLUME = "android:audio_voice_volume"; 1041 /** @hide */ 1042 @SystemApi @TestApi 1043 public static final String OPSTR_AUDIO_RING_VOLUME = "android:audio_ring_volume"; 1044 /** @hide */ 1045 @SystemApi @TestApi 1046 public static final String OPSTR_AUDIO_MEDIA_VOLUME = "android:audio_media_volume"; 1047 /** @hide */ 1048 @SystemApi @TestApi 1049 public static final String OPSTR_AUDIO_ALARM_VOLUME = "android:audio_alarm_volume"; 1050 /** @hide */ 1051 @SystemApi @TestApi 1052 public static final String OPSTR_AUDIO_NOTIFICATION_VOLUME = 1053 "android:audio_notification_volume"; 1054 /** @hide */ 1055 @SystemApi @TestApi 1056 public static final String OPSTR_AUDIO_BLUETOOTH_VOLUME = "android:audio_bluetooth_volume"; 1057 /** @hide */ 1058 @SystemApi @TestApi 1059 public static final String OPSTR_WAKE_LOCK = "android:wake_lock"; 1060 /** @hide */ 1061 @SystemApi @TestApi 1062 public static final String OPSTR_MUTE_MICROPHONE = "android:mute_microphone"; 1063 /** @hide */ 1064 @SystemApi @TestApi 1065 public static final String OPSTR_TOAST_WINDOW = "android:toast_window"; 1066 /** @hide */ 1067 @SystemApi @TestApi 1068 public static final String OPSTR_PROJECT_MEDIA = "android:project_media"; 1069 /** @hide */ 1070 @SystemApi @TestApi 1071 public static final String OPSTR_WRITE_WALLPAPER = "android:write_wallpaper"; 1072 /** @hide */ 1073 @SystemApi @TestApi 1074 public static final String OPSTR_ASSIST_STRUCTURE = "android:assist_structure"; 1075 /** @hide */ 1076 @SystemApi @TestApi 1077 public static final String OPSTR_ASSIST_SCREENSHOT = "android:assist_screenshot"; 1078 /** @hide */ 1079 @SystemApi @TestApi 1080 public static final String OPSTR_TURN_SCREEN_ON = "android:turn_screen_on"; 1081 /** @hide */ 1082 @SystemApi @TestApi 1083 public static final String OPSTR_RUN_IN_BACKGROUND = "android:run_in_background"; 1084 /** @hide */ 1085 @SystemApi @TestApi 1086 public static final String OPSTR_AUDIO_ACCESSIBILITY_VOLUME = 1087 "android:audio_accessibility_volume"; 1088 /** @hide */ 1089 @SystemApi @TestApi 1090 public static final String OPSTR_REQUEST_INSTALL_PACKAGES = "android:request_install_packages"; 1091 /** @hide */ 1092 @SystemApi @TestApi 1093 public static final String OPSTR_RUN_ANY_IN_BACKGROUND = "android:run_any_in_background"; 1094 /** @hide */ 1095 @SystemApi @TestApi 1096 public static final String OPSTR_CHANGE_WIFI_STATE = "android:change_wifi_state"; 1097 /** @hide */ 1098 @SystemApi @TestApi 1099 public static final String OPSTR_REQUEST_DELETE_PACKAGES = "android:request_delete_packages"; 1100 /** @hide */ 1101 @SystemApi @TestApi 1102 public static final String OPSTR_BIND_ACCESSIBILITY_SERVICE = 1103 "android:bind_accessibility_service"; 1104 /** @hide */ 1105 @SystemApi @TestApi 1106 public static final String OPSTR_MANAGE_IPSEC_TUNNELS = "android:manage_ipsec_tunnels"; 1107 /** @hide */ 1108 @SystemApi @TestApi 1109 public static final String OPSTR_START_FOREGROUND = "android:start_foreground"; 1110 /** @hide */ 1111 public static final String OPSTR_BLUETOOTH_SCAN = "android:bluetooth_scan"; 1112 1113 /** @hide Use the BiometricPrompt/BiometricManager APIs. */ 1114 public static final String OPSTR_USE_BIOMETRIC = "android:use_biometric"; 1115 1116 /** @hide Recognize physical activity. */ 1117 public static final String OPSTR_ACTIVITY_RECOGNITION = "android:activity_recognition"; 1118 1119 /** @hide Financial app read sms. */ 1120 public static final String OPSTR_SMS_FINANCIAL_TRANSACTIONS = 1121 "android:sms_financial_transactions"; 1122 1123 /** @hide Read media of audio type. */ 1124 public static final String OPSTR_READ_MEDIA_AUDIO = "android:read_media_audio"; 1125 /** @hide Write media of audio type. */ 1126 public static final String OPSTR_WRITE_MEDIA_AUDIO = "android:write_media_audio"; 1127 /** @hide Read media of video type. */ 1128 public static final String OPSTR_READ_MEDIA_VIDEO = "android:read_media_video"; 1129 /** @hide Write media of video type. */ 1130 public static final String OPSTR_WRITE_MEDIA_VIDEO = "android:write_media_video"; 1131 /** @hide Read media of image type. */ 1132 public static final String OPSTR_READ_MEDIA_IMAGES = "android:read_media_images"; 1133 /** @hide Write media of image type. */ 1134 public static final String OPSTR_WRITE_MEDIA_IMAGES = "android:write_media_images"; 1135 /** @hide Has a legacy (non-isolated) view of storage. */ 1136 @TestApi 1137 @SystemApi 1138 public static final String OPSTR_LEGACY_STORAGE = "android:legacy_storage"; 1139 /** @hide Read location metadata from media */ 1140 public static final String OPSTR_ACCESS_MEDIA_LOCATION = "android:access_media_location"; 1141 1142 /** @hide Interact with accessibility. */ 1143 @SystemApi 1144 public static final String OPSTR_ACCESS_ACCESSIBILITY = "android:access_accessibility"; 1145 /** @hide Read device identifiers */ 1146 public static final String OPSTR_READ_DEVICE_IDENTIFIERS = "android:read_device_identifiers"; 1147 /** @hide Start Platform VPN without user intervention */ 1148 public static final String OPSTR_ACTIVATE_PLATFORM_VPN = "android:activate_platform_vpn"; 1149 1150 // Warning: If an permission is added here it also has to be added to 1151 // com.android.packageinstaller.permission.utils.EventLogger 1152 private static final int[] RUNTIME_AND_APPOP_PERMISSIONS_OPS = { 1153 // RUNTIME PERMISSIONS 1154 // Contacts 1155 OP_READ_CONTACTS, 1156 OP_WRITE_CONTACTS, 1157 OP_GET_ACCOUNTS, 1158 // Calendar 1159 OP_READ_CALENDAR, 1160 OP_WRITE_CALENDAR, 1161 // SMS 1162 OP_SEND_SMS, 1163 OP_RECEIVE_SMS, 1164 OP_READ_SMS, 1165 OP_RECEIVE_WAP_PUSH, 1166 OP_RECEIVE_MMS, 1167 OP_READ_CELL_BROADCASTS, 1168 // Storage 1169 OP_READ_EXTERNAL_STORAGE, 1170 OP_WRITE_EXTERNAL_STORAGE, 1171 OP_ACCESS_MEDIA_LOCATION, 1172 // Location 1173 OP_COARSE_LOCATION, 1174 OP_FINE_LOCATION, 1175 // Phone 1176 OP_READ_PHONE_STATE, 1177 OP_READ_PHONE_NUMBERS, 1178 OP_CALL_PHONE, 1179 OP_READ_CALL_LOG, 1180 OP_WRITE_CALL_LOG, 1181 OP_ADD_VOICEMAIL, 1182 OP_USE_SIP, 1183 OP_PROCESS_OUTGOING_CALLS, 1184 OP_ANSWER_PHONE_CALLS, 1185 OP_ACCEPT_HANDOVER, 1186 // Microphone 1187 OP_RECORD_AUDIO, 1188 // Camera 1189 OP_CAMERA, 1190 // Body sensors 1191 OP_BODY_SENSORS, 1192 // Activity recognition 1193 OP_ACTIVITY_RECOGNITION, 1194 // Aural 1195 OP_READ_MEDIA_AUDIO, 1196 OP_WRITE_MEDIA_AUDIO, 1197 // Visual 1198 OP_READ_MEDIA_VIDEO, 1199 OP_WRITE_MEDIA_VIDEO, 1200 OP_READ_MEDIA_IMAGES, 1201 OP_WRITE_MEDIA_IMAGES, 1202 1203 // APPOP PERMISSIONS 1204 OP_ACCESS_NOTIFICATIONS, 1205 OP_SYSTEM_ALERT_WINDOW, 1206 OP_WRITE_SETTINGS, 1207 OP_REQUEST_INSTALL_PACKAGES, 1208 OP_START_FOREGROUND, 1209 OP_SMS_FINANCIAL_TRANSACTIONS, 1210 }; 1211 1212 /** 1213 * This maps each operation to the operation that serves as the 1214 * switch to determine whether it is allowed. Generally this is 1215 * a 1:1 mapping, but for some things (like location) that have 1216 * multiple low-level operations being tracked that should be 1217 * presented to the user as one switch then this can be used to 1218 * make them all controlled by the same single operation. 1219 */ 1220 private static int[] sOpToSwitch = new int[] { 1221 OP_COARSE_LOCATION, // COARSE_LOCATION 1222 OP_COARSE_LOCATION, // FINE_LOCATION 1223 OP_COARSE_LOCATION, // GPS 1224 OP_VIBRATE, // VIBRATE 1225 OP_READ_CONTACTS, // READ_CONTACTS 1226 OP_WRITE_CONTACTS, // WRITE_CONTACTS 1227 OP_READ_CALL_LOG, // READ_CALL_LOG 1228 OP_WRITE_CALL_LOG, // WRITE_CALL_LOG 1229 OP_READ_CALENDAR, // READ_CALENDAR 1230 OP_WRITE_CALENDAR, // WRITE_CALENDAR 1231 OP_COARSE_LOCATION, // WIFI_SCAN 1232 OP_POST_NOTIFICATION, // POST_NOTIFICATION 1233 OP_COARSE_LOCATION, // NEIGHBORING_CELLS 1234 OP_CALL_PHONE, // CALL_PHONE 1235 OP_READ_SMS, // READ_SMS 1236 OP_WRITE_SMS, // WRITE_SMS 1237 OP_RECEIVE_SMS, // RECEIVE_SMS 1238 OP_RECEIVE_SMS, // RECEIVE_EMERGECY_SMS 1239 OP_RECEIVE_MMS, // RECEIVE_MMS 1240 OP_RECEIVE_WAP_PUSH, // RECEIVE_WAP_PUSH 1241 OP_SEND_SMS, // SEND_SMS 1242 OP_READ_SMS, // READ_ICC_SMS 1243 OP_WRITE_SMS, // WRITE_ICC_SMS 1244 OP_WRITE_SETTINGS, // WRITE_SETTINGS 1245 OP_SYSTEM_ALERT_WINDOW, // SYSTEM_ALERT_WINDOW 1246 OP_ACCESS_NOTIFICATIONS, // ACCESS_NOTIFICATIONS 1247 OP_CAMERA, // CAMERA 1248 OP_RECORD_AUDIO, // RECORD_AUDIO 1249 OP_PLAY_AUDIO, // PLAY_AUDIO 1250 OP_READ_CLIPBOARD, // READ_CLIPBOARD 1251 OP_WRITE_CLIPBOARD, // WRITE_CLIPBOARD 1252 OP_TAKE_MEDIA_BUTTONS, // TAKE_MEDIA_BUTTONS 1253 OP_TAKE_AUDIO_FOCUS, // TAKE_AUDIO_FOCUS 1254 OP_AUDIO_MASTER_VOLUME, // AUDIO_MASTER_VOLUME 1255 OP_AUDIO_VOICE_VOLUME, // AUDIO_VOICE_VOLUME 1256 OP_AUDIO_RING_VOLUME, // AUDIO_RING_VOLUME 1257 OP_AUDIO_MEDIA_VOLUME, // AUDIO_MEDIA_VOLUME 1258 OP_AUDIO_ALARM_VOLUME, // AUDIO_ALARM_VOLUME 1259 OP_AUDIO_NOTIFICATION_VOLUME, // AUDIO_NOTIFICATION_VOLUME 1260 OP_AUDIO_BLUETOOTH_VOLUME, // AUDIO_BLUETOOTH_VOLUME 1261 OP_WAKE_LOCK, // WAKE_LOCK 1262 OP_COARSE_LOCATION, // MONITOR_LOCATION 1263 OP_COARSE_LOCATION, // MONITOR_HIGH_POWER_LOCATION 1264 OP_GET_USAGE_STATS, // GET_USAGE_STATS 1265 OP_MUTE_MICROPHONE, // MUTE_MICROPHONE 1266 OP_TOAST_WINDOW, // TOAST_WINDOW 1267 OP_PROJECT_MEDIA, // PROJECT_MEDIA 1268 OP_ACTIVATE_VPN, // ACTIVATE_VPN 1269 OP_WRITE_WALLPAPER, // WRITE_WALLPAPER 1270 OP_ASSIST_STRUCTURE, // ASSIST_STRUCTURE 1271 OP_ASSIST_SCREENSHOT, // ASSIST_SCREENSHOT 1272 OP_READ_PHONE_STATE, // READ_PHONE_STATE 1273 OP_ADD_VOICEMAIL, // ADD_VOICEMAIL 1274 OP_USE_SIP, // USE_SIP 1275 OP_PROCESS_OUTGOING_CALLS, // PROCESS_OUTGOING_CALLS 1276 OP_USE_FINGERPRINT, // USE_FINGERPRINT 1277 OP_BODY_SENSORS, // BODY_SENSORS 1278 OP_READ_CELL_BROADCASTS, // READ_CELL_BROADCASTS 1279 OP_MOCK_LOCATION, // MOCK_LOCATION 1280 OP_READ_EXTERNAL_STORAGE, // READ_EXTERNAL_STORAGE 1281 OP_WRITE_EXTERNAL_STORAGE, // WRITE_EXTERNAL_STORAGE 1282 OP_TURN_SCREEN_ON, // TURN_SCREEN_ON 1283 OP_GET_ACCOUNTS, // GET_ACCOUNTS 1284 OP_RUN_IN_BACKGROUND, // RUN_IN_BACKGROUND 1285 OP_AUDIO_ACCESSIBILITY_VOLUME, // AUDIO_ACCESSIBILITY_VOLUME 1286 OP_READ_PHONE_NUMBERS, // READ_PHONE_NUMBERS 1287 OP_REQUEST_INSTALL_PACKAGES, // REQUEST_INSTALL_PACKAGES 1288 OP_PICTURE_IN_PICTURE, // ENTER_PICTURE_IN_PICTURE_ON_HIDE 1289 OP_INSTANT_APP_START_FOREGROUND, // INSTANT_APP_START_FOREGROUND 1290 OP_ANSWER_PHONE_CALLS, // ANSWER_PHONE_CALLS 1291 OP_RUN_ANY_IN_BACKGROUND, // OP_RUN_ANY_IN_BACKGROUND 1292 OP_CHANGE_WIFI_STATE, // OP_CHANGE_WIFI_STATE 1293 OP_REQUEST_DELETE_PACKAGES, // OP_REQUEST_DELETE_PACKAGES 1294 OP_BIND_ACCESSIBILITY_SERVICE, // OP_BIND_ACCESSIBILITY_SERVICE 1295 OP_ACCEPT_HANDOVER, // ACCEPT_HANDOVER 1296 OP_MANAGE_IPSEC_TUNNELS, // MANAGE_IPSEC_HANDOVERS 1297 OP_START_FOREGROUND, // START_FOREGROUND 1298 OP_COARSE_LOCATION, // BLUETOOTH_SCAN 1299 OP_USE_BIOMETRIC, // BIOMETRIC 1300 OP_ACTIVITY_RECOGNITION, // ACTIVITY_RECOGNITION 1301 OP_SMS_FINANCIAL_TRANSACTIONS, // SMS_FINANCIAL_TRANSACTIONS 1302 OP_READ_MEDIA_AUDIO, // READ_MEDIA_AUDIO 1303 OP_WRITE_MEDIA_AUDIO, // WRITE_MEDIA_AUDIO 1304 OP_READ_MEDIA_VIDEO, // READ_MEDIA_VIDEO 1305 OP_WRITE_MEDIA_VIDEO, // WRITE_MEDIA_VIDEO 1306 OP_READ_MEDIA_IMAGES, // READ_MEDIA_IMAGES 1307 OP_WRITE_MEDIA_IMAGES, // WRITE_MEDIA_IMAGES 1308 OP_LEGACY_STORAGE, // LEGACY_STORAGE 1309 OP_ACCESS_ACCESSIBILITY, // ACCESS_ACCESSIBILITY 1310 OP_READ_DEVICE_IDENTIFIERS, // READ_DEVICE_IDENTIFIERS 1311 OP_ACCESS_MEDIA_LOCATION, // ACCESS_MEDIA_LOCATION 1312 OP_ACTIVATE_PLATFORM_VPN, // ACTIVATE_PLATFORM_VPN 1313 }; 1314 1315 /** 1316 * This maps each operation to the public string constant for it. 1317 */ 1318 private static String[] sOpToString = new String[]{ 1319 OPSTR_COARSE_LOCATION, 1320 OPSTR_FINE_LOCATION, 1321 OPSTR_GPS, 1322 OPSTR_VIBRATE, 1323 OPSTR_READ_CONTACTS, 1324 OPSTR_WRITE_CONTACTS, 1325 OPSTR_READ_CALL_LOG, 1326 OPSTR_WRITE_CALL_LOG, 1327 OPSTR_READ_CALENDAR, 1328 OPSTR_WRITE_CALENDAR, 1329 OPSTR_WIFI_SCAN, 1330 OPSTR_POST_NOTIFICATION, 1331 OPSTR_NEIGHBORING_CELLS, 1332 OPSTR_CALL_PHONE, 1333 OPSTR_READ_SMS, 1334 OPSTR_WRITE_SMS, 1335 OPSTR_RECEIVE_SMS, 1336 OPSTR_RECEIVE_EMERGENCY_BROADCAST, 1337 OPSTR_RECEIVE_MMS, 1338 OPSTR_RECEIVE_WAP_PUSH, 1339 OPSTR_SEND_SMS, 1340 OPSTR_READ_ICC_SMS, 1341 OPSTR_WRITE_ICC_SMS, 1342 OPSTR_WRITE_SETTINGS, 1343 OPSTR_SYSTEM_ALERT_WINDOW, 1344 OPSTR_ACCESS_NOTIFICATIONS, 1345 OPSTR_CAMERA, 1346 OPSTR_RECORD_AUDIO, 1347 OPSTR_PLAY_AUDIO, 1348 OPSTR_READ_CLIPBOARD, 1349 OPSTR_WRITE_CLIPBOARD, 1350 OPSTR_TAKE_MEDIA_BUTTONS, 1351 OPSTR_TAKE_AUDIO_FOCUS, 1352 OPSTR_AUDIO_MASTER_VOLUME, 1353 OPSTR_AUDIO_VOICE_VOLUME, 1354 OPSTR_AUDIO_RING_VOLUME, 1355 OPSTR_AUDIO_MEDIA_VOLUME, 1356 OPSTR_AUDIO_ALARM_VOLUME, 1357 OPSTR_AUDIO_NOTIFICATION_VOLUME, 1358 OPSTR_AUDIO_BLUETOOTH_VOLUME, 1359 OPSTR_WAKE_LOCK, 1360 OPSTR_MONITOR_LOCATION, 1361 OPSTR_MONITOR_HIGH_POWER_LOCATION, 1362 OPSTR_GET_USAGE_STATS, 1363 OPSTR_MUTE_MICROPHONE, 1364 OPSTR_TOAST_WINDOW, 1365 OPSTR_PROJECT_MEDIA, 1366 OPSTR_ACTIVATE_VPN, 1367 OPSTR_WRITE_WALLPAPER, 1368 OPSTR_ASSIST_STRUCTURE, 1369 OPSTR_ASSIST_SCREENSHOT, 1370 OPSTR_READ_PHONE_STATE, 1371 OPSTR_ADD_VOICEMAIL, 1372 OPSTR_USE_SIP, 1373 OPSTR_PROCESS_OUTGOING_CALLS, 1374 OPSTR_USE_FINGERPRINT, 1375 OPSTR_BODY_SENSORS, 1376 OPSTR_READ_CELL_BROADCASTS, 1377 OPSTR_MOCK_LOCATION, 1378 OPSTR_READ_EXTERNAL_STORAGE, 1379 OPSTR_WRITE_EXTERNAL_STORAGE, 1380 OPSTR_TURN_SCREEN_ON, 1381 OPSTR_GET_ACCOUNTS, 1382 OPSTR_RUN_IN_BACKGROUND, 1383 OPSTR_AUDIO_ACCESSIBILITY_VOLUME, 1384 OPSTR_READ_PHONE_NUMBERS, 1385 OPSTR_REQUEST_INSTALL_PACKAGES, 1386 OPSTR_PICTURE_IN_PICTURE, 1387 OPSTR_INSTANT_APP_START_FOREGROUND, 1388 OPSTR_ANSWER_PHONE_CALLS, 1389 OPSTR_RUN_ANY_IN_BACKGROUND, 1390 OPSTR_CHANGE_WIFI_STATE, 1391 OPSTR_REQUEST_DELETE_PACKAGES, 1392 OPSTR_BIND_ACCESSIBILITY_SERVICE, 1393 OPSTR_ACCEPT_HANDOVER, 1394 OPSTR_MANAGE_IPSEC_TUNNELS, 1395 OPSTR_START_FOREGROUND, 1396 OPSTR_BLUETOOTH_SCAN, 1397 OPSTR_USE_BIOMETRIC, 1398 OPSTR_ACTIVITY_RECOGNITION, 1399 OPSTR_SMS_FINANCIAL_TRANSACTIONS, 1400 OPSTR_READ_MEDIA_AUDIO, 1401 OPSTR_WRITE_MEDIA_AUDIO, 1402 OPSTR_READ_MEDIA_VIDEO, 1403 OPSTR_WRITE_MEDIA_VIDEO, 1404 OPSTR_READ_MEDIA_IMAGES, 1405 OPSTR_WRITE_MEDIA_IMAGES, 1406 OPSTR_LEGACY_STORAGE, 1407 OPSTR_ACCESS_ACCESSIBILITY, 1408 OPSTR_READ_DEVICE_IDENTIFIERS, 1409 OPSTR_ACCESS_MEDIA_LOCATION, 1410 OPSTR_ACTIVATE_PLATFORM_VPN, 1411 }; 1412 1413 /** 1414 * This provides a simple name for each operation to be used 1415 * in debug output. 1416 */ 1417 private static String[] sOpNames = new String[] { 1418 "COARSE_LOCATION", 1419 "FINE_LOCATION", 1420 "GPS", 1421 "VIBRATE", 1422 "READ_CONTACTS", 1423 "WRITE_CONTACTS", 1424 "READ_CALL_LOG", 1425 "WRITE_CALL_LOG", 1426 "READ_CALENDAR", 1427 "WRITE_CALENDAR", 1428 "WIFI_SCAN", 1429 "POST_NOTIFICATION", 1430 "NEIGHBORING_CELLS", 1431 "CALL_PHONE", 1432 "READ_SMS", 1433 "WRITE_SMS", 1434 "RECEIVE_SMS", 1435 "RECEIVE_EMERGECY_SMS", 1436 "RECEIVE_MMS", 1437 "RECEIVE_WAP_PUSH", 1438 "SEND_SMS", 1439 "READ_ICC_SMS", 1440 "WRITE_ICC_SMS", 1441 "WRITE_SETTINGS", 1442 "SYSTEM_ALERT_WINDOW", 1443 "ACCESS_NOTIFICATIONS", 1444 "CAMERA", 1445 "RECORD_AUDIO", 1446 "PLAY_AUDIO", 1447 "READ_CLIPBOARD", 1448 "WRITE_CLIPBOARD", 1449 "TAKE_MEDIA_BUTTONS", 1450 "TAKE_AUDIO_FOCUS", 1451 "AUDIO_MASTER_VOLUME", 1452 "AUDIO_VOICE_VOLUME", 1453 "AUDIO_RING_VOLUME", 1454 "AUDIO_MEDIA_VOLUME", 1455 "AUDIO_ALARM_VOLUME", 1456 "AUDIO_NOTIFICATION_VOLUME", 1457 "AUDIO_BLUETOOTH_VOLUME", 1458 "WAKE_LOCK", 1459 "MONITOR_LOCATION", 1460 "MONITOR_HIGH_POWER_LOCATION", 1461 "GET_USAGE_STATS", 1462 "MUTE_MICROPHONE", 1463 "TOAST_WINDOW", 1464 "PROJECT_MEDIA", 1465 "ACTIVATE_VPN", 1466 "WRITE_WALLPAPER", 1467 "ASSIST_STRUCTURE", 1468 "ASSIST_SCREENSHOT", 1469 "READ_PHONE_STATE", 1470 "ADD_VOICEMAIL", 1471 "USE_SIP", 1472 "PROCESS_OUTGOING_CALLS", 1473 "USE_FINGERPRINT", 1474 "BODY_SENSORS", 1475 "READ_CELL_BROADCASTS", 1476 "MOCK_LOCATION", 1477 "READ_EXTERNAL_STORAGE", 1478 "WRITE_EXTERNAL_STORAGE", 1479 "TURN_ON_SCREEN", 1480 "GET_ACCOUNTS", 1481 "RUN_IN_BACKGROUND", 1482 "AUDIO_ACCESSIBILITY_VOLUME", 1483 "READ_PHONE_NUMBERS", 1484 "REQUEST_INSTALL_PACKAGES", 1485 "PICTURE_IN_PICTURE", 1486 "INSTANT_APP_START_FOREGROUND", 1487 "ANSWER_PHONE_CALLS", 1488 "RUN_ANY_IN_BACKGROUND", 1489 "CHANGE_WIFI_STATE", 1490 "REQUEST_DELETE_PACKAGES", 1491 "BIND_ACCESSIBILITY_SERVICE", 1492 "ACCEPT_HANDOVER", 1493 "MANAGE_IPSEC_TUNNELS", 1494 "START_FOREGROUND", 1495 "BLUETOOTH_SCAN", 1496 "USE_BIOMETRIC", 1497 "ACTIVITY_RECOGNITION", 1498 "SMS_FINANCIAL_TRANSACTIONS", 1499 "READ_MEDIA_AUDIO", 1500 "WRITE_MEDIA_AUDIO", 1501 "READ_MEDIA_VIDEO", 1502 "WRITE_MEDIA_VIDEO", 1503 "READ_MEDIA_IMAGES", 1504 "WRITE_MEDIA_IMAGES", 1505 "LEGACY_STORAGE", 1506 "ACCESS_ACCESSIBILITY", 1507 "READ_DEVICE_IDENTIFIERS", 1508 "ACCESS_MEDIA_LOCATION", 1509 "ACTIVATE_PLATFORM_VPN" 1510 }; 1511 1512 /** 1513 * This optionally maps a permission to an operation. If there 1514 * is no permission associated with an operation, it is null. 1515 */ 1516 @UnsupportedAppUsage 1517 private static String[] sOpPerms = new String[] { 1518 android.Manifest.permission.ACCESS_COARSE_LOCATION, 1519 android.Manifest.permission.ACCESS_FINE_LOCATION, 1520 null, 1521 android.Manifest.permission.VIBRATE, 1522 android.Manifest.permission.READ_CONTACTS, 1523 android.Manifest.permission.WRITE_CONTACTS, 1524 android.Manifest.permission.READ_CALL_LOG, 1525 android.Manifest.permission.WRITE_CALL_LOG, 1526 android.Manifest.permission.READ_CALENDAR, 1527 android.Manifest.permission.WRITE_CALENDAR, 1528 android.Manifest.permission.ACCESS_WIFI_STATE, 1529 null, // no permission required for notifications 1530 null, // neighboring cells shares the coarse location perm 1531 android.Manifest.permission.CALL_PHONE, 1532 android.Manifest.permission.READ_SMS, 1533 null, // no permission required for writing sms 1534 android.Manifest.permission.RECEIVE_SMS, 1535 android.Manifest.permission.RECEIVE_EMERGENCY_BROADCAST, 1536 android.Manifest.permission.RECEIVE_MMS, 1537 android.Manifest.permission.RECEIVE_WAP_PUSH, 1538 android.Manifest.permission.SEND_SMS, 1539 android.Manifest.permission.READ_SMS, 1540 null, // no permission required for writing icc sms 1541 android.Manifest.permission.WRITE_SETTINGS, 1542 android.Manifest.permission.SYSTEM_ALERT_WINDOW, 1543 android.Manifest.permission.ACCESS_NOTIFICATIONS, 1544 android.Manifest.permission.CAMERA, 1545 android.Manifest.permission.RECORD_AUDIO, 1546 null, // no permission for playing audio 1547 null, // no permission for reading clipboard 1548 null, // no permission for writing clipboard 1549 null, // no permission for taking media buttons 1550 null, // no permission for taking audio focus 1551 null, // no permission for changing master volume 1552 null, // no permission for changing voice volume 1553 null, // no permission for changing ring volume 1554 null, // no permission for changing media volume 1555 null, // no permission for changing alarm volume 1556 null, // no permission for changing notification volume 1557 null, // no permission for changing bluetooth volume 1558 android.Manifest.permission.WAKE_LOCK, 1559 null, // no permission for generic location monitoring 1560 null, // no permission for high power location monitoring 1561 android.Manifest.permission.PACKAGE_USAGE_STATS, 1562 null, // no permission for muting/unmuting microphone 1563 null, // no permission for displaying toasts 1564 null, // no permission for projecting media 1565 null, // no permission for activating vpn 1566 null, // no permission for supporting wallpaper 1567 null, // no permission for receiving assist structure 1568 null, // no permission for receiving assist screenshot 1569 Manifest.permission.READ_PHONE_STATE, 1570 Manifest.permission.ADD_VOICEMAIL, 1571 Manifest.permission.USE_SIP, 1572 Manifest.permission.PROCESS_OUTGOING_CALLS, 1573 Manifest.permission.USE_FINGERPRINT, 1574 Manifest.permission.BODY_SENSORS, 1575 Manifest.permission.READ_CELL_BROADCASTS, 1576 null, 1577 Manifest.permission.READ_EXTERNAL_STORAGE, 1578 Manifest.permission.WRITE_EXTERNAL_STORAGE, 1579 null, // no permission for turning the screen on 1580 Manifest.permission.GET_ACCOUNTS, 1581 null, // no permission for running in background 1582 null, // no permission for changing accessibility volume 1583 Manifest.permission.READ_PHONE_NUMBERS, 1584 Manifest.permission.REQUEST_INSTALL_PACKAGES, 1585 null, // no permission for entering picture-in-picture on hide 1586 Manifest.permission.INSTANT_APP_FOREGROUND_SERVICE, 1587 Manifest.permission.ANSWER_PHONE_CALLS, 1588 null, // no permission for OP_RUN_ANY_IN_BACKGROUND 1589 Manifest.permission.CHANGE_WIFI_STATE, 1590 Manifest.permission.REQUEST_DELETE_PACKAGES, 1591 Manifest.permission.BIND_ACCESSIBILITY_SERVICE, 1592 Manifest.permission.ACCEPT_HANDOVER, 1593 null, // no permission for OP_MANAGE_IPSEC_TUNNELS 1594 Manifest.permission.FOREGROUND_SERVICE, 1595 null, // no permission for OP_BLUETOOTH_SCAN 1596 Manifest.permission.USE_BIOMETRIC, 1597 Manifest.permission.ACTIVITY_RECOGNITION, 1598 Manifest.permission.SMS_FINANCIAL_TRANSACTIONS, 1599 null, 1600 null, // no permission for OP_WRITE_MEDIA_AUDIO 1601 null, 1602 null, // no permission for OP_WRITE_MEDIA_VIDEO 1603 null, 1604 null, // no permission for OP_WRITE_MEDIA_IMAGES 1605 null, // no permission for OP_LEGACY_STORAGE 1606 null, // no permission for OP_ACCESS_ACCESSIBILITY 1607 null, // no direct permission for OP_READ_DEVICE_IDENTIFIERS 1608 Manifest.permission.ACCESS_MEDIA_LOCATION, 1609 null, // no permission for OP_ACTIVATE_PLATFORM_VPN 1610 }; 1611 1612 /** 1613 * Specifies whether an Op should be restricted by a user restriction. 1614 * Each Op should be filled with a restriction string from UserManager or 1615 * null to specify it is not affected by any user restriction. 1616 */ 1617 private static String[] sOpRestrictions = new String[] { 1618 UserManager.DISALLOW_SHARE_LOCATION, //COARSE_LOCATION 1619 UserManager.DISALLOW_SHARE_LOCATION, //FINE_LOCATION 1620 UserManager.DISALLOW_SHARE_LOCATION, //GPS 1621 null, //VIBRATE 1622 null, //READ_CONTACTS 1623 null, //WRITE_CONTACTS 1624 UserManager.DISALLOW_OUTGOING_CALLS, //READ_CALL_LOG 1625 UserManager.DISALLOW_OUTGOING_CALLS, //WRITE_CALL_LOG 1626 null, //READ_CALENDAR 1627 null, //WRITE_CALENDAR 1628 UserManager.DISALLOW_SHARE_LOCATION, //WIFI_SCAN 1629 null, //POST_NOTIFICATION 1630 null, //NEIGHBORING_CELLS 1631 null, //CALL_PHONE 1632 UserManager.DISALLOW_SMS, //READ_SMS 1633 UserManager.DISALLOW_SMS, //WRITE_SMS 1634 UserManager.DISALLOW_SMS, //RECEIVE_SMS 1635 null, //RECEIVE_EMERGENCY_SMS 1636 UserManager.DISALLOW_SMS, //RECEIVE_MMS 1637 null, //RECEIVE_WAP_PUSH 1638 UserManager.DISALLOW_SMS, //SEND_SMS 1639 UserManager.DISALLOW_SMS, //READ_ICC_SMS 1640 UserManager.DISALLOW_SMS, //WRITE_ICC_SMS 1641 null, //WRITE_SETTINGS 1642 UserManager.DISALLOW_CREATE_WINDOWS, //SYSTEM_ALERT_WINDOW 1643 null, //ACCESS_NOTIFICATIONS 1644 UserManager.DISALLOW_CAMERA, //CAMERA 1645 UserManager.DISALLOW_RECORD_AUDIO, //RECORD_AUDIO 1646 null, //PLAY_AUDIO 1647 null, //READ_CLIPBOARD 1648 null, //WRITE_CLIPBOARD 1649 null, //TAKE_MEDIA_BUTTONS 1650 null, //TAKE_AUDIO_FOCUS 1651 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MASTER_VOLUME 1652 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_VOICE_VOLUME 1653 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_RING_VOLUME 1654 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MEDIA_VOLUME 1655 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ALARM_VOLUME 1656 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_NOTIFICATION_VOLUME 1657 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_BLUETOOTH_VOLUME 1658 null, //WAKE_LOCK 1659 UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_LOCATION 1660 UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_HIGH_POWER_LOCATION 1661 null, //GET_USAGE_STATS 1662 UserManager.DISALLOW_UNMUTE_MICROPHONE, // MUTE_MICROPHONE 1663 UserManager.DISALLOW_CREATE_WINDOWS, // TOAST_WINDOW 1664 null, //PROJECT_MEDIA 1665 null, // ACTIVATE_VPN 1666 UserManager.DISALLOW_WALLPAPER, // WRITE_WALLPAPER 1667 null, // ASSIST_STRUCTURE 1668 null, // ASSIST_SCREENSHOT 1669 null, // READ_PHONE_STATE 1670 null, // ADD_VOICEMAIL 1671 null, // USE_SIP 1672 null, // PROCESS_OUTGOING_CALLS 1673 null, // USE_FINGERPRINT 1674 null, // BODY_SENSORS 1675 null, // READ_CELL_BROADCASTS 1676 null, // MOCK_LOCATION 1677 null, // READ_EXTERNAL_STORAGE 1678 null, // WRITE_EXTERNAL_STORAGE 1679 null, // TURN_ON_SCREEN 1680 null, // GET_ACCOUNTS 1681 null, // RUN_IN_BACKGROUND 1682 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ACCESSIBILITY_VOLUME 1683 null, // READ_PHONE_NUMBERS 1684 null, // REQUEST_INSTALL_PACKAGES 1685 null, // ENTER_PICTURE_IN_PICTURE_ON_HIDE 1686 null, // INSTANT_APP_START_FOREGROUND 1687 null, // ANSWER_PHONE_CALLS 1688 null, // OP_RUN_ANY_IN_BACKGROUND 1689 null, // OP_CHANGE_WIFI_STATE 1690 null, // REQUEST_DELETE_PACKAGES 1691 null, // OP_BIND_ACCESSIBILITY_SERVICE 1692 null, // ACCEPT_HANDOVER 1693 null, // MANAGE_IPSEC_TUNNELS 1694 null, // START_FOREGROUND 1695 null, // maybe should be UserManager.DISALLOW_SHARE_LOCATION, //BLUETOOTH_SCAN 1696 null, // USE_BIOMETRIC 1697 null, // ACTIVITY_RECOGNITION 1698 UserManager.DISALLOW_SMS, // SMS_FINANCIAL_TRANSACTIONS 1699 null, // READ_MEDIA_AUDIO 1700 null, // WRITE_MEDIA_AUDIO 1701 null, // READ_MEDIA_VIDEO 1702 null, // WRITE_MEDIA_VIDEO 1703 null, // READ_MEDIA_IMAGES 1704 null, // WRITE_MEDIA_IMAGES 1705 null, // LEGACY_STORAGE 1706 null, // ACCESS_ACCESSIBILITY 1707 null, // READ_DEVICE_IDENTIFIERS 1708 null, // ACCESS_MEDIA_LOCATION 1709 null, // ACTIVATE_PLATFORM_VPN 1710 }; 1711 1712 /** 1713 * This specifies whether each option should allow the system 1714 * (and system ui) to bypass the user restriction when active. 1715 */ 1716 private static boolean[] sOpAllowSystemRestrictionBypass = new boolean[] { 1717 true, //COARSE_LOCATION 1718 true, //FINE_LOCATION 1719 false, //GPS 1720 false, //VIBRATE 1721 false, //READ_CONTACTS 1722 false, //WRITE_CONTACTS 1723 false, //READ_CALL_LOG 1724 false, //WRITE_CALL_LOG 1725 false, //READ_CALENDAR 1726 false, //WRITE_CALENDAR 1727 true, //WIFI_SCAN 1728 false, //POST_NOTIFICATION 1729 false, //NEIGHBORING_CELLS 1730 false, //CALL_PHONE 1731 false, //READ_SMS 1732 false, //WRITE_SMS 1733 false, //RECEIVE_SMS 1734 false, //RECEIVE_EMERGECY_SMS 1735 false, //RECEIVE_MMS 1736 false, //RECEIVE_WAP_PUSH 1737 false, //SEND_SMS 1738 false, //READ_ICC_SMS 1739 false, //WRITE_ICC_SMS 1740 false, //WRITE_SETTINGS 1741 true, //SYSTEM_ALERT_WINDOW 1742 false, //ACCESS_NOTIFICATIONS 1743 false, //CAMERA 1744 false, //RECORD_AUDIO 1745 false, //PLAY_AUDIO 1746 false, //READ_CLIPBOARD 1747 false, //WRITE_CLIPBOARD 1748 false, //TAKE_MEDIA_BUTTONS 1749 false, //TAKE_AUDIO_FOCUS 1750 false, //AUDIO_MASTER_VOLUME 1751 false, //AUDIO_VOICE_VOLUME 1752 false, //AUDIO_RING_VOLUME 1753 false, //AUDIO_MEDIA_VOLUME 1754 false, //AUDIO_ALARM_VOLUME 1755 false, //AUDIO_NOTIFICATION_VOLUME 1756 false, //AUDIO_BLUETOOTH_VOLUME 1757 false, //WAKE_LOCK 1758 false, //MONITOR_LOCATION 1759 false, //MONITOR_HIGH_POWER_LOCATION 1760 false, //GET_USAGE_STATS 1761 false, //MUTE_MICROPHONE 1762 true, //TOAST_WINDOW 1763 false, //PROJECT_MEDIA 1764 false, //ACTIVATE_VPN 1765 false, //WALLPAPER 1766 false, //ASSIST_STRUCTURE 1767 false, //ASSIST_SCREENSHOT 1768 false, //READ_PHONE_STATE 1769 false, //ADD_VOICEMAIL 1770 false, // USE_SIP 1771 false, // PROCESS_OUTGOING_CALLS 1772 false, // USE_FINGERPRINT 1773 false, // BODY_SENSORS 1774 false, // READ_CELL_BROADCASTS 1775 false, // MOCK_LOCATION 1776 false, // READ_EXTERNAL_STORAGE 1777 false, // WRITE_EXTERNAL_STORAGE 1778 false, // TURN_ON_SCREEN 1779 false, // GET_ACCOUNTS 1780 false, // RUN_IN_BACKGROUND 1781 false, // AUDIO_ACCESSIBILITY_VOLUME 1782 false, // READ_PHONE_NUMBERS 1783 false, // REQUEST_INSTALL_PACKAGES 1784 false, // ENTER_PICTURE_IN_PICTURE_ON_HIDE 1785 false, // INSTANT_APP_START_FOREGROUND 1786 false, // ANSWER_PHONE_CALLS 1787 false, // OP_RUN_ANY_IN_BACKGROUND 1788 false, // OP_CHANGE_WIFI_STATE 1789 false, // OP_REQUEST_DELETE_PACKAGES 1790 false, // OP_BIND_ACCESSIBILITY_SERVICE 1791 false, // ACCEPT_HANDOVER 1792 false, // MANAGE_IPSEC_HANDOVERS 1793 false, // START_FOREGROUND 1794 true, // BLUETOOTH_SCAN 1795 false, // USE_BIOMETRIC 1796 false, // ACTIVITY_RECOGNITION 1797 false, // SMS_FINANCIAL_TRANSACTIONS 1798 false, // READ_MEDIA_AUDIO 1799 false, // WRITE_MEDIA_AUDIO 1800 false, // READ_MEDIA_VIDEO 1801 false, // WRITE_MEDIA_VIDEO 1802 false, // READ_MEDIA_IMAGES 1803 false, // WRITE_MEDIA_IMAGES 1804 false, // LEGACY_STORAGE 1805 false, // ACCESS_ACCESSIBILITY 1806 false, // READ_DEVICE_IDENTIFIERS 1807 false, // ACCESS_MEDIA_LOCATION 1808 false, // ACTIVATE_PLATFORM_VPN 1809 }; 1810 1811 /** 1812 * This specifies the default mode for each operation. 1813 */ 1814 private static int[] sOpDefaultMode = new int[] { 1815 AppOpsManager.MODE_ALLOWED, // COARSE_LOCATION 1816 AppOpsManager.MODE_ALLOWED, // FINE_LOCATION 1817 AppOpsManager.MODE_ALLOWED, // GPS 1818 AppOpsManager.MODE_ALLOWED, // VIBRATE 1819 AppOpsManager.MODE_ALLOWED, // READ_CONTACTS 1820 AppOpsManager.MODE_ALLOWED, // WRITE_CONTACTS 1821 AppOpsManager.MODE_ALLOWED, // READ_CALL_LOG 1822 AppOpsManager.MODE_ALLOWED, // WRITE_CALL_LOG 1823 AppOpsManager.MODE_ALLOWED, // READ_CALENDAR 1824 AppOpsManager.MODE_ALLOWED, // WRITE_CALENDAR 1825 AppOpsManager.MODE_ALLOWED, // WIFI_SCAN 1826 AppOpsManager.MODE_ALLOWED, // POST_NOTIFICATION 1827 AppOpsManager.MODE_ALLOWED, // NEIGHBORING_CELLS 1828 AppOpsManager.MODE_ALLOWED, // CALL_PHONE 1829 AppOpsManager.MODE_ALLOWED, // READ_SMS 1830 AppOpsManager.MODE_IGNORED, // WRITE_SMS 1831 AppOpsManager.MODE_ALLOWED, // RECEIVE_SMS 1832 AppOpsManager.MODE_ALLOWED, // RECEIVE_EMERGENCY_BROADCAST 1833 AppOpsManager.MODE_ALLOWED, // RECEIVE_MMS 1834 AppOpsManager.MODE_ALLOWED, // RECEIVE_WAP_PUSH 1835 AppOpsManager.MODE_ALLOWED, // SEND_SMS 1836 AppOpsManager.MODE_ALLOWED, // READ_ICC_SMS 1837 AppOpsManager.MODE_ALLOWED, // WRITE_ICC_SMS 1838 AppOpsManager.MODE_DEFAULT, // WRITE_SETTINGS 1839 getSystemAlertWindowDefault(), // SYSTEM_ALERT_WINDOW 1840 AppOpsManager.MODE_ALLOWED, // ACCESS_NOTIFICATIONS 1841 AppOpsManager.MODE_ALLOWED, // CAMERA 1842 AppOpsManager.MODE_ALLOWED, // RECORD_AUDIO 1843 AppOpsManager.MODE_ALLOWED, // PLAY_AUDIO 1844 AppOpsManager.MODE_ALLOWED, // READ_CLIPBOARD 1845 AppOpsManager.MODE_ALLOWED, // WRITE_CLIPBOARD 1846 AppOpsManager.MODE_ALLOWED, // TAKE_MEDIA_BUTTONS 1847 AppOpsManager.MODE_ALLOWED, // TAKE_AUDIO_FOCUS 1848 AppOpsManager.MODE_ALLOWED, // AUDIO_MASTER_VOLUME 1849 AppOpsManager.MODE_ALLOWED, // AUDIO_VOICE_VOLUME 1850 AppOpsManager.MODE_ALLOWED, // AUDIO_RING_VOLUME 1851 AppOpsManager.MODE_ALLOWED, // AUDIO_MEDIA_VOLUME 1852 AppOpsManager.MODE_ALLOWED, // AUDIO_ALARM_VOLUME 1853 AppOpsManager.MODE_ALLOWED, // AUDIO_NOTIFICATION_VOLUME 1854 AppOpsManager.MODE_ALLOWED, // AUDIO_BLUETOOTH_VOLUME 1855 AppOpsManager.MODE_ALLOWED, // WAKE_LOCK 1856 AppOpsManager.MODE_ALLOWED, // MONITOR_LOCATION 1857 AppOpsManager.MODE_ALLOWED, // MONITOR_HIGH_POWER_LOCATION 1858 AppOpsManager.MODE_DEFAULT, // GET_USAGE_STATS 1859 AppOpsManager.MODE_ALLOWED, // MUTE_MICROPHONE 1860 AppOpsManager.MODE_ALLOWED, // TOAST_WINDOW 1861 AppOpsManager.MODE_IGNORED, // PROJECT_MEDIA 1862 AppOpsManager.MODE_IGNORED, // ACTIVATE_VPN 1863 AppOpsManager.MODE_ALLOWED, // WRITE_WALLPAPER 1864 AppOpsManager.MODE_ALLOWED, // ASSIST_STRUCTURE 1865 AppOpsManager.MODE_ALLOWED, // ASSIST_SCREENSHOT 1866 AppOpsManager.MODE_ALLOWED, // READ_PHONE_STATE 1867 AppOpsManager.MODE_ALLOWED, // ADD_VOICEMAIL 1868 AppOpsManager.MODE_ALLOWED, // USE_SIP 1869 AppOpsManager.MODE_ALLOWED, // PROCESS_OUTGOING_CALLS 1870 AppOpsManager.MODE_ALLOWED, // USE_FINGERPRINT 1871 AppOpsManager.MODE_ALLOWED, // BODY_SENSORS 1872 AppOpsManager.MODE_ALLOWED, // READ_CELL_BROADCASTS 1873 AppOpsManager.MODE_ERRORED, // MOCK_LOCATION 1874 AppOpsManager.MODE_ALLOWED, // READ_EXTERNAL_STORAGE 1875 AppOpsManager.MODE_ALLOWED, // WRITE_EXTERNAL_STORAGE 1876 AppOpsManager.MODE_ALLOWED, // TURN_SCREEN_ON 1877 AppOpsManager.MODE_ALLOWED, // GET_ACCOUNTS 1878 AppOpsManager.MODE_ALLOWED, // RUN_IN_BACKGROUND 1879 AppOpsManager.MODE_ALLOWED, // AUDIO_ACCESSIBILITY_VOLUME 1880 AppOpsManager.MODE_ALLOWED, // READ_PHONE_NUMBERS 1881 AppOpsManager.MODE_DEFAULT, // REQUEST_INSTALL_PACKAGES 1882 AppOpsManager.MODE_ALLOWED, // PICTURE_IN_PICTURE 1883 AppOpsManager.MODE_DEFAULT, // INSTANT_APP_START_FOREGROUND 1884 AppOpsManager.MODE_ALLOWED, // ANSWER_PHONE_CALLS 1885 AppOpsManager.MODE_ALLOWED, // RUN_ANY_IN_BACKGROUND 1886 AppOpsManager.MODE_ALLOWED, // CHANGE_WIFI_STATE 1887 AppOpsManager.MODE_ALLOWED, // REQUEST_DELETE_PACKAGES 1888 AppOpsManager.MODE_ALLOWED, // BIND_ACCESSIBILITY_SERVICE 1889 AppOpsManager.MODE_ALLOWED, // ACCEPT_HANDOVER 1890 AppOpsManager.MODE_ERRORED, // MANAGE_IPSEC_TUNNELS 1891 AppOpsManager.MODE_ALLOWED, // START_FOREGROUND 1892 AppOpsManager.MODE_ALLOWED, // BLUETOOTH_SCAN 1893 AppOpsManager.MODE_ALLOWED, // USE_BIOMETRIC 1894 AppOpsManager.MODE_ALLOWED, // ACTIVITY_RECOGNITION 1895 AppOpsManager.MODE_DEFAULT, // SMS_FINANCIAL_TRANSACTIONS 1896 AppOpsManager.MODE_ALLOWED, // READ_MEDIA_AUDIO 1897 AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_AUDIO 1898 AppOpsManager.MODE_ALLOWED, // READ_MEDIA_VIDEO 1899 AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_VIDEO 1900 AppOpsManager.MODE_ALLOWED, // READ_MEDIA_IMAGES 1901 AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_IMAGES 1902 AppOpsManager.MODE_DEFAULT, // LEGACY_STORAGE 1903 AppOpsManager.MODE_ALLOWED, // ACCESS_ACCESSIBILITY 1904 AppOpsManager.MODE_ERRORED, // READ_DEVICE_IDENTIFIERS 1905 AppOpsManager.MODE_ALLOWED, // ALLOW_MEDIA_LOCATION 1906 AppOpsManager.MODE_IGNORED, // ACTIVATE_PLATFORM_VPN 1907 }; 1908 1909 /** 1910 * This specifies whether each option is allowed to be reset 1911 * when resetting all app preferences. Disable reset for 1912 * app ops that are under strong control of some part of the 1913 * system (such as OP_WRITE_SMS, which should be allowed only 1914 * for whichever app is selected as the current SMS app). 1915 */ 1916 private static boolean[] sOpDisableReset = new boolean[] { 1917 false, // COARSE_LOCATION 1918 false, // FINE_LOCATION 1919 false, // GPS 1920 false, // VIBRATE 1921 false, // READ_CONTACTS 1922 false, // WRITE_CONTACTS 1923 false, // READ_CALL_LOG 1924 false, // WRITE_CALL_LOG 1925 false, // READ_CALENDAR 1926 false, // WRITE_CALENDAR 1927 false, // WIFI_SCAN 1928 false, // POST_NOTIFICATION 1929 false, // NEIGHBORING_CELLS 1930 false, // CALL_PHONE 1931 true, // READ_SMS 1932 true, // WRITE_SMS 1933 true, // RECEIVE_SMS 1934 false, // RECEIVE_EMERGENCY_BROADCAST 1935 false, // RECEIVE_MMS 1936 true, // RECEIVE_WAP_PUSH 1937 true, // SEND_SMS 1938 false, // READ_ICC_SMS 1939 false, // WRITE_ICC_SMS 1940 false, // WRITE_SETTINGS 1941 false, // SYSTEM_ALERT_WINDOW 1942 false, // ACCESS_NOTIFICATIONS 1943 false, // CAMERA 1944 false, // RECORD_AUDIO 1945 false, // PLAY_AUDIO 1946 false, // READ_CLIPBOARD 1947 false, // WRITE_CLIPBOARD 1948 false, // TAKE_MEDIA_BUTTONS 1949 false, // TAKE_AUDIO_FOCUS 1950 false, // AUDIO_MASTER_VOLUME 1951 false, // AUDIO_VOICE_VOLUME 1952 false, // AUDIO_RING_VOLUME 1953 false, // AUDIO_MEDIA_VOLUME 1954 false, // AUDIO_ALARM_VOLUME 1955 false, // AUDIO_NOTIFICATION_VOLUME 1956 false, // AUDIO_BLUETOOTH_VOLUME 1957 false, // WAKE_LOCK 1958 false, // MONITOR_LOCATION 1959 false, // MONITOR_HIGH_POWER_LOCATION 1960 false, // GET_USAGE_STATS 1961 false, // MUTE_MICROPHONE 1962 false, // TOAST_WINDOW 1963 false, // PROJECT_MEDIA 1964 false, // ACTIVATE_VPN 1965 false, // WRITE_WALLPAPER 1966 false, // ASSIST_STRUCTURE 1967 false, // ASSIST_SCREENSHOT 1968 false, // READ_PHONE_STATE 1969 false, // ADD_VOICEMAIL 1970 false, // USE_SIP 1971 false, // PROCESS_OUTGOING_CALLS 1972 false, // USE_FINGERPRINT 1973 false, // BODY_SENSORS 1974 true, // READ_CELL_BROADCASTS 1975 false, // MOCK_LOCATION 1976 false, // READ_EXTERNAL_STORAGE 1977 false, // WRITE_EXTERNAL_STORAGE 1978 false, // TURN_SCREEN_ON 1979 false, // GET_ACCOUNTS 1980 false, // RUN_IN_BACKGROUND 1981 false, // AUDIO_ACCESSIBILITY_VOLUME 1982 false, // READ_PHONE_NUMBERS 1983 false, // REQUEST_INSTALL_PACKAGES 1984 false, // PICTURE_IN_PICTURE 1985 false, // INSTANT_APP_START_FOREGROUND 1986 false, // ANSWER_PHONE_CALLS 1987 false, // RUN_ANY_IN_BACKGROUND 1988 false, // CHANGE_WIFI_STATE 1989 false, // REQUEST_DELETE_PACKAGES 1990 false, // BIND_ACCESSIBILITY_SERVICE 1991 false, // ACCEPT_HANDOVER 1992 false, // MANAGE_IPSEC_TUNNELS 1993 false, // START_FOREGROUND 1994 false, // BLUETOOTH_SCAN 1995 false, // USE_BIOMETRIC 1996 false, // ACTIVITY_RECOGNITION 1997 false, // SMS_FINANCIAL_TRANSACTIONS 1998 false, // READ_MEDIA_AUDIO 1999 false, // WRITE_MEDIA_AUDIO 2000 false, // READ_MEDIA_VIDEO 2001 false, // WRITE_MEDIA_VIDEO 2002 false, // READ_MEDIA_IMAGES 2003 false, // WRITE_MEDIA_IMAGES 2004 false, // LEGACY_STORAGE 2005 false, // ACCESS_ACCESSIBILITY 2006 false, // READ_DEVICE_IDENTIFIERS 2007 false, // ACCESS_MEDIA_LOCATION 2008 false, // ACTIVATE_PLATFORM_VPN 2009 }; 2010 2011 /** 2012 * Mapping from an app op name to the app op code. 2013 */ 2014 private static HashMap<String, Integer> sOpStrToOp = new HashMap<>(); 2015 2016 /** 2017 * Mapping from a permission to the corresponding app op. 2018 */ 2019 private static HashMap<String, Integer> sPermToOp = new HashMap<>(); 2020 2021 static { 2022 if (sOpToSwitch.length != _NUM_OP) { 2023 throw new IllegalStateException("sOpToSwitch length " + sOpToSwitch.length 2024 + " should be " + _NUM_OP); 2025 } 2026 if (sOpToString.length != _NUM_OP) { 2027 throw new IllegalStateException("sOpToString length " + sOpToString.length 2028 + " should be " + _NUM_OP); 2029 } 2030 if (sOpNames.length != _NUM_OP) { 2031 throw new IllegalStateException("sOpNames length " + sOpNames.length 2032 + " should be " + _NUM_OP); 2033 } 2034 if (sOpPerms.length != _NUM_OP) { 2035 throw new IllegalStateException("sOpPerms length " + sOpPerms.length 2036 + " should be " + _NUM_OP); 2037 } 2038 if (sOpDefaultMode.length != _NUM_OP) { 2039 throw new IllegalStateException("sOpDefaultMode length " + sOpDefaultMode.length 2040 + " should be " + _NUM_OP); 2041 } 2042 if (sOpDisableReset.length != _NUM_OP) { 2043 throw new IllegalStateException("sOpDisableReset length " + sOpDisableReset.length 2044 + " should be " + _NUM_OP); 2045 } 2046 if (sOpRestrictions.length != _NUM_OP) { 2047 throw new IllegalStateException("sOpRestrictions length " + sOpRestrictions.length 2048 + " should be " + _NUM_OP); 2049 } 2050 if (sOpAllowSystemRestrictionBypass.length != _NUM_OP) { 2051 throw new IllegalStateException("sOpAllowSYstemRestrictionsBypass length " 2052 + sOpRestrictions.length + " should be " + _NUM_OP); 2053 } 2054 for (int i=0; i<_NUM_OP; i++) { 2055 if (sOpToString[i] != null) { sOpStrToOp.put(sOpToString[i], i)2056 sOpStrToOp.put(sOpToString[i], i); 2057 } 2058 } 2059 for (int op : RUNTIME_AND_APPOP_PERMISSIONS_OPS) { 2060 if (sOpPerms[op] != null) { sPermToOp.put(sOpPerms[op], op)2061 sPermToOp.put(sOpPerms[op], op); 2062 } 2063 } 2064 } 2065 2066 /** @hide */ 2067 public static final String KEY_HISTORICAL_OPS = "historical_ops"; 2068 2069 /** System properties for debug logging of noteOp call sites */ 2070 private static final String DEBUG_LOGGING_ENABLE_PROP = "appops.logging_enabled"; 2071 private static final String DEBUG_LOGGING_PACKAGES_PROP = "appops.logging_packages"; 2072 private static final String DEBUG_LOGGING_OPS_PROP = "appops.logging_ops"; 2073 private static final String DEBUG_LOGGING_TAG = "AppOpsManager"; 2074 2075 /** 2076 * Retrieve the op switch that controls the given operation. 2077 * @hide 2078 */ 2079 @UnsupportedAppUsage opToSwitch(int op)2080 public static int opToSwitch(int op) { 2081 return sOpToSwitch[op]; 2082 } 2083 2084 /** 2085 * Retrieve a non-localized name for the operation, for debugging output. 2086 * @hide 2087 */ 2088 @UnsupportedAppUsage opToName(int op)2089 public static String opToName(int op) { 2090 if (op == OP_NONE) return "NONE"; 2091 return op < sOpNames.length ? sOpNames[op] : ("Unknown(" + op + ")"); 2092 } 2093 2094 /** 2095 * Retrieve a non-localized public name for the operation. 2096 * 2097 * @hide 2098 */ opToPublicName(int op)2099 public static @NonNull String opToPublicName(int op) { 2100 return sOpToString[op]; 2101 } 2102 2103 /** 2104 * @hide 2105 */ strDebugOpToOp(String op)2106 public static int strDebugOpToOp(String op) { 2107 for (int i=0; i<sOpNames.length; i++) { 2108 if (sOpNames[i].equals(op)) { 2109 return i; 2110 } 2111 } 2112 throw new IllegalArgumentException("Unknown operation string: " + op); 2113 } 2114 2115 /** 2116 * Retrieve the permission associated with an operation, or null if there is not one. 2117 * @hide 2118 */ 2119 @UnsupportedAppUsage 2120 @TestApi opToPermission(int op)2121 public static String opToPermission(int op) { 2122 return sOpPerms[op]; 2123 } 2124 2125 /** 2126 * Retrieve the permission associated with an operation, or null if there is not one. 2127 * 2128 * @param op The operation name. 2129 * 2130 * @hide 2131 */ 2132 @Nullable 2133 @SystemApi opToPermission(@onNull String op)2134 public static String opToPermission(@NonNull String op) { 2135 return opToPermission(strOpToOp(op)); 2136 } 2137 2138 /** 2139 * Retrieve the user restriction associated with an operation, or null if there is not one. 2140 * @hide 2141 */ opToRestriction(int op)2142 public static String opToRestriction(int op) { 2143 return sOpRestrictions[op]; 2144 } 2145 2146 /** 2147 * Retrieve the app op code for a permission, or null if there is not one. 2148 * This API is intended to be used for mapping runtime or appop permissions 2149 * to the corresponding app op. 2150 * @hide 2151 */ 2152 @UnsupportedAppUsage 2153 @TestApi permissionToOpCode(String permission)2154 public static int permissionToOpCode(String permission) { 2155 Integer boxedOpCode = sPermToOp.get(permission); 2156 return boxedOpCode != null ? boxedOpCode : OP_NONE; 2157 } 2158 2159 /** 2160 * Retrieve whether the op allows the system (and system ui) to 2161 * bypass the user restriction. 2162 * @hide 2163 */ opAllowSystemBypassRestriction(int op)2164 public static boolean opAllowSystemBypassRestriction(int op) { 2165 return sOpAllowSystemRestrictionBypass[op]; 2166 } 2167 2168 /** 2169 * Retrieve the default mode for the operation. 2170 * @hide 2171 */ opToDefaultMode(int op)2172 public static @Mode int opToDefaultMode(int op) { 2173 return sOpDefaultMode[op]; 2174 } 2175 2176 /** 2177 * Retrieve the default mode for the app op. 2178 * 2179 * @param appOp The app op name 2180 * 2181 * @return the default mode for the app op 2182 * 2183 * @hide 2184 */ 2185 @TestApi 2186 @SystemApi opToDefaultMode(@onNull String appOp)2187 public static int opToDefaultMode(@NonNull String appOp) { 2188 return opToDefaultMode(strOpToOp(appOp)); 2189 } 2190 2191 /** 2192 * Retrieve the human readable mode. 2193 * @hide 2194 */ modeToName(@ode int mode)2195 public static String modeToName(@Mode int mode) { 2196 if (mode >= 0 && mode < MODE_NAMES.length) { 2197 return MODE_NAMES[mode]; 2198 } 2199 return "mode=" + mode; 2200 } 2201 2202 /** 2203 * Retrieve whether the op allows itself to be reset. 2204 * @hide 2205 */ opAllowsReset(int op)2206 public static boolean opAllowsReset(int op) { 2207 return !sOpDisableReset[op]; 2208 } 2209 2210 /** 2211 * Class holding all of the operation information associated with an app. 2212 * @hide 2213 */ 2214 @SystemApi 2215 public static final class PackageOps implements Parcelable { 2216 private final String mPackageName; 2217 private final int mUid; 2218 private final List<OpEntry> mEntries; 2219 2220 /** 2221 * @hide 2222 */ 2223 @UnsupportedAppUsage PackageOps(String packageName, int uid, List<OpEntry> entries)2224 public PackageOps(String packageName, int uid, List<OpEntry> entries) { 2225 mPackageName = packageName; 2226 mUid = uid; 2227 mEntries = entries; 2228 } 2229 2230 /** 2231 * @return The name of the package. 2232 */ getPackageName()2233 public @NonNull String getPackageName() { 2234 return mPackageName; 2235 } 2236 2237 /** 2238 * @return The uid of the package. 2239 */ getUid()2240 public int getUid() { 2241 return mUid; 2242 } 2243 2244 /** 2245 * @return The ops of the package. 2246 */ getOps()2247 public @NonNull List<OpEntry> getOps() { 2248 return mEntries; 2249 } 2250 2251 @Override describeContents()2252 public int describeContents() { 2253 return 0; 2254 } 2255 2256 @Override writeToParcel(Parcel dest, int flags)2257 public void writeToParcel(Parcel dest, int flags) { 2258 dest.writeString(mPackageName); 2259 dest.writeInt(mUid); 2260 dest.writeInt(mEntries.size()); 2261 for (int i=0; i<mEntries.size(); i++) { 2262 mEntries.get(i).writeToParcel(dest, flags); 2263 } 2264 } 2265 PackageOps(Parcel source)2266 PackageOps(Parcel source) { 2267 mPackageName = source.readString(); 2268 mUid = source.readInt(); 2269 mEntries = new ArrayList<OpEntry>(); 2270 final int N = source.readInt(); 2271 for (int i=0; i<N; i++) { 2272 mEntries.add(OpEntry.CREATOR.createFromParcel(source)); 2273 } 2274 } 2275 2276 public static final @android.annotation.NonNull Creator<PackageOps> CREATOR = new Creator<PackageOps>() { 2277 @Override public PackageOps createFromParcel(Parcel source) { 2278 return new PackageOps(source); 2279 } 2280 2281 @Override public PackageOps[] newArray(int size) { 2282 return new PackageOps[size]; 2283 } 2284 }; 2285 } 2286 2287 /** 2288 * Class holding the information about one unique operation of an application. 2289 * @hide 2290 */ 2291 @TestApi 2292 @Immutable 2293 @SystemApi 2294 public static final class OpEntry implements Parcelable { 2295 private final int mOp; 2296 private final boolean mRunning; 2297 private final @Mode int mMode; 2298 private final @Nullable LongSparseLongArray mAccessTimes; 2299 private final @Nullable LongSparseLongArray mRejectTimes; 2300 private final @Nullable LongSparseLongArray mDurations; 2301 private final @Nullable LongSparseLongArray mProxyUids; 2302 private final @Nullable LongSparseArray<String> mProxyPackageNames; 2303 2304 /** 2305 * @hide 2306 */ OpEntry(int op, boolean running, @Mode int mode, @Nullable LongSparseLongArray accessTimes, @Nullable LongSparseLongArray rejectTimes, @Nullable LongSparseLongArray durations, @Nullable LongSparseLongArray proxyUids, @Nullable LongSparseArray<String> proxyPackageNames)2307 public OpEntry(int op, boolean running, @Mode int mode, 2308 @Nullable LongSparseLongArray accessTimes, @Nullable LongSparseLongArray rejectTimes, 2309 @Nullable LongSparseLongArray durations, @Nullable LongSparseLongArray proxyUids, 2310 @Nullable LongSparseArray<String> proxyPackageNames) { 2311 mOp = op; 2312 mRunning = running; 2313 mMode = mode; 2314 mAccessTimes = accessTimes; 2315 mRejectTimes = rejectTimes; 2316 mDurations = durations; 2317 mProxyUids = proxyUids; 2318 mProxyPackageNames = proxyPackageNames; 2319 } 2320 2321 /** 2322 * @hide 2323 */ OpEntry(int op, @Mode int mode)2324 public OpEntry(int op, @Mode int mode) { 2325 mOp = op; 2326 mMode = mode; 2327 mRunning = false; 2328 mAccessTimes = null; 2329 mRejectTimes = null; 2330 mDurations = null; 2331 mProxyUids = null; 2332 mProxyPackageNames = null; 2333 } 2334 2335 /** 2336 * Returns all keys for which we have mapped state in any of the data buckets - 2337 * access time, reject time, duration. 2338 * @hide */ collectKeys()2339 public @Nullable LongSparseArray<Object> collectKeys() { 2340 LongSparseArray<Object> result = AppOpsManager.collectKeys(mAccessTimes, null); 2341 result = AppOpsManager.collectKeys(mRejectTimes, result); 2342 result = AppOpsManager.collectKeys(mDurations, result); 2343 return result; 2344 } 2345 2346 /** 2347 * @hide 2348 */ 2349 @UnsupportedAppUsage getOp()2350 public int getOp() { 2351 return mOp; 2352 } 2353 2354 /** 2355 * @return This entry's op string name, such as {@link #OPSTR_COARSE_LOCATION}. 2356 */ getOpStr()2357 public @NonNull String getOpStr() { 2358 return sOpToString[mOp]; 2359 } 2360 2361 /** 2362 * @return this entry's current mode, such as {@link #MODE_ALLOWED}. 2363 */ getMode()2364 public @Mode int getMode() { 2365 return mMode; 2366 } 2367 2368 /** 2369 * @hide 2370 */ 2371 @UnsupportedAppUsage getTime()2372 public long getTime() { 2373 return getLastAccessTime(OP_FLAGS_ALL); 2374 } 2375 2376 /** 2377 * Return the last wall clock time in milliseconds this op was accessed. 2378 * 2379 * @param flags The flags which are any combination of 2380 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 2381 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 2382 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 2383 * for any flag. 2384 * @return the last access time in milliseconds since 2385 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). 2386 * 2387 * @see #getLastAccessForegroundTime(int) 2388 * @see #getLastAccessBackgroundTime(int) 2389 * @see #getLastAccessTime(int, int, int) 2390 */ getLastAccessTime(@pFlags int flags)2391 public long getLastAccessTime(@OpFlags int flags) { 2392 return maxForFlagsInStates(mAccessTimes, MAX_PRIORITY_UID_STATE, 2393 MIN_PRIORITY_UID_STATE, flags); 2394 } 2395 2396 /** 2397 * Return the last wall clock time in milliseconds this op was accessed 2398 * by the app while in the foreground. 2399 * 2400 * @param flags The flags which are any combination of 2401 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 2402 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 2403 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 2404 * for any flag. 2405 * @return the last foreground access time in milliseconds since 2406 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). 2407 * 2408 * @see #getLastAccessBackgroundTime(int) 2409 * @see #getLastAccessTime(int) 2410 * @see #getLastAccessTime(int, int, int) 2411 */ getLastAccessForegroundTime(@pFlags int flags)2412 public long getLastAccessForegroundTime(@OpFlags int flags) { 2413 return maxForFlagsInStates(mAccessTimes, MAX_PRIORITY_UID_STATE, 2414 resolveFirstUnrestrictedUidState(mOp), flags); 2415 } 2416 2417 /** 2418 * Return the last wall clock time in milliseconds this op was accessed 2419 * by the app while in the background. 2420 * 2421 * @param flags The flags which are any combination of 2422 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 2423 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 2424 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 2425 * for any flag. 2426 * @return the last foreground access time in milliseconds since 2427 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). 2428 * 2429 * @see #getLastAccessForegroundTime(int) 2430 * @see #getLastAccessTime(int) 2431 * @see #getLastAccessTime(int, int, int) 2432 */ getLastAccessBackgroundTime(@pFlags int flags)2433 public long getLastAccessBackgroundTime(@OpFlags int flags) { 2434 return maxForFlagsInStates(mAccessTimes, resolveLastRestrictedUidState(mOp), 2435 MIN_PRIORITY_UID_STATE, flags); 2436 } 2437 2438 /** 2439 * Return the last wall clock time in milliseconds this op was accessed 2440 * by the app for a given range of UID states. 2441 * 2442 * @param fromUidState The UID state for which to query. Could be one of 2443 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP}, 2444 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND}, 2445 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}. 2446 * @param toUidState The UID state for which to query. 2447 * @param flags The flags which are any combination of 2448 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 2449 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 2450 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 2451 * for any flag. 2452 * 2453 * @return the last foreground access time in milliseconds since 2454 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). 2455 * 2456 * @see #getLastAccessForegroundTime(int) 2457 * @see #getLastAccessBackgroundTime(int) 2458 * @see #getLastAccessTime(int) 2459 */ getLastAccessTime(@idState int fromUidState, @UidState int toUidState, @OpFlags int flags)2460 public long getLastAccessTime(@UidState int fromUidState, @UidState int toUidState, 2461 @OpFlags int flags) { 2462 return maxForFlagsInStates(mAccessTimes, fromUidState, toUidState, flags); 2463 } 2464 2465 /** 2466 * @hide 2467 */ 2468 @UnsupportedAppUsage getRejectTime()2469 public long getRejectTime() { 2470 return getLastRejectTime(OP_FLAGS_ALL); 2471 } 2472 2473 /** 2474 * Return the last wall clock time in milliseconds the app made an attempt 2475 * to access this op but was rejected. 2476 * 2477 * @param flags The flags which are any combination of 2478 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 2479 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 2480 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 2481 * for any flag. 2482 * @return the last reject time in milliseconds since 2483 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). 2484 * 2485 * @see #getLastRejectBackgroundTime(int) 2486 * @see #getLastRejectForegroundTime(int) 2487 * @see #getLastRejectTime(int, int, int) 2488 */ getLastRejectTime(@pFlags int flags)2489 public long getLastRejectTime(@OpFlags int flags) { 2490 return maxForFlagsInStates(mRejectTimes, MAX_PRIORITY_UID_STATE, 2491 MIN_PRIORITY_UID_STATE, flags); 2492 } 2493 2494 /** 2495 * Return the last wall clock time in milliseconds the app made an attempt 2496 * to access this op while in the foreground but was rejected. 2497 * 2498 * @param flags The flags which are any combination of 2499 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 2500 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 2501 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 2502 * for any flag. 2503 * @return the last foreground reject time in milliseconds since 2504 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). 2505 * 2506 * @see #getLastRejectBackgroundTime(int) 2507 * @see #getLastRejectTime(int, int, int) 2508 * @see #getLastRejectTime(int) 2509 */ getLastRejectForegroundTime(@pFlags int flags)2510 public long getLastRejectForegroundTime(@OpFlags int flags) { 2511 return maxForFlagsInStates(mRejectTimes, MAX_PRIORITY_UID_STATE, 2512 resolveFirstUnrestrictedUidState(mOp), flags); 2513 } 2514 2515 /** 2516 * Return the last wall clock time in milliseconds the app made an attempt 2517 * to access this op while in the background but was rejected. 2518 * 2519 * @param flags The flags which are any combination of 2520 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 2521 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 2522 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 2523 * for any flag. 2524 * @return the last background reject time in milliseconds since 2525 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). 2526 * 2527 * @see #getLastRejectForegroundTime(int) 2528 * @see #getLastRejectTime(int, int, int) 2529 * @see #getLastRejectTime(int) 2530 */ getLastRejectBackgroundTime(@pFlags int flags)2531 public long getLastRejectBackgroundTime(@OpFlags int flags) { 2532 return maxForFlagsInStates(mRejectTimes, resolveLastRestrictedUidState(mOp), 2533 MIN_PRIORITY_UID_STATE, flags); 2534 } 2535 2536 /** 2537 * Return the last wall clock time state in milliseconds the app made an 2538 * attempt to access this op for a given range of UID states. 2539 * 2540 * @param fromUidState The UID state from which to query. Could be one of 2541 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP}, 2542 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND}, 2543 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}. 2544 * @param toUidState The UID state to which to query. 2545 * @param flags The flags which are any combination of 2546 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 2547 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 2548 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 2549 * for any flag. 2550 * @return the last foreground access time in milliseconds since 2551 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). 2552 * 2553 * @see #getLastRejectForegroundTime(int) 2554 * @see #getLastRejectBackgroundTime(int) 2555 * @see #getLastRejectTime(int) 2556 */ getLastRejectTime(@idState int fromUidState, @UidState int toUidState, @OpFlags int flags)2557 public long getLastRejectTime(@UidState int fromUidState, @UidState int toUidState, 2558 @OpFlags int flags) { 2559 return maxForFlagsInStates(mRejectTimes, fromUidState, toUidState, flags); 2560 } 2561 2562 /** 2563 * @return Whether the operation is running. 2564 */ isRunning()2565 public boolean isRunning() { 2566 return mRunning; 2567 } 2568 2569 /** 2570 * @return The duration of the operation in milliseconds. The duration is in wall time. 2571 */ getDuration()2572 public long getDuration() { 2573 return getLastDuration(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL); 2574 } 2575 2576 /** 2577 * Return the duration in milliseconds the app accessed this op while 2578 * in the foreground. The duration is in wall time. 2579 * 2580 * @param flags The flags which are any combination of 2581 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 2582 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 2583 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 2584 * for any flag. 2585 * @return the foreground access duration in milliseconds. 2586 * 2587 * @see #getLastBackgroundDuration(int) 2588 * @see #getLastDuration(int, int, int) 2589 */ getLastForegroundDuration(@pFlags int flags)2590 public long getLastForegroundDuration(@OpFlags int flags) { 2591 return sumForFlagsInStates(mDurations, MAX_PRIORITY_UID_STATE, 2592 resolveFirstUnrestrictedUidState(mOp), flags); 2593 } 2594 2595 /** 2596 * Return the duration in milliseconds the app accessed this op while 2597 * in the background. The duration is in wall time. 2598 * 2599 * @param flags The flags which are any combination of 2600 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 2601 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 2602 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 2603 * for any flag. 2604 * @return the background access duration in milliseconds. 2605 * 2606 * @see #getLastForegroundDuration(int) 2607 * @see #getLastDuration(int, int, int) 2608 */ getLastBackgroundDuration(@pFlags int flags)2609 public long getLastBackgroundDuration(@OpFlags int flags) { 2610 return sumForFlagsInStates(mDurations, resolveLastRestrictedUidState(mOp), 2611 MIN_PRIORITY_UID_STATE, flags); 2612 } 2613 2614 /** 2615 * Return the duration in milliseconds the app accessed this op for 2616 * a given range of UID states. The duration is in wall time. 2617 * 2618 * @param fromUidState The UID state for which to query. Could be one of 2619 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP}, 2620 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND}, 2621 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}. 2622 * @param toUidState The UID state for which to query. 2623 * @param flags The flags which are any combination of 2624 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 2625 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 2626 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 2627 * for any flag. 2628 * @return the access duration in milliseconds. 2629 */ getLastDuration(@idState int fromUidState, @UidState int toUidState, @OpFlags int flags)2630 public long getLastDuration(@UidState int fromUidState, @UidState int toUidState, 2631 @OpFlags int flags) { 2632 return sumForFlagsInStates(mDurations, fromUidState, toUidState, flags); 2633 } 2634 2635 /** 2636 * Gets the UID of the app that performed the op on behalf of this app and 2637 * as a result blamed the op on this app or {@link Process#INVALID_UID} if 2638 * there is no proxy. 2639 * 2640 * @return The proxy UID. 2641 */ getProxyUid()2642 public int getProxyUid() { 2643 return (int) findFirstNonNegativeForFlagsInStates(mProxyUids, 2644 MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL); 2645 } 2646 2647 /** 2648 * Gets the UID of the app that performed the op on behalf of this app and 2649 * as a result blamed the op on this app or {@link Process#INVALID_UID} if 2650 * there is no proxy. 2651 * 2652 * @param uidState The UID state for which to query. Could be one of 2653 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP}, 2654 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND}, 2655 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}. 2656 * @param flags The flags which are any combination of 2657 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 2658 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 2659 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 2660 * for any flag. 2661 * 2662 * @return The proxy UID. 2663 */ getProxyUid(@idState int uidState, @OpFlags int flags)2664 public int getProxyUid(@UidState int uidState, @OpFlags int flags) { 2665 return (int) findFirstNonNegativeForFlagsInStates(mProxyUids, 2666 uidState, uidState, flags); 2667 } 2668 2669 /** 2670 * Gets the package name of the app that performed the op on behalf of this 2671 * app and as a result blamed the op on this app or {@code null} 2672 * if there is no proxy. 2673 * 2674 * @return The proxy package name. 2675 */ getProxyPackageName()2676 public @Nullable String getProxyPackageName() { 2677 return findFirstNonNullForFlagsInStates(mProxyPackageNames, MAX_PRIORITY_UID_STATE, 2678 MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL); 2679 } 2680 2681 /** 2682 * Gets the package name of the app that performed the op on behalf of this 2683 * app and as a result blamed the op on this app for a UID state or 2684 * {@code null} if there is no proxy. 2685 * 2686 * @param uidState The UID state for which to query. Could be one of 2687 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP}, 2688 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND}, 2689 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}. 2690 * @param flags The flags which are any combination of 2691 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 2692 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 2693 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 2694 * for any flag. 2695 * @return The proxy package name. 2696 */ getProxyPackageName(@idState int uidState, @OpFlags int flags)2697 public @Nullable String getProxyPackageName(@UidState int uidState, @OpFlags int flags) { 2698 return findFirstNonNullForFlagsInStates(mProxyPackageNames, uidState, uidState, flags); 2699 } 2700 2701 @Override describeContents()2702 public int describeContents() { 2703 return 0; 2704 } 2705 2706 @Override writeToParcel(Parcel dest, int flags)2707 public void writeToParcel(Parcel dest, int flags) { 2708 dest.writeInt(mOp); 2709 dest.writeInt(mMode); 2710 dest.writeBoolean(mRunning); 2711 writeLongSparseLongArrayToParcel(mAccessTimes, dest); 2712 writeLongSparseLongArrayToParcel(mRejectTimes, dest); 2713 writeLongSparseLongArrayToParcel(mDurations, dest); 2714 writeLongSparseLongArrayToParcel(mProxyUids, dest); 2715 writeLongSparseStringArrayToParcel(mProxyPackageNames, dest); 2716 } 2717 OpEntry(Parcel source)2718 OpEntry(Parcel source) { 2719 mOp = source.readInt(); 2720 mMode = source.readInt(); 2721 mRunning = source.readBoolean(); 2722 mAccessTimes = readLongSparseLongArrayFromParcel(source); 2723 mRejectTimes = readLongSparseLongArrayFromParcel(source); 2724 mDurations = readLongSparseLongArrayFromParcel(source); 2725 mProxyUids = readLongSparseLongArrayFromParcel(source); 2726 mProxyPackageNames = readLongSparseStringArrayFromParcel(source); 2727 } 2728 2729 public static final @android.annotation.NonNull Creator<OpEntry> CREATOR = new Creator<OpEntry>() { 2730 @Override public OpEntry createFromParcel(Parcel source) { 2731 return new OpEntry(source); 2732 } 2733 2734 @Override public OpEntry[] newArray(int size) { 2735 return new OpEntry[size]; 2736 } 2737 }; 2738 } 2739 2740 /** @hide */ 2741 public interface HistoricalOpsVisitor { visitHistoricalOps(@onNull HistoricalOps ops)2742 void visitHistoricalOps(@NonNull HistoricalOps ops); visitHistoricalUidOps(@onNull HistoricalUidOps ops)2743 void visitHistoricalUidOps(@NonNull HistoricalUidOps ops); visitHistoricalPackageOps(@onNull HistoricalPackageOps ops)2744 void visitHistoricalPackageOps(@NonNull HistoricalPackageOps ops); visitHistoricalOp(@onNull HistoricalOp ops)2745 void visitHistoricalOp(@NonNull HistoricalOp ops); 2746 } 2747 2748 /** 2749 * Request for getting historical app op usage. The request acts 2750 * as a filtering criteria when querying historical op usage. 2751 * 2752 * @hide 2753 */ 2754 @Immutable 2755 @TestApi 2756 @SystemApi 2757 public static final class HistoricalOpsRequest { 2758 private final int mUid; 2759 private final @Nullable String mPackageName; 2760 private final @Nullable List<String> mOpNames; 2761 private final long mBeginTimeMillis; 2762 private final long mEndTimeMillis; 2763 private final @OpFlags int mFlags; 2764 HistoricalOpsRequest(int uid, @Nullable String packageName, @Nullable List<String> opNames, long beginTimeMillis, long endTimeMillis, @OpFlags int flags)2765 private HistoricalOpsRequest(int uid, @Nullable String packageName, 2766 @Nullable List<String> opNames, long beginTimeMillis, long endTimeMillis, 2767 @OpFlags int flags) { 2768 mUid = uid; 2769 mPackageName = packageName; 2770 mOpNames = opNames; 2771 mBeginTimeMillis = beginTimeMillis; 2772 mEndTimeMillis = endTimeMillis; 2773 mFlags = flags; 2774 } 2775 2776 /** 2777 * Builder for creating a {@link HistoricalOpsRequest}. 2778 * 2779 * @hide 2780 */ 2781 @TestApi 2782 @SystemApi 2783 public static final class Builder { 2784 private int mUid = Process.INVALID_UID; 2785 private @Nullable String mPackageName; 2786 private @Nullable List<String> mOpNames; 2787 private final long mBeginTimeMillis; 2788 private final long mEndTimeMillis; 2789 private @OpFlags int mFlags = OP_FLAGS_ALL; 2790 2791 /** 2792 * Creates a new builder. 2793 * 2794 * @param beginTimeMillis The beginning of the interval in milliseconds since 2795 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). Must be non 2796 * negative. 2797 * @param endTimeMillis The end of the interval in milliseconds since 2798 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). Must be after 2799 * {@code beginTimeMillis}. Pass {@link Long#MAX_VALUE} to get the most recent 2800 * history including ops that happen while this call is in flight. 2801 */ Builder(long beginTimeMillis, long endTimeMillis)2802 public Builder(long beginTimeMillis, long endTimeMillis) { 2803 Preconditions.checkArgument(beginTimeMillis >= 0 && beginTimeMillis < endTimeMillis, 2804 "beginTimeMillis must be non negative and lesser than endTimeMillis"); 2805 mBeginTimeMillis = beginTimeMillis; 2806 mEndTimeMillis = endTimeMillis; 2807 } 2808 2809 /** 2810 * Sets the UID to query for. 2811 * 2812 * @param uid The uid. Pass {@link android.os.Process#INVALID_UID} for any uid. 2813 * @return This builder. 2814 */ setUid(int uid)2815 public @NonNull Builder setUid(int uid) { 2816 Preconditions.checkArgument(uid == Process.INVALID_UID || uid >= 0, 2817 "uid must be " + Process.INVALID_UID + " or non negative"); 2818 mUid = uid; 2819 return this; 2820 } 2821 2822 /** 2823 * Sets the package to query for. 2824 * 2825 * @param packageName The package name. <code>Null</code> for any package. 2826 * @return This builder. 2827 */ setPackageName(@ullable String packageName)2828 public @NonNull Builder setPackageName(@Nullable String packageName) { 2829 mPackageName = packageName; 2830 return this; 2831 } 2832 2833 /** 2834 * Sets the op names to query for. 2835 * 2836 * @param opNames The op names. <code>Null</code> for any op. 2837 * @return This builder. 2838 */ setOpNames(@ullable List<String> opNames)2839 public @NonNull Builder setOpNames(@Nullable List<String> opNames) { 2840 if (opNames != null) { 2841 final int opCount = opNames.size(); 2842 for (int i = 0; i < opCount; i++) { 2843 Preconditions.checkArgument(AppOpsManager.strOpToOp( 2844 opNames.get(i)) != AppOpsManager.OP_NONE); 2845 } 2846 } 2847 mOpNames = opNames; 2848 return this; 2849 } 2850 2851 /** 2852 * Sets the op flags to query for. The flags specify the type of 2853 * op data being queried. 2854 * 2855 * @param flags The flags which are any combination of 2856 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 2857 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 2858 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 2859 * for any flag. 2860 * @return This builder. 2861 */ setFlags(@pFlags int flags)2862 public @NonNull Builder setFlags(@OpFlags int flags) { 2863 Preconditions.checkFlagsArgument(flags, OP_FLAGS_ALL); 2864 mFlags = flags; 2865 return this; 2866 } 2867 2868 /** 2869 * @return a new {@link HistoricalOpsRequest}. 2870 */ build()2871 public @NonNull HistoricalOpsRequest build() { 2872 return new HistoricalOpsRequest(mUid, mPackageName, mOpNames, 2873 mBeginTimeMillis, mEndTimeMillis, mFlags); 2874 } 2875 } 2876 } 2877 2878 /** 2879 * This class represents historical app op state of all UIDs for a given time interval. 2880 * 2881 * @hide 2882 */ 2883 @TestApi 2884 @SystemApi 2885 public static final class HistoricalOps implements Parcelable { 2886 private long mBeginTimeMillis; 2887 private long mEndTimeMillis; 2888 private @Nullable SparseArray<HistoricalUidOps> mHistoricalUidOps; 2889 2890 /** @hide */ 2891 @TestApi HistoricalOps(long beginTimeMillis, long endTimeMillis)2892 public HistoricalOps(long beginTimeMillis, long endTimeMillis) { 2893 Preconditions.checkState(beginTimeMillis <= endTimeMillis); 2894 mBeginTimeMillis = beginTimeMillis; 2895 mEndTimeMillis = endTimeMillis; 2896 } 2897 2898 /** @hide */ HistoricalOps(@onNull HistoricalOps other)2899 public HistoricalOps(@NonNull HistoricalOps other) { 2900 mBeginTimeMillis = other.mBeginTimeMillis; 2901 mEndTimeMillis = other.mEndTimeMillis; 2902 Preconditions.checkState(mBeginTimeMillis <= mEndTimeMillis); 2903 if (other.mHistoricalUidOps != null) { 2904 final int opCount = other.getUidCount(); 2905 for (int i = 0; i < opCount; i++) { 2906 final HistoricalUidOps origOps = other.getUidOpsAt(i); 2907 final HistoricalUidOps clonedOps = new HistoricalUidOps(origOps); 2908 if (mHistoricalUidOps == null) { 2909 mHistoricalUidOps = new SparseArray<>(opCount); 2910 } 2911 mHistoricalUidOps.put(clonedOps.getUid(), clonedOps); 2912 } 2913 } 2914 } 2915 HistoricalOps(Parcel parcel)2916 private HistoricalOps(Parcel parcel) { 2917 mBeginTimeMillis = parcel.readLong(); 2918 mEndTimeMillis = parcel.readLong(); 2919 final int[] uids = parcel.createIntArray(); 2920 if (!ArrayUtils.isEmpty(uids)) { 2921 final ParceledListSlice<HistoricalUidOps> listSlice = parcel.readParcelable( 2922 HistoricalOps.class.getClassLoader()); 2923 final List<HistoricalUidOps> uidOps = (listSlice != null) 2924 ? listSlice.getList() : null; 2925 if (uidOps == null) { 2926 return; 2927 } 2928 for (int i = 0; i < uids.length; i++) { 2929 if (mHistoricalUidOps == null) { 2930 mHistoricalUidOps = new SparseArray<>(); 2931 } 2932 mHistoricalUidOps.put(uids[i], uidOps.get(i)); 2933 } 2934 } 2935 } 2936 2937 /** 2938 * Splice a piece from the beginning of these ops. 2939 * 2940 * @param splicePoint The fraction of the data to be spliced off. 2941 * 2942 * @hide 2943 */ spliceFromBeginning(double splicePoint)2944 public @NonNull HistoricalOps spliceFromBeginning(double splicePoint) { 2945 return splice(splicePoint, true); 2946 } 2947 2948 /** 2949 * Splice a piece from the end of these ops. 2950 * 2951 * @param fractionToRemove The fraction of the data to be spliced off. 2952 * 2953 * @hide 2954 */ spliceFromEnd(double fractionToRemove)2955 public @NonNull HistoricalOps spliceFromEnd(double fractionToRemove) { 2956 return splice(fractionToRemove, false); 2957 } 2958 2959 /** 2960 * Splice a piece from the beginning or end of these ops. 2961 * 2962 * @param fractionToRemove The fraction of the data to be spliced off. 2963 * @param beginning Whether to splice off the beginning or the end. 2964 * 2965 * @return The spliced off part. 2966 * 2967 * @hide 2968 */ splice(double fractionToRemove, boolean beginning)2969 private @Nullable HistoricalOps splice(double fractionToRemove, boolean beginning) { 2970 final long spliceBeginTimeMills; 2971 final long spliceEndTimeMills; 2972 if (beginning) { 2973 spliceBeginTimeMills = mBeginTimeMillis; 2974 spliceEndTimeMills = (long) (mBeginTimeMillis 2975 + getDurationMillis() * fractionToRemove); 2976 mBeginTimeMillis = spliceEndTimeMills; 2977 } else { 2978 spliceBeginTimeMills = (long) (mEndTimeMillis 2979 - getDurationMillis() * fractionToRemove); 2980 spliceEndTimeMills = mEndTimeMillis; 2981 mEndTimeMillis = spliceBeginTimeMills; 2982 } 2983 2984 HistoricalOps splice = null; 2985 final int uidCount = getUidCount(); 2986 for (int i = 0; i < uidCount; i++) { 2987 final HistoricalUidOps origOps = getUidOpsAt(i); 2988 final HistoricalUidOps spliceOps = origOps.splice(fractionToRemove); 2989 if (spliceOps != null) { 2990 if (splice == null) { 2991 splice = new HistoricalOps(spliceBeginTimeMills, spliceEndTimeMills); 2992 } 2993 if (splice.mHistoricalUidOps == null) { 2994 splice.mHistoricalUidOps = new SparseArray<>(); 2995 } 2996 splice.mHistoricalUidOps.put(spliceOps.getUid(), spliceOps); 2997 } 2998 } 2999 return splice; 3000 } 3001 3002 /** 3003 * Merge the passed ops into the current ones. The time interval is a 3004 * union of the current and passed in one and the passed in data is 3005 * folded into the data of this instance. 3006 * 3007 * @hide 3008 */ merge(@onNull HistoricalOps other)3009 public void merge(@NonNull HistoricalOps other) { 3010 mBeginTimeMillis = Math.min(mBeginTimeMillis, other.mBeginTimeMillis); 3011 mEndTimeMillis = Math.max(mEndTimeMillis, other.mEndTimeMillis); 3012 final int uidCount = other.getUidCount(); 3013 for (int i = 0; i < uidCount; i++) { 3014 final HistoricalUidOps otherUidOps = other.getUidOpsAt(i); 3015 final HistoricalUidOps thisUidOps = getUidOps(otherUidOps.getUid()); 3016 if (thisUidOps != null) { 3017 thisUidOps.merge(otherUidOps); 3018 } else { 3019 if (mHistoricalUidOps == null) { 3020 mHistoricalUidOps = new SparseArray<>(); 3021 } 3022 mHistoricalUidOps.put(otherUidOps.getUid(), otherUidOps); 3023 } 3024 } 3025 } 3026 3027 /** 3028 * AppPermissionUsage the ops to leave only the data we filter for. 3029 * 3030 * @param uid Uid to filter for or {@link android.os.Process#INCIDENTD_UID} for all. 3031 * @param packageName Package to filter for or null for all. 3032 * @param opNames Ops to filter for or null for all. 3033 * @param beginTimeMillis The begin time to filter for or {@link Long#MIN_VALUE} for all. 3034 * @param endTimeMillis The end time to filter for or {@link Long#MAX_VALUE} for all. 3035 * 3036 * @hide 3037 */ filter(int uid, @Nullable String packageName, @Nullable String[] opNames, long beginTimeMillis, long endTimeMillis)3038 public void filter(int uid, @Nullable String packageName, @Nullable String[] opNames, 3039 long beginTimeMillis, long endTimeMillis) { 3040 final long durationMillis = getDurationMillis(); 3041 mBeginTimeMillis = Math.max(mBeginTimeMillis, beginTimeMillis); 3042 mEndTimeMillis = Math.min(mEndTimeMillis, endTimeMillis); 3043 final double scaleFactor = Math.min((double) (endTimeMillis - beginTimeMillis) 3044 / (double) durationMillis, 1); 3045 final int uidCount = getUidCount(); 3046 for (int i = uidCount - 1; i >= 0; i--) { 3047 final HistoricalUidOps uidOp = mHistoricalUidOps.valueAt(i); 3048 if (uid != Process.INVALID_UID && uid != uidOp.getUid()) { 3049 mHistoricalUidOps.removeAt(i); 3050 } else { 3051 uidOp.filter(packageName, opNames, scaleFactor); 3052 } 3053 } 3054 } 3055 3056 /** @hide */ isEmpty()3057 public boolean isEmpty() { 3058 if (getBeginTimeMillis() >= getEndTimeMillis()) { 3059 return true; 3060 } 3061 final int uidCount = getUidCount(); 3062 for (int i = uidCount - 1; i >= 0; i--) { 3063 final HistoricalUidOps uidOp = mHistoricalUidOps.valueAt(i); 3064 if (!uidOp.isEmpty()) { 3065 return false; 3066 } 3067 } 3068 return true; 3069 } 3070 3071 /** @hide */ getDurationMillis()3072 public long getDurationMillis() { 3073 return mEndTimeMillis - mBeginTimeMillis; 3074 } 3075 3076 /** @hide */ 3077 @TestApi increaseAccessCount(int opCode, int uid, @NonNull String packageName, @UidState int uidState, @OpFlags int flags, long increment)3078 public void increaseAccessCount(int opCode, int uid, @NonNull String packageName, 3079 @UidState int uidState, @OpFlags int flags, long increment) { 3080 getOrCreateHistoricalUidOps(uid).increaseAccessCount(opCode, 3081 packageName, uidState, flags, increment); 3082 } 3083 3084 /** @hide */ 3085 @TestApi increaseRejectCount(int opCode, int uid, @NonNull String packageName, @UidState int uidState, @OpFlags int flags, long increment)3086 public void increaseRejectCount(int opCode, int uid, @NonNull String packageName, 3087 @UidState int uidState, @OpFlags int flags, long increment) { 3088 getOrCreateHistoricalUidOps(uid).increaseRejectCount(opCode, 3089 packageName, uidState, flags, increment); 3090 } 3091 3092 /** @hide */ 3093 @TestApi increaseAccessDuration(int opCode, int uid, @NonNull String packageName, @UidState int uidState, @OpFlags int flags, long increment)3094 public void increaseAccessDuration(int opCode, int uid, @NonNull String packageName, 3095 @UidState int uidState, @OpFlags int flags, long increment) { 3096 getOrCreateHistoricalUidOps(uid).increaseAccessDuration(opCode, 3097 packageName, uidState, flags, increment); 3098 } 3099 3100 /** @hide */ 3101 @TestApi offsetBeginAndEndTime(long offsetMillis)3102 public void offsetBeginAndEndTime(long offsetMillis) { 3103 mBeginTimeMillis += offsetMillis; 3104 mEndTimeMillis += offsetMillis; 3105 } 3106 3107 /** @hide */ setBeginAndEndTime(long beginTimeMillis, long endTimeMillis)3108 public void setBeginAndEndTime(long beginTimeMillis, long endTimeMillis) { 3109 mBeginTimeMillis = beginTimeMillis; 3110 mEndTimeMillis = endTimeMillis; 3111 } 3112 3113 /** @hide */ setBeginTime(long beginTimeMillis)3114 public void setBeginTime(long beginTimeMillis) { 3115 mBeginTimeMillis = beginTimeMillis; 3116 } 3117 3118 /** @hide */ setEndTime(long endTimeMillis)3119 public void setEndTime(long endTimeMillis) { 3120 mEndTimeMillis = endTimeMillis; 3121 } 3122 3123 /** 3124 * @return The beginning of the interval in milliseconds since 3125 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). 3126 */ getBeginTimeMillis()3127 public long getBeginTimeMillis() { 3128 return mBeginTimeMillis; 3129 } 3130 3131 /** 3132 * @return The end of the interval in milliseconds since 3133 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). 3134 */ getEndTimeMillis()3135 public long getEndTimeMillis() { 3136 return mEndTimeMillis; 3137 } 3138 3139 /** 3140 * Gets number of UIDs with historical ops. 3141 * 3142 * @return The number of UIDs with historical ops. 3143 * 3144 * @see #getUidOpsAt(int) 3145 */ getUidCount()3146 public @IntRange(from = 0) int getUidCount() { 3147 if (mHistoricalUidOps == null) { 3148 return 0; 3149 } 3150 return mHistoricalUidOps.size(); 3151 } 3152 3153 /** 3154 * Gets the historical UID ops at a given index. 3155 * 3156 * @param index The index. 3157 * 3158 * @return The historical UID ops at the given index. 3159 * 3160 * @see #getUidCount() 3161 */ getUidOpsAt(@ntRangefrom = 0) int index)3162 public @NonNull HistoricalUidOps getUidOpsAt(@IntRange(from = 0) int index) { 3163 if (mHistoricalUidOps == null) { 3164 throw new IndexOutOfBoundsException(); 3165 } 3166 return mHistoricalUidOps.valueAt(index); 3167 } 3168 3169 /** 3170 * Gets the historical UID ops for a given UID. 3171 * 3172 * @param uid The UID. 3173 * 3174 * @return The historical ops for the UID. 3175 */ getUidOps(int uid)3176 public @Nullable HistoricalUidOps getUidOps(int uid) { 3177 if (mHistoricalUidOps == null) { 3178 return null; 3179 } 3180 return mHistoricalUidOps.get(uid); 3181 } 3182 3183 /** @hide */ clearHistory(int uid, @NonNull String packageName)3184 public void clearHistory(int uid, @NonNull String packageName) { 3185 HistoricalUidOps historicalUidOps = getOrCreateHistoricalUidOps(uid); 3186 historicalUidOps.clearHistory(packageName); 3187 if (historicalUidOps.isEmpty()) { 3188 mHistoricalUidOps.remove(uid); 3189 } 3190 } 3191 3192 @Override describeContents()3193 public int describeContents() { 3194 return 0; 3195 } 3196 3197 @Override writeToParcel(Parcel parcel, int flags)3198 public void writeToParcel(Parcel parcel, int flags) { 3199 parcel.writeLong(mBeginTimeMillis); 3200 parcel.writeLong(mEndTimeMillis); 3201 if (mHistoricalUidOps != null) { 3202 final int uidCount = mHistoricalUidOps.size(); 3203 parcel.writeInt(uidCount); 3204 for (int i = 0; i < uidCount; i++) { 3205 parcel.writeInt(mHistoricalUidOps.keyAt(i)); 3206 } 3207 final List<HistoricalUidOps> opsList = new ArrayList<>(uidCount); 3208 for (int i = 0; i < uidCount; i++) { 3209 opsList.add(mHistoricalUidOps.valueAt(i)); 3210 } 3211 parcel.writeParcelable(new ParceledListSlice<>(opsList), flags); 3212 } else { 3213 parcel.writeInt(-1); 3214 } 3215 } 3216 3217 /** 3218 * Accepts a visitor to traverse the ops tree. 3219 * 3220 * @param visitor The visitor. 3221 * 3222 * @hide 3223 */ accept(@onNull HistoricalOpsVisitor visitor)3224 public void accept(@NonNull HistoricalOpsVisitor visitor) { 3225 visitor.visitHistoricalOps(this); 3226 final int uidCount = getUidCount(); 3227 for (int i = 0; i < uidCount; i++) { 3228 getUidOpsAt(i).accept(visitor); 3229 } 3230 } 3231 getOrCreateHistoricalUidOps(int uid)3232 private @NonNull HistoricalUidOps getOrCreateHistoricalUidOps(int uid) { 3233 if (mHistoricalUidOps == null) { 3234 mHistoricalUidOps = new SparseArray<>(); 3235 } 3236 HistoricalUidOps historicalUidOp = mHistoricalUidOps.get(uid); 3237 if (historicalUidOp == null) { 3238 historicalUidOp = new HistoricalUidOps(uid); 3239 mHistoricalUidOps.put(uid, historicalUidOp); 3240 } 3241 return historicalUidOp; 3242 } 3243 3244 /** 3245 * @return Rounded value up at the 0.5 boundary. 3246 * 3247 * @hide 3248 */ round(double value)3249 public static double round(double value) { 3250 final BigDecimal decimalScale = new BigDecimal(value); 3251 return decimalScale.setScale(0, RoundingMode.HALF_UP).doubleValue(); 3252 } 3253 3254 @Override equals(@ullable Object obj)3255 public boolean equals(@Nullable Object obj) { 3256 if (this == obj) { 3257 return true; 3258 } 3259 if (obj == null || getClass() != obj.getClass()) { 3260 return false; 3261 } 3262 final HistoricalOps other = (HistoricalOps) obj; 3263 if (mBeginTimeMillis != other.mBeginTimeMillis) { 3264 return false; 3265 } 3266 if (mEndTimeMillis != other.mEndTimeMillis) { 3267 return false; 3268 } 3269 if (mHistoricalUidOps == null) { 3270 if (other.mHistoricalUidOps != null) { 3271 return false; 3272 } 3273 } else if (!mHistoricalUidOps.equals(other.mHistoricalUidOps)) { 3274 return false; 3275 } 3276 return true; 3277 } 3278 3279 @Override hashCode()3280 public int hashCode() { 3281 int result = (int) (mBeginTimeMillis ^ (mBeginTimeMillis >>> 32)); 3282 result = 31 * result + mHistoricalUidOps.hashCode(); 3283 return result; 3284 } 3285 3286 @NonNull 3287 @Override toString()3288 public String toString() { 3289 return getClass().getSimpleName() + "[from:" 3290 + mBeginTimeMillis + " to:" + mEndTimeMillis + "]"; 3291 } 3292 3293 public static final @android.annotation.NonNull Creator<HistoricalOps> CREATOR = new Creator<HistoricalOps>() { 3294 @Override 3295 public @NonNull HistoricalOps createFromParcel(@NonNull Parcel parcel) { 3296 return new HistoricalOps(parcel); 3297 } 3298 3299 @Override 3300 public @NonNull HistoricalOps[] newArray(int size) { 3301 return new HistoricalOps[size]; 3302 } 3303 }; 3304 } 3305 3306 /** 3307 * This class represents historical app op state for a UID. 3308 * 3309 * @hide 3310 */ 3311 @TestApi 3312 @SystemApi 3313 public static final class HistoricalUidOps implements Parcelable { 3314 private final int mUid; 3315 private @Nullable ArrayMap<String, HistoricalPackageOps> mHistoricalPackageOps; 3316 3317 /** @hide */ HistoricalUidOps(int uid)3318 public HistoricalUidOps(int uid) { 3319 mUid = uid; 3320 } 3321 HistoricalUidOps(@onNull HistoricalUidOps other)3322 private HistoricalUidOps(@NonNull HistoricalUidOps other) { 3323 mUid = other.mUid; 3324 final int opCount = other.getPackageCount(); 3325 for (int i = 0; i < opCount; i++) { 3326 final HistoricalPackageOps origOps = other.getPackageOpsAt(i); 3327 final HistoricalPackageOps cloneOps = new HistoricalPackageOps(origOps); 3328 if (mHistoricalPackageOps == null) { 3329 mHistoricalPackageOps = new ArrayMap<>(opCount); 3330 } 3331 mHistoricalPackageOps.put(cloneOps.getPackageName(), cloneOps); 3332 } 3333 } 3334 HistoricalUidOps(@onNull Parcel parcel)3335 private HistoricalUidOps(@NonNull Parcel parcel) { 3336 // No arg check since we always read from a trusted source. 3337 mUid = parcel.readInt(); 3338 mHistoricalPackageOps = parcel.createTypedArrayMap(HistoricalPackageOps.CREATOR); 3339 } 3340 splice(double fractionToRemove)3341 private @Nullable HistoricalUidOps splice(double fractionToRemove) { 3342 HistoricalUidOps splice = null; 3343 final int packageCount = getPackageCount(); 3344 for (int i = 0; i < packageCount; i++) { 3345 final HistoricalPackageOps origOps = getPackageOpsAt(i); 3346 final HistoricalPackageOps spliceOps = origOps.splice(fractionToRemove); 3347 if (spliceOps != null) { 3348 if (splice == null) { 3349 splice = new HistoricalUidOps(mUid); 3350 } 3351 if (splice.mHistoricalPackageOps == null) { 3352 splice.mHistoricalPackageOps = new ArrayMap<>(); 3353 } 3354 splice.mHistoricalPackageOps.put(spliceOps.getPackageName(), spliceOps); 3355 } 3356 } 3357 return splice; 3358 } 3359 merge(@onNull HistoricalUidOps other)3360 private void merge(@NonNull HistoricalUidOps other) { 3361 final int packageCount = other.getPackageCount(); 3362 for (int i = 0; i < packageCount; i++) { 3363 final HistoricalPackageOps otherPackageOps = other.getPackageOpsAt(i); 3364 final HistoricalPackageOps thisPackageOps = getPackageOps( 3365 otherPackageOps.getPackageName()); 3366 if (thisPackageOps != null) { 3367 thisPackageOps.merge(otherPackageOps); 3368 } else { 3369 if (mHistoricalPackageOps == null) { 3370 mHistoricalPackageOps = new ArrayMap<>(); 3371 } 3372 mHistoricalPackageOps.put(otherPackageOps.getPackageName(), otherPackageOps); 3373 } 3374 } 3375 } 3376 filter(@ullable String packageName, @Nullable String[] opNames, double fractionToRemove)3377 private void filter(@Nullable String packageName, @Nullable String[] opNames, 3378 double fractionToRemove) { 3379 final int packageCount = getPackageCount(); 3380 for (int i = packageCount - 1; i >= 0; i--) { 3381 final HistoricalPackageOps packageOps = getPackageOpsAt(i); 3382 if (packageName != null && !packageName.equals(packageOps.getPackageName())) { 3383 mHistoricalPackageOps.removeAt(i); 3384 } else { 3385 packageOps.filter(opNames, fractionToRemove); 3386 } 3387 } 3388 } 3389 isEmpty()3390 private boolean isEmpty() { 3391 final int packageCount = getPackageCount(); 3392 for (int i = packageCount - 1; i >= 0; i--) { 3393 final HistoricalPackageOps packageOps = mHistoricalPackageOps.valueAt(i); 3394 if (!packageOps.isEmpty()) { 3395 return false; 3396 } 3397 } 3398 return true; 3399 } 3400 increaseAccessCount(int opCode, @NonNull String packageName, @UidState int uidState, @OpFlags int flags, long increment)3401 private void increaseAccessCount(int opCode, @NonNull String packageName, 3402 @UidState int uidState, @OpFlags int flags, long increment) { 3403 getOrCreateHistoricalPackageOps(packageName).increaseAccessCount( 3404 opCode, uidState, flags, increment); 3405 } 3406 increaseRejectCount(int opCode, @NonNull String packageName, @UidState int uidState, @OpFlags int flags, long increment)3407 private void increaseRejectCount(int opCode, @NonNull String packageName, 3408 @UidState int uidState, @OpFlags int flags, long increment) { 3409 getOrCreateHistoricalPackageOps(packageName).increaseRejectCount( 3410 opCode, uidState, flags, increment); 3411 } 3412 increaseAccessDuration(int opCode, @NonNull String packageName, @UidState int uidState, @OpFlags int flags, long increment)3413 private void increaseAccessDuration(int opCode, @NonNull String packageName, 3414 @UidState int uidState, @OpFlags int flags, long increment) { 3415 getOrCreateHistoricalPackageOps(packageName).increaseAccessDuration( 3416 opCode, uidState, flags, increment); 3417 } 3418 3419 /** 3420 * @return The UID for which the data is related. 3421 */ getUid()3422 public int getUid() { 3423 return mUid; 3424 } 3425 3426 /** 3427 * Gets number of packages with historical ops. 3428 * 3429 * @return The number of packages with historical ops. 3430 * 3431 * @see #getPackageOpsAt(int) 3432 */ getPackageCount()3433 public @IntRange(from = 0) int getPackageCount() { 3434 if (mHistoricalPackageOps == null) { 3435 return 0; 3436 } 3437 return mHistoricalPackageOps.size(); 3438 } 3439 3440 /** 3441 * Gets the historical package ops at a given index. 3442 * 3443 * @param index The index. 3444 * 3445 * @return The historical package ops at the given index. 3446 * 3447 * @see #getPackageCount() 3448 */ getPackageOpsAt(@ntRangefrom = 0) int index)3449 public @NonNull HistoricalPackageOps getPackageOpsAt(@IntRange(from = 0) int index) { 3450 if (mHistoricalPackageOps == null) { 3451 throw new IndexOutOfBoundsException(); 3452 } 3453 return mHistoricalPackageOps.valueAt(index); 3454 } 3455 3456 /** 3457 * Gets the historical package ops for a given package. 3458 * 3459 * @param packageName The package. 3460 * 3461 * @return The historical ops for the package. 3462 */ getPackageOps(@onNull String packageName)3463 public @Nullable HistoricalPackageOps getPackageOps(@NonNull String packageName) { 3464 if (mHistoricalPackageOps == null) { 3465 return null; 3466 } 3467 return mHistoricalPackageOps.get(packageName); 3468 } 3469 clearHistory(@onNull String packageName)3470 private void clearHistory(@NonNull String packageName) { 3471 if (mHistoricalPackageOps != null) { 3472 mHistoricalPackageOps.remove(packageName); 3473 } 3474 } 3475 3476 @Override describeContents()3477 public int describeContents() { 3478 return 0; 3479 } 3480 3481 @Override writeToParcel(Parcel parcel, int flags)3482 public void writeToParcel(Parcel parcel, int flags) { 3483 parcel.writeInt(mUid); 3484 parcel.writeTypedArrayMap(mHistoricalPackageOps, flags); 3485 } 3486 accept(@onNull HistoricalOpsVisitor visitor)3487 private void accept(@NonNull HistoricalOpsVisitor visitor) { 3488 visitor.visitHistoricalUidOps(this); 3489 final int packageCount = getPackageCount(); 3490 for (int i = 0; i < packageCount; i++) { 3491 getPackageOpsAt(i).accept(visitor); 3492 } 3493 } 3494 getOrCreateHistoricalPackageOps( @onNull String packageName)3495 private @NonNull HistoricalPackageOps getOrCreateHistoricalPackageOps( 3496 @NonNull String packageName) { 3497 if (mHistoricalPackageOps == null) { 3498 mHistoricalPackageOps = new ArrayMap<>(); 3499 } 3500 HistoricalPackageOps historicalPackageOp = mHistoricalPackageOps.get(packageName); 3501 if (historicalPackageOp == null) { 3502 historicalPackageOp = new HistoricalPackageOps(packageName); 3503 mHistoricalPackageOps.put(packageName, historicalPackageOp); 3504 } 3505 return historicalPackageOp; 3506 } 3507 3508 3509 public static final @android.annotation.NonNull Creator<HistoricalUidOps> CREATOR = new Creator<HistoricalUidOps>() { 3510 @Override 3511 public @NonNull HistoricalUidOps createFromParcel(@NonNull Parcel parcel) { 3512 return new HistoricalUidOps(parcel); 3513 } 3514 3515 @Override 3516 public @NonNull HistoricalUidOps[] newArray(int size) { 3517 return new HistoricalUidOps[size]; 3518 } 3519 }; 3520 3521 @Override equals(@ullable Object obj)3522 public boolean equals(@Nullable Object obj) { 3523 if (this == obj) { 3524 return true; 3525 } 3526 if (obj == null || getClass() != obj.getClass()) { 3527 return false; 3528 } 3529 final HistoricalUidOps other = (HistoricalUidOps) obj; 3530 if (mUid != other.mUid) { 3531 return false; 3532 } 3533 if (mHistoricalPackageOps == null) { 3534 if (other.mHistoricalPackageOps != null) { 3535 return false; 3536 } 3537 } else if (!mHistoricalPackageOps.equals(other.mHistoricalPackageOps)) { 3538 return false; 3539 } 3540 return true; 3541 } 3542 3543 @Override hashCode()3544 public int hashCode() { 3545 int result = mUid; 3546 result = 31 * result + (mHistoricalPackageOps != null 3547 ? mHistoricalPackageOps.hashCode() : 0); 3548 return result; 3549 } 3550 } 3551 3552 /** 3553 * This class represents historical app op information about a package. 3554 * 3555 * @hide 3556 */ 3557 @TestApi 3558 @SystemApi 3559 public static final class HistoricalPackageOps implements Parcelable { 3560 private final @NonNull String mPackageName; 3561 private @Nullable ArrayMap<String, HistoricalOp> mHistoricalOps; 3562 3563 /** @hide */ HistoricalPackageOps(@onNull String packageName)3564 public HistoricalPackageOps(@NonNull String packageName) { 3565 mPackageName = packageName; 3566 } 3567 HistoricalPackageOps(@onNull HistoricalPackageOps other)3568 private HistoricalPackageOps(@NonNull HistoricalPackageOps other) { 3569 mPackageName = other.mPackageName; 3570 final int opCount = other.getOpCount(); 3571 for (int i = 0; i < opCount; i++) { 3572 final HistoricalOp origOp = other.getOpAt(i); 3573 final HistoricalOp cloneOp = new HistoricalOp(origOp); 3574 if (mHistoricalOps == null) { 3575 mHistoricalOps = new ArrayMap<>(opCount); 3576 } 3577 mHistoricalOps.put(cloneOp.getOpName(), cloneOp); 3578 } 3579 } 3580 HistoricalPackageOps(@onNull Parcel parcel)3581 private HistoricalPackageOps(@NonNull Parcel parcel) { 3582 mPackageName = parcel.readString(); 3583 mHistoricalOps = parcel.createTypedArrayMap(HistoricalOp.CREATOR); 3584 } 3585 splice(double fractionToRemove)3586 private @Nullable HistoricalPackageOps splice(double fractionToRemove) { 3587 HistoricalPackageOps splice = null; 3588 final int opCount = getOpCount(); 3589 for (int i = 0; i < opCount; i++) { 3590 final HistoricalOp origOps = getOpAt(i); 3591 final HistoricalOp spliceOps = origOps.splice(fractionToRemove); 3592 if (spliceOps != null) { 3593 if (splice == null) { 3594 splice = new HistoricalPackageOps(mPackageName); 3595 } 3596 if (splice.mHistoricalOps == null) { 3597 splice.mHistoricalOps = new ArrayMap<>(); 3598 } 3599 splice.mHistoricalOps.put(spliceOps.getOpName(), spliceOps); 3600 } 3601 } 3602 return splice; 3603 } 3604 merge(@onNull HistoricalPackageOps other)3605 private void merge(@NonNull HistoricalPackageOps other) { 3606 final int opCount = other.getOpCount(); 3607 for (int i = 0; i < opCount; i++) { 3608 final HistoricalOp otherOp = other.getOpAt(i); 3609 final HistoricalOp thisOp = getOp(otherOp.getOpName()); 3610 if (thisOp != null) { 3611 thisOp.merge(otherOp); 3612 } else { 3613 if (mHistoricalOps == null) { 3614 mHistoricalOps = new ArrayMap<>(); 3615 } 3616 mHistoricalOps.put(otherOp.getOpName(), otherOp); 3617 } 3618 } 3619 } 3620 filter(@ullable String[] opNames, double scaleFactor)3621 private void filter(@Nullable String[] opNames, double scaleFactor) { 3622 final int opCount = getOpCount(); 3623 for (int i = opCount - 1; i >= 0; i--) { 3624 final HistoricalOp op = mHistoricalOps.valueAt(i); 3625 if (opNames != null && !ArrayUtils.contains(opNames, op.getOpName())) { 3626 mHistoricalOps.removeAt(i); 3627 } else { 3628 op.filter(scaleFactor); 3629 } 3630 } 3631 } 3632 isEmpty()3633 private boolean isEmpty() { 3634 final int opCount = getOpCount(); 3635 for (int i = opCount - 1; i >= 0; i--) { 3636 final HistoricalOp op = mHistoricalOps.valueAt(i); 3637 if (!op.isEmpty()) { 3638 return false; 3639 } 3640 } 3641 return true; 3642 } 3643 increaseAccessCount(int opCode, @UidState int uidState, @OpFlags int flags, long increment)3644 private void increaseAccessCount(int opCode, @UidState int uidState, 3645 @OpFlags int flags, long increment) { 3646 getOrCreateHistoricalOp(opCode).increaseAccessCount(uidState, flags, increment); 3647 } 3648 increaseRejectCount(int opCode, @UidState int uidState, @OpFlags int flags, long increment)3649 private void increaseRejectCount(int opCode, @UidState int uidState, 3650 @OpFlags int flags, long increment) { 3651 getOrCreateHistoricalOp(opCode).increaseRejectCount(uidState, flags, increment); 3652 } 3653 increaseAccessDuration(int opCode, @UidState int uidState, @OpFlags int flags, long increment)3654 private void increaseAccessDuration(int opCode, @UidState int uidState, 3655 @OpFlags int flags, long increment) { 3656 getOrCreateHistoricalOp(opCode).increaseAccessDuration(uidState, flags, increment); 3657 } 3658 3659 /** 3660 * Gets the package name which the data represents. 3661 * 3662 * @return The package name which the data represents. 3663 */ getPackageName()3664 public @NonNull String getPackageName() { 3665 return mPackageName; 3666 } 3667 3668 /** 3669 * Gets number historical app ops. 3670 * 3671 * @return The number historical app ops. 3672 * @see #getOpAt(int) 3673 */ getOpCount()3674 public @IntRange(from = 0) int getOpCount() { 3675 if (mHistoricalOps == null) { 3676 return 0; 3677 } 3678 return mHistoricalOps.size(); 3679 } 3680 3681 /** 3682 * Gets the historical op at a given index. 3683 * 3684 * @param index The index to lookup. 3685 * @return The op at the given index. 3686 * @see #getOpCount() 3687 */ getOpAt(@ntRangefrom = 0) int index)3688 public @NonNull HistoricalOp getOpAt(@IntRange(from = 0) int index) { 3689 if (mHistoricalOps == null) { 3690 throw new IndexOutOfBoundsException(); 3691 } 3692 return mHistoricalOps.valueAt(index); 3693 } 3694 3695 /** 3696 * Gets the historical entry for a given op name. 3697 * 3698 * @param opName The op name. 3699 * @return The historical entry for that op name. 3700 */ getOp(@onNull String opName)3701 public @Nullable HistoricalOp getOp(@NonNull String opName) { 3702 if (mHistoricalOps == null) { 3703 return null; 3704 } 3705 return mHistoricalOps.get(opName); 3706 } 3707 3708 @Override describeContents()3709 public int describeContents() { 3710 return 0; 3711 } 3712 3713 @Override writeToParcel(@onNull Parcel parcel, int flags)3714 public void writeToParcel(@NonNull Parcel parcel, int flags) { 3715 parcel.writeString(mPackageName); 3716 parcel.writeTypedArrayMap(mHistoricalOps, flags); 3717 } 3718 accept(@onNull HistoricalOpsVisitor visitor)3719 private void accept(@NonNull HistoricalOpsVisitor visitor) { 3720 visitor.visitHistoricalPackageOps(this); 3721 final int opCount = getOpCount(); 3722 for (int i = 0; i < opCount; i++) { 3723 getOpAt(i).accept(visitor); 3724 } 3725 } 3726 getOrCreateHistoricalOp(int opCode)3727 private @NonNull HistoricalOp getOrCreateHistoricalOp(int opCode) { 3728 if (mHistoricalOps == null) { 3729 mHistoricalOps = new ArrayMap<>(); 3730 } 3731 final String opStr = sOpToString[opCode]; 3732 HistoricalOp op = mHistoricalOps.get(opStr); 3733 if (op == null) { 3734 op = new HistoricalOp(opCode); 3735 mHistoricalOps.put(opStr, op); 3736 } 3737 return op; 3738 } 3739 3740 public static final @android.annotation.NonNull Creator<HistoricalPackageOps> CREATOR = 3741 new Creator<HistoricalPackageOps>() { 3742 @Override 3743 public @NonNull HistoricalPackageOps createFromParcel(@NonNull Parcel parcel) { 3744 return new HistoricalPackageOps(parcel); 3745 } 3746 3747 @Override 3748 public @NonNull HistoricalPackageOps[] newArray(int size) { 3749 return new HistoricalPackageOps[size]; 3750 } 3751 }; 3752 3753 @Override equals(@ullable Object obj)3754 public boolean equals(@Nullable Object obj) { 3755 if (this == obj) { 3756 return true; 3757 } 3758 if (obj == null || getClass() != obj.getClass()) { 3759 return false; 3760 } 3761 final HistoricalPackageOps other = (HistoricalPackageOps) obj; 3762 if (!mPackageName.equals(other.mPackageName)) { 3763 return false; 3764 } 3765 if (mHistoricalOps == null) { 3766 if (other.mHistoricalOps != null) { 3767 return false; 3768 } 3769 } else if (!mHistoricalOps.equals(other.mHistoricalOps)) { 3770 return false; 3771 } 3772 return true; 3773 } 3774 3775 @Override hashCode()3776 public int hashCode() { 3777 int result = mPackageName != null ? mPackageName.hashCode() : 0; 3778 result = 31 * result + (mHistoricalOps != null ? mHistoricalOps.hashCode() : 0); 3779 return result; 3780 } 3781 } 3782 3783 /** 3784 * This class represents historical information about an app op. 3785 * 3786 * @hide 3787 */ 3788 @TestApi 3789 @SystemApi 3790 public static final class HistoricalOp implements Parcelable { 3791 private final int mOp; 3792 private @Nullable LongSparseLongArray mAccessCount; 3793 private @Nullable LongSparseLongArray mRejectCount; 3794 private @Nullable LongSparseLongArray mAccessDuration; 3795 3796 /** @hide */ HistoricalOp(int op)3797 public HistoricalOp(int op) { 3798 mOp = op; 3799 } 3800 HistoricalOp(@onNull HistoricalOp other)3801 private HistoricalOp(@NonNull HistoricalOp other) { 3802 mOp = other.mOp; 3803 if (other.mAccessCount != null) { 3804 mAccessCount = other.mAccessCount.clone(); 3805 } 3806 if (other.mRejectCount != null) { 3807 mRejectCount = other.mRejectCount.clone(); 3808 } 3809 if (other.mAccessDuration != null) { 3810 mAccessDuration = other.mAccessDuration.clone(); 3811 } 3812 } 3813 HistoricalOp(@onNull Parcel parcel)3814 private HistoricalOp(@NonNull Parcel parcel) { 3815 mOp = parcel.readInt(); 3816 mAccessCount = readLongSparseLongArrayFromParcel(parcel); 3817 mRejectCount = readLongSparseLongArrayFromParcel(parcel); 3818 mAccessDuration = readLongSparseLongArrayFromParcel(parcel); 3819 } 3820 filter(double scaleFactor)3821 private void filter(double scaleFactor) { 3822 scale(mAccessCount, scaleFactor); 3823 scale(mRejectCount, scaleFactor); 3824 scale(mAccessDuration, scaleFactor); 3825 } 3826 isEmpty()3827 private boolean isEmpty() { 3828 return !hasData(mAccessCount) 3829 && !hasData(mRejectCount) 3830 && !hasData(mAccessDuration); 3831 } 3832 hasData(@onNull LongSparseLongArray array)3833 private boolean hasData(@NonNull LongSparseLongArray array) { 3834 return (array != null && array.size() > 0); 3835 } 3836 splice(double fractionToRemove)3837 private @Nullable HistoricalOp splice(double fractionToRemove) { 3838 final HistoricalOp splice = new HistoricalOp(mOp); 3839 splice(mAccessCount, splice::getOrCreateAccessCount, fractionToRemove); 3840 splice(mRejectCount, splice::getOrCreateRejectCount, fractionToRemove); 3841 splice(mAccessDuration, splice::getOrCreateAccessDuration, fractionToRemove); 3842 return splice; 3843 } 3844 splice(@ullable LongSparseLongArray sourceContainer, @NonNull Supplier<LongSparseLongArray> destContainerProvider, double fractionToRemove)3845 private static void splice(@Nullable LongSparseLongArray sourceContainer, 3846 @NonNull Supplier<LongSparseLongArray> destContainerProvider, 3847 double fractionToRemove) { 3848 if (sourceContainer != null) { 3849 final int size = sourceContainer.size(); 3850 for (int i = 0; i < size; i++) { 3851 final long key = sourceContainer.keyAt(i); 3852 final long value = sourceContainer.valueAt(i); 3853 final long removedFraction = Math.round(value * fractionToRemove); 3854 if (removedFraction > 0) { 3855 destContainerProvider.get().put(key, removedFraction); 3856 sourceContainer.put(key, value - removedFraction); 3857 } 3858 } 3859 } 3860 } 3861 merge(@onNull HistoricalOp other)3862 private void merge(@NonNull HistoricalOp other) { 3863 merge(this::getOrCreateAccessCount, other.mAccessCount); 3864 merge(this::getOrCreateRejectCount, other.mRejectCount); 3865 merge(this::getOrCreateAccessDuration, other.mAccessDuration); 3866 } 3867 increaseAccessCount(@idState int uidState, @OpFlags int flags, long increment)3868 private void increaseAccessCount(@UidState int uidState, @OpFlags int flags, 3869 long increment) { 3870 increaseCount(getOrCreateAccessCount(), uidState, flags, increment); 3871 } 3872 increaseRejectCount(@idState int uidState, @OpFlags int flags, long increment)3873 private void increaseRejectCount(@UidState int uidState, @OpFlags int flags, 3874 long increment) { 3875 increaseCount(getOrCreateRejectCount(), uidState, flags, increment); 3876 } 3877 increaseAccessDuration(@idState int uidState, @OpFlags int flags, long increment)3878 private void increaseAccessDuration(@UidState int uidState, @OpFlags int flags, 3879 long increment) { 3880 increaseCount(getOrCreateAccessDuration(), uidState, flags, increment); 3881 } 3882 increaseCount(@onNull LongSparseLongArray counts, @UidState int uidState, @OpFlags int flags, long increment)3883 private void increaseCount(@NonNull LongSparseLongArray counts, 3884 @UidState int uidState, @OpFlags int flags, long increment) { 3885 while (flags != 0) { 3886 final int flag = 1 << Integer.numberOfTrailingZeros(flags); 3887 flags &= ~flag; 3888 final long key = makeKey(uidState, flag); 3889 counts.put(key, counts.get(key) + increment); 3890 } 3891 } 3892 3893 /** 3894 * Gets the op name. 3895 * 3896 * @return The op name. 3897 */ getOpName()3898 public @NonNull String getOpName() { 3899 return sOpToString[mOp]; 3900 } 3901 3902 /** @hide */ getOpCode()3903 public int getOpCode() { 3904 return mOp; 3905 } 3906 3907 /** 3908 * Gets the number times the op was accessed (performed) in the foreground. 3909 * 3910 * @param flags The flags which are any combination of 3911 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 3912 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 3913 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 3914 * for any flag. 3915 * @return The times the op was accessed in the foreground. 3916 * 3917 * @see #getBackgroundAccessCount(int) 3918 * @see #getAccessCount(int, int, int) 3919 */ getForegroundAccessCount(@pFlags int flags)3920 public long getForegroundAccessCount(@OpFlags int flags) { 3921 return sumForFlagsInStates(mAccessCount, MAX_PRIORITY_UID_STATE, 3922 resolveFirstUnrestrictedUidState(mOp), flags); 3923 } 3924 3925 /** 3926 * Gets the number times the op was accessed (performed) in the background. 3927 * 3928 * @param flags The flags which are any combination of 3929 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 3930 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 3931 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 3932 * for any flag. 3933 * @return The times the op was accessed in the background. 3934 * 3935 * @see #getForegroundAccessCount(int) 3936 * @see #getAccessCount(int, int, int) 3937 */ getBackgroundAccessCount(@pFlags int flags)3938 public long getBackgroundAccessCount(@OpFlags int flags) { 3939 return sumForFlagsInStates(mAccessCount, resolveLastRestrictedUidState(mOp), 3940 MIN_PRIORITY_UID_STATE, flags); 3941 } 3942 3943 /** 3944 * Gets the number times the op was accessed (performed) for a 3945 * range of uid states. 3946 * 3947 * @param fromUidState The UID state from which to query. Could be one of 3948 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP}, 3949 * {@link #UID_STATE_FOREGROUND_SERVICE_LOCATION}, 3950 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND}, 3951 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}. 3952 * @param toUidState The UID state to which to query. 3953 * @param flags The flags which are any combination of 3954 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 3955 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 3956 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 3957 * for any flag. 3958 * 3959 * @return The times the op was accessed for the given UID state. 3960 * 3961 * @see #getForegroundAccessCount(int) 3962 * @see #getBackgroundAccessCount(int) 3963 */ getAccessCount(@idState int fromUidState, @UidState int toUidState, @OpFlags int flags)3964 public long getAccessCount(@UidState int fromUidState, @UidState int toUidState, 3965 @OpFlags int flags) { 3966 return sumForFlagsInStates(mAccessCount, fromUidState, toUidState, flags); 3967 } 3968 3969 /** 3970 * Gets the number times the op was rejected in the foreground. 3971 * 3972 * @param flags The flags which are any combination of 3973 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 3974 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 3975 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 3976 * for any flag. 3977 * @return The times the op was rejected in the foreground. 3978 * 3979 * @see #getBackgroundRejectCount(int) 3980 * @see #getRejectCount(int, int, int) 3981 */ getForegroundRejectCount(@pFlags int flags)3982 public long getForegroundRejectCount(@OpFlags int flags) { 3983 return sumForFlagsInStates(mRejectCount, MAX_PRIORITY_UID_STATE, 3984 resolveFirstUnrestrictedUidState(mOp), flags); 3985 } 3986 3987 /** 3988 * Gets the number times the op was rejected in the background. 3989 * 3990 * @param flags The flags which are any combination of 3991 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 3992 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 3993 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 3994 * for any flag. 3995 * @return The times the op was rejected in the background. 3996 * 3997 * @see #getForegroundRejectCount(int) 3998 * @see #getRejectCount(int, int, int) 3999 */ getBackgroundRejectCount(@pFlags int flags)4000 public long getBackgroundRejectCount(@OpFlags int flags) { 4001 return sumForFlagsInStates(mRejectCount, resolveLastRestrictedUidState(mOp), 4002 MIN_PRIORITY_UID_STATE, flags); 4003 } 4004 4005 /** 4006 * Gets the number times the op was rejected for a given range of UID states. 4007 * 4008 * @param fromUidState The UID state from which to query. Could be one of 4009 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP}, 4010 * {@link #UID_STATE_FOREGROUND_SERVICE_LOCATION}, 4011 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND}, 4012 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}. 4013 * @param toUidState The UID state to which to query. 4014 * @param flags The flags which are any combination of 4015 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 4016 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 4017 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 4018 * for any flag. 4019 * 4020 * @return The times the op was rejected for the given UID state. 4021 * 4022 * @see #getForegroundRejectCount(int) 4023 * @see #getBackgroundRejectCount(int) 4024 */ getRejectCount(@idState int fromUidState, @UidState int toUidState, @OpFlags int flags)4025 public long getRejectCount(@UidState int fromUidState, @UidState int toUidState, 4026 @OpFlags int flags) { 4027 return sumForFlagsInStates(mRejectCount, fromUidState, toUidState, flags); 4028 } 4029 4030 /** 4031 * Gets the total duration the app op was accessed (performed) in the foreground. 4032 * The duration is in wall time. 4033 * 4034 * @param flags The flags which are any combination of 4035 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 4036 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 4037 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 4038 * for any flag. 4039 * @return The total duration the app op was accessed in the foreground. 4040 * 4041 * @see #getBackgroundAccessDuration(int) 4042 * @see #getAccessDuration(int, int, int) 4043 */ getForegroundAccessDuration(@pFlags int flags)4044 public long getForegroundAccessDuration(@OpFlags int flags) { 4045 return sumForFlagsInStates(mAccessDuration, MAX_PRIORITY_UID_STATE, 4046 resolveFirstUnrestrictedUidState(mOp), flags); 4047 } 4048 4049 /** 4050 * Gets the total duration the app op was accessed (performed) in the background. 4051 * The duration is in wall time. 4052 * 4053 * @param flags The flags which are any combination of 4054 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 4055 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 4056 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 4057 * for any flag. 4058 * @return The total duration the app op was accessed in the background. 4059 * 4060 * @see #getForegroundAccessDuration(int) 4061 * @see #getAccessDuration(int, int, int) 4062 */ getBackgroundAccessDuration(@pFlags int flags)4063 public long getBackgroundAccessDuration(@OpFlags int flags) { 4064 return sumForFlagsInStates(mAccessDuration, resolveLastRestrictedUidState(mOp), 4065 MIN_PRIORITY_UID_STATE, flags); 4066 } 4067 4068 /** 4069 * Gets the total duration the app op was accessed (performed) for a given 4070 * range of UID states. The duration is in wall time. 4071 * 4072 * @param fromUidState The UID state from which to query. Could be one of 4073 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP}, 4074 * {@link #UID_STATE_FOREGROUND_SERVICE_LOCATION}, 4075 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND}, 4076 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}. 4077 * @param toUidState The UID state from which to query. 4078 * @param flags The flags which are any combination of 4079 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 4080 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 4081 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 4082 * for any flag. 4083 * 4084 * @return The total duration the app op was accessed for the given UID state. 4085 * 4086 * @see #getForegroundAccessDuration(int) 4087 * @see #getBackgroundAccessDuration(int) 4088 */ getAccessDuration(@idState int fromUidState, @UidState int toUidState, @OpFlags int flags)4089 public long getAccessDuration(@UidState int fromUidState, @UidState int toUidState, 4090 @OpFlags int flags) { 4091 return sumForFlagsInStates(mAccessDuration, fromUidState, toUidState, flags); 4092 } 4093 4094 @Override describeContents()4095 public int describeContents() { 4096 return 0; 4097 } 4098 4099 @Override writeToParcel(Parcel parcel, int flags)4100 public void writeToParcel(Parcel parcel, int flags) { 4101 parcel.writeInt(mOp); 4102 writeLongSparseLongArrayToParcel(mAccessCount, parcel); 4103 writeLongSparseLongArrayToParcel(mRejectCount, parcel); 4104 writeLongSparseLongArrayToParcel(mAccessDuration, parcel); 4105 } 4106 4107 @Override equals(@ullable Object obj)4108 public boolean equals(@Nullable Object obj) { 4109 if (this == obj) { 4110 return true; 4111 } 4112 if (obj == null || getClass() != obj.getClass()) { 4113 return false; 4114 } 4115 final HistoricalOp other = (HistoricalOp) obj; 4116 if (mOp != other.mOp) { 4117 return false; 4118 } 4119 if (!Objects.equals(mAccessCount, other.mAccessCount)) { 4120 return false; 4121 } 4122 if (!Objects.equals(mRejectCount, other.mRejectCount)) { 4123 return false; 4124 } 4125 return Objects.equals(mAccessDuration, other.mAccessDuration); 4126 } 4127 4128 @Override hashCode()4129 public int hashCode() { 4130 int result = mOp; 4131 result = 31 * result + Objects.hashCode(mAccessCount); 4132 result = 31 * result + Objects.hashCode(mRejectCount); 4133 result = 31 * result + Objects.hashCode(mAccessDuration); 4134 return result; 4135 } 4136 accept(@onNull HistoricalOpsVisitor visitor)4137 private void accept(@NonNull HistoricalOpsVisitor visitor) { 4138 visitor.visitHistoricalOp(this); 4139 } 4140 getOrCreateAccessCount()4141 private @NonNull LongSparseLongArray getOrCreateAccessCount() { 4142 if (mAccessCount == null) { 4143 mAccessCount = new LongSparseLongArray(); 4144 } 4145 return mAccessCount; 4146 } 4147 getOrCreateRejectCount()4148 private @NonNull LongSparseLongArray getOrCreateRejectCount() { 4149 if (mRejectCount == null) { 4150 mRejectCount = new LongSparseLongArray(); 4151 } 4152 return mRejectCount; 4153 } 4154 getOrCreateAccessDuration()4155 private @NonNull LongSparseLongArray getOrCreateAccessDuration() { 4156 if (mAccessDuration == null) { 4157 mAccessDuration = new LongSparseLongArray(); 4158 } 4159 return mAccessDuration; 4160 } 4161 4162 /** 4163 * Multiplies the entries in the array with the passed in scale factor and 4164 * rounds the result at up 0.5 boundary. 4165 * 4166 * @param data The data to scale. 4167 * @param scaleFactor The scale factor. 4168 */ scale(@onNull LongSparseLongArray data, double scaleFactor)4169 private static void scale(@NonNull LongSparseLongArray data, double scaleFactor) { 4170 if (data != null) { 4171 final int size = data.size(); 4172 for (int i = 0; i < size; i++) { 4173 data.put(data.keyAt(i), (long) HistoricalOps.round( 4174 (double) data.valueAt(i) * scaleFactor)); 4175 } 4176 } 4177 } 4178 4179 /** 4180 * Merges two arrays while lazily acquiring the destination. 4181 * 4182 * @param thisSupplier The destination supplier. 4183 * @param other The array to merge in. 4184 */ merge(@onNull Supplier<LongSparseLongArray> thisSupplier, @Nullable LongSparseLongArray other)4185 private static void merge(@NonNull Supplier<LongSparseLongArray> thisSupplier, 4186 @Nullable LongSparseLongArray other) { 4187 if (other != null) { 4188 final int otherSize = other.size(); 4189 for (int i = 0; i < otherSize; i++) { 4190 final LongSparseLongArray that = thisSupplier.get(); 4191 final long otherKey = other.keyAt(i); 4192 final long otherValue = other.valueAt(i); 4193 that.put(otherKey, that.get(otherKey) + otherValue); 4194 } 4195 } 4196 } 4197 4198 /** @hide */ collectKeys()4199 public @Nullable LongSparseArray<Object> collectKeys() { 4200 LongSparseArray<Object> result = AppOpsManager.collectKeys(mAccessCount, 4201 null /*result*/); 4202 result = AppOpsManager.collectKeys(mRejectCount, result); 4203 result = AppOpsManager.collectKeys(mAccessDuration, result); 4204 return result; 4205 } 4206 4207 public static final @android.annotation.NonNull Creator<HistoricalOp> CREATOR = 4208 new Creator<HistoricalOp>() { 4209 @Override 4210 public @NonNull HistoricalOp createFromParcel(@NonNull Parcel source) { 4211 return new HistoricalOp(source); 4212 } 4213 4214 @Override 4215 public @NonNull HistoricalOp[] newArray(int size) { 4216 return new HistoricalOp[size]; 4217 } 4218 }; 4219 } 4220 4221 /** 4222 * Computes the sum of the counts for the given flags in between the begin and 4223 * end UID states. 4224 * 4225 * @param counts The data array. 4226 * @param beginUidState The beginning UID state (inclusive). 4227 * @param endUidState The end UID state (inclusive). 4228 * @param flags The UID flags. 4229 * @return The sum. 4230 */ sumForFlagsInStates(@ullable LongSparseLongArray counts, @UidState int beginUidState, @UidState int endUidState, @OpFlags int flags)4231 private static long sumForFlagsInStates(@Nullable LongSparseLongArray counts, 4232 @UidState int beginUidState, @UidState int endUidState, @OpFlags int flags) { 4233 if (counts == null) { 4234 return 0; 4235 } 4236 long sum = 0; 4237 while (flags != 0) { 4238 final int flag = 1 << Integer.numberOfTrailingZeros(flags); 4239 flags &= ~flag; 4240 for (int uidState : UID_STATES) { 4241 if (uidState < beginUidState || uidState > endUidState) { 4242 continue; 4243 } 4244 final long key = makeKey(uidState, flag); 4245 sum += counts.get(key); 4246 } 4247 } 4248 return sum; 4249 } 4250 4251 /** 4252 * Finds the first non-negative value for the given flags in between the begin and 4253 * end UID states. 4254 * 4255 * @param counts The data array. 4256 * @param beginUidState The beginning UID state (inclusive). 4257 * @param endUidState The end UID state (inclusive). 4258 * @param flags The UID flags. 4259 * @return The non-negative value or -1. 4260 */ findFirstNonNegativeForFlagsInStates(@ullable LongSparseLongArray counts, @UidState int beginUidState, @UidState int endUidState, @OpFlags int flags)4261 private static long findFirstNonNegativeForFlagsInStates(@Nullable LongSparseLongArray counts, 4262 @UidState int beginUidState, @UidState int endUidState, @OpFlags int flags) { 4263 if (counts == null) { 4264 return -1; 4265 } 4266 while (flags != 0) { 4267 final int flag = 1 << Integer.numberOfTrailingZeros(flags); 4268 flags &= ~flag; 4269 for (int uidState : UID_STATES) { 4270 if (uidState < beginUidState || uidState > endUidState) { 4271 continue; 4272 } 4273 final long key = makeKey(uidState, flag); 4274 final long value = counts.get(key); 4275 if (value >= 0) { 4276 return value; 4277 } 4278 } 4279 } 4280 return -1; 4281 } 4282 4283 /** 4284 * Finds the first non-null value for the given flags in between the begin and 4285 * end UID states. 4286 * 4287 * @param counts The data array. 4288 * @param beginUidState The beginning UID state (inclusive). 4289 * @param endUidState The end UID state (inclusive). 4290 * @param flags The UID flags. 4291 * @return The non-negative value or -1. 4292 */ findFirstNonNullForFlagsInStates( @ullable LongSparseArray<String> counts, @UidState int beginUidState, @UidState int endUidState, @OpFlags int flags)4293 private static @Nullable String findFirstNonNullForFlagsInStates( 4294 @Nullable LongSparseArray<String> counts, @UidState int beginUidState, 4295 @UidState int endUidState, @OpFlags int flags) { 4296 if (counts == null) { 4297 return null; 4298 } 4299 while (flags != 0) { 4300 final int flag = 1 << Integer.numberOfTrailingZeros(flags); 4301 flags &= ~flag; 4302 for (int uidState : UID_STATES) { 4303 if (uidState < beginUidState || uidState > endUidState) { 4304 continue; 4305 } 4306 final long key = makeKey(uidState, flag); 4307 final String value = counts.get(key); 4308 if (value != null) { 4309 return value; 4310 } 4311 } 4312 } 4313 return null; 4314 } 4315 4316 /** 4317 * Callback for notification of changes to operation state. 4318 */ 4319 public interface OnOpChangedListener { onOpChanged(String op, String packageName)4320 public void onOpChanged(String op, String packageName); 4321 } 4322 4323 /** 4324 * Callback for notification of changes to operation active state. 4325 * 4326 * @hide 4327 */ 4328 @TestApi 4329 public interface OnOpActiveChangedListener { 4330 /** 4331 * Called when the active state of an app op changes. 4332 * 4333 * @param code The op code. 4334 * @param uid The UID performing the operation. 4335 * @param packageName The package performing the operation. 4336 * @param active Whether the operation became active or inactive. 4337 */ onOpActiveChanged(int code, int uid, String packageName, boolean active)4338 void onOpActiveChanged(int code, int uid, String packageName, boolean active); 4339 } 4340 4341 /** 4342 * Callback for notification of an op being noted. 4343 * 4344 * @hide 4345 */ 4346 public interface OnOpNotedListener { 4347 /** 4348 * Called when an op was noted. 4349 * 4350 * @param code The op code. 4351 * @param uid The UID performing the operation. 4352 * @param packageName The package performing the operation. 4353 * @param result The result of the note. 4354 */ onOpNoted(int code, int uid, String packageName, int result)4355 void onOpNoted(int code, int uid, String packageName, int result); 4356 } 4357 4358 /** 4359 * Callback for notification of changes to operation state. 4360 * This allows you to see the raw op codes instead of strings. 4361 * @hide 4362 */ 4363 public static class OnOpChangedInternalListener implements OnOpChangedListener { onOpChanged(String op, String packageName)4364 public void onOpChanged(String op, String packageName) { } onOpChanged(int op, String packageName)4365 public void onOpChanged(int op, String packageName) { } 4366 } 4367 AppOpsManager(Context context, IAppOpsService service)4368 AppOpsManager(Context context, IAppOpsService service) { 4369 mContext = context; 4370 mService = service; 4371 } 4372 4373 /** 4374 * Retrieve current operation state for all applications. 4375 * 4376 * The mode of the ops returned are set for the package but may not reflect their effective 4377 * state due to UID policy or because it's controlled by a different master op. 4378 * 4379 * Use {@link #unsafeCheckOp(String, int, String)}} or {@link #noteOp(String, int, String)} 4380 * if the effective mode is needed. 4381 * 4382 * @param ops The set of operations you are interested in, or null if you want all of them. 4383 * @hide 4384 */ 4385 @SystemApi 4386 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) getPackagesForOps(@ullable String[] ops)4387 public @NonNull List<AppOpsManager.PackageOps> getPackagesForOps(@Nullable String[] ops) { 4388 final int opCount = ops.length; 4389 final int[] opCodes = new int[opCount]; 4390 for (int i = 0; i < opCount; i++) { 4391 opCodes[i] = sOpStrToOp.get(ops[i]); 4392 } 4393 final List<AppOpsManager.PackageOps> result = getPackagesForOps(opCodes); 4394 return (result != null) ? result : Collections.emptyList(); 4395 } 4396 4397 /** 4398 * Retrieve current operation state for all applications. 4399 * 4400 * The mode of the ops returned are set for the package but may not reflect their effective 4401 * state due to UID policy or because it's controlled by a different master op. 4402 * 4403 * Use {@link #unsafeCheckOp(String, int, String)}} or {@link #noteOp(String, int, String)} 4404 * if the effective mode is needed. 4405 * 4406 * @param ops The set of operations you are interested in, or null if you want all of them. 4407 * @hide 4408 */ 4409 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) 4410 @UnsupportedAppUsage getPackagesForOps(int[] ops)4411 public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) { 4412 try { 4413 return mService.getPackagesForOps(ops); 4414 } catch (RemoteException e) { 4415 throw e.rethrowFromSystemServer(); 4416 } 4417 } 4418 4419 /** 4420 * Retrieve current operation state for one application. 4421 * 4422 * The mode of the ops returned are set for the package but may not reflect their effective 4423 * state due to UID policy or because it's controlled by a different master op. 4424 * 4425 * Use {@link #unsafeCheckOp(String, int, String)}} or {@link #noteOp(String, int, String)} 4426 * if the effective mode is needed. 4427 * 4428 * @param uid The uid of the application of interest. 4429 * @param packageName The name of the application of interest. 4430 * @param ops The set of operations you are interested in, or null if you want all of them. 4431 * 4432 * @deprecated The int op codes are not stable and you should use the string based op 4433 * names which are stable and namespaced. Use 4434 * {@link #getOpsForPackage(int, String, String...)})}. 4435 * 4436 * @hide 4437 * @removed 4438 */ 4439 @Deprecated 4440 @SystemApi 4441 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) getOpsForPackage(int uid, @NonNull String packageName, @Nullable int[] ops)4442 public @NonNull List<PackageOps> getOpsForPackage(int uid, @NonNull String packageName, 4443 @Nullable int[] ops) { 4444 try { 4445 return mService.getOpsForPackage(uid, packageName, ops); 4446 } catch (RemoteException e) { 4447 throw e.rethrowFromSystemServer(); 4448 } 4449 } 4450 4451 /** 4452 * Retrieve current operation state for one application. The UID and the 4453 * package must match. 4454 * 4455 * The mode of the ops returned are set for the package but may not reflect their effective 4456 * state due to UID policy or because it's controlled by a different master op. 4457 * 4458 * Use {@link #unsafeCheckOp(String, int, String)}} or {@link #noteOp(String, int, String)} 4459 * if the effective mode is needed. 4460 * 4461 * @param uid The uid of the application of interest. 4462 * @param packageName The name of the application of interest. 4463 * @param ops The set of operations you are interested in, or null if you want all of them. 4464 * 4465 * @hide 4466 */ 4467 @SystemApi 4468 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) getOpsForPackage(int uid, @NonNull String packageName, @Nullable String... ops)4469 public @NonNull List<AppOpsManager.PackageOps> getOpsForPackage(int uid, 4470 @NonNull String packageName, @Nullable String... ops) { 4471 int[] opCodes = null; 4472 if (ops != null) { 4473 opCodes = new int[ops.length]; 4474 for (int i = 0; i < ops.length; i++) { 4475 opCodes[i] = strOpToOp(ops[i]); 4476 } 4477 } 4478 try { 4479 final List<PackageOps> result = mService.getOpsForPackage(uid, packageName, opCodes); 4480 if (result == null) { 4481 return Collections.emptyList(); 4482 } 4483 return result; 4484 } catch (RemoteException e) { 4485 throw e.rethrowFromSystemServer(); 4486 } 4487 } 4488 4489 /** 4490 * Retrieve historical app op stats for a period. 4491 * 4492 * @param request A request object describing the data being queried for. 4493 * @param executor Executor on which to run the callback. If <code>null</code> 4494 * the callback is executed on the default executor running on the main thread. 4495 * @param callback Callback on which to deliver the result. 4496 * 4497 * @throws IllegalArgumentException If any of the argument contracts is violated. 4498 * 4499 * @hide 4500 */ 4501 @TestApi 4502 @SystemApi 4503 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) getHistoricalOps(@onNull HistoricalOpsRequest request, @NonNull Executor executor, @NonNull Consumer<HistoricalOps> callback)4504 public void getHistoricalOps(@NonNull HistoricalOpsRequest request, 4505 @NonNull Executor executor, @NonNull Consumer<HistoricalOps> callback) { 4506 Preconditions.checkNotNull(executor, "executor cannot be null"); 4507 Preconditions.checkNotNull(callback, "callback cannot be null"); 4508 try { 4509 mService.getHistoricalOps(request.mUid, request.mPackageName, request.mOpNames, 4510 request.mBeginTimeMillis, request.mEndTimeMillis, request.mFlags, 4511 new RemoteCallback((result) -> { 4512 final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS); 4513 final long identity = Binder.clearCallingIdentity(); 4514 try { 4515 executor.execute(() -> callback.accept(ops)); 4516 } finally { 4517 Binder.restoreCallingIdentity(identity); 4518 } 4519 })); 4520 } catch (RemoteException e) { 4521 throw e.rethrowFromSystemServer(); 4522 } 4523 } 4524 4525 /** 4526 * Retrieve historical app op stats for a period. 4527 * <p> 4528 * This method queries only the on disk state and the returned ops are raw, 4529 * which is their times are relative to the history start as opposed to the 4530 * epoch start. 4531 * 4532 * @param request A request object describing the data being queried for. 4533 * @param executor Executor on which to run the callback. If <code>null</code> 4534 * the callback is executed on the default executor running on the main thread. 4535 * @param callback Callback on which to deliver the result. 4536 * 4537 * @throws IllegalArgumentException If any of the argument contracts is violated. 4538 * 4539 * @hide 4540 */ 4541 @TestApi 4542 @RequiresPermission(Manifest.permission.MANAGE_APPOPS) getHistoricalOpsFromDiskRaw(@onNull HistoricalOpsRequest request, @Nullable Executor executor, @NonNull Consumer<HistoricalOps> callback)4543 public void getHistoricalOpsFromDiskRaw(@NonNull HistoricalOpsRequest request, 4544 @Nullable Executor executor, @NonNull Consumer<HistoricalOps> callback) { 4545 Preconditions.checkNotNull(executor, "executor cannot be null"); 4546 Preconditions.checkNotNull(callback, "callback cannot be null"); 4547 try { 4548 mService.getHistoricalOpsFromDiskRaw(request.mUid, request.mPackageName, 4549 request.mOpNames, request.mBeginTimeMillis, request.mEndTimeMillis, 4550 request.mFlags, new RemoteCallback((result) -> { 4551 final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS); 4552 final long identity = Binder.clearCallingIdentity(); 4553 try { 4554 executor.execute(() -> callback.accept(ops)); 4555 } finally { 4556 Binder.restoreCallingIdentity(identity); 4557 } 4558 })); 4559 } catch (RemoteException e) { 4560 throw e.rethrowFromSystemServer(); 4561 } 4562 } 4563 4564 /** 4565 * Reloads the non historical state to allow testing the read/write path. 4566 * 4567 * @hide 4568 */ 4569 @TestApi 4570 @RequiresPermission(Manifest.permission.MANAGE_APPOPS) reloadNonHistoricalState()4571 public void reloadNonHistoricalState() { 4572 try { 4573 mService.reloadNonHistoricalState(); 4574 } catch (RemoteException e) { 4575 throw e.rethrowFromSystemServer(); 4576 } 4577 } 4578 4579 /** 4580 * Sets given app op in the specified mode for app ops in the UID. 4581 * This applies to all apps currently in the UID or installed in 4582 * this UID in the future. 4583 * 4584 * @param code The app op. 4585 * @param uid The UID for which to set the app. 4586 * @param mode The app op mode to set. 4587 * @hide 4588 */ 4589 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES) setUidMode(int code, int uid, @Mode int mode)4590 public void setUidMode(int code, int uid, @Mode int mode) { 4591 try { 4592 mService.setUidMode(code, uid, mode); 4593 } catch (RemoteException e) { 4594 throw e.rethrowFromSystemServer(); 4595 } 4596 } 4597 4598 /** 4599 * Sets given app op in the specified mode for app ops in the UID. 4600 * This applies to all apps currently in the UID or installed in 4601 * this UID in the future. 4602 * 4603 * @param appOp The app op. 4604 * @param uid The UID for which to set the app. 4605 * @param mode The app op mode to set. 4606 * @hide 4607 */ 4608 @SystemApi 4609 @TestApi 4610 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES) setUidMode(String appOp, int uid, @Mode int mode)4611 public void setUidMode(String appOp, int uid, @Mode int mode) { 4612 try { 4613 mService.setUidMode(AppOpsManager.strOpToOp(appOp), uid, mode); 4614 } catch (RemoteException e) { 4615 throw e.rethrowFromSystemServer(); 4616 } 4617 } 4618 4619 /** @hide */ setUserRestriction(int code, boolean restricted, IBinder token)4620 public void setUserRestriction(int code, boolean restricted, IBinder token) { 4621 setUserRestriction(code, restricted, token, /*exceptionPackages*/null); 4622 } 4623 4624 /** @hide */ setUserRestriction(int code, boolean restricted, IBinder token, String[] exceptionPackages)4625 public void setUserRestriction(int code, boolean restricted, IBinder token, 4626 String[] exceptionPackages) { 4627 setUserRestrictionForUser(code, restricted, token, exceptionPackages, mContext.getUserId()); 4628 } 4629 4630 /** @hide */ setUserRestrictionForUser(int code, boolean restricted, IBinder token, String[] exceptionPackages, int userId)4631 public void setUserRestrictionForUser(int code, boolean restricted, IBinder token, 4632 String[] exceptionPackages, int userId) { 4633 try { 4634 mService.setUserRestriction(code, restricted, token, userId, exceptionPackages); 4635 } catch (RemoteException e) { 4636 throw e.rethrowFromSystemServer(); 4637 } 4638 } 4639 4640 /** @hide */ 4641 @UnsupportedAppUsage 4642 @TestApi 4643 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES) setMode(int code, int uid, String packageName, @Mode int mode)4644 public void setMode(int code, int uid, String packageName, @Mode int mode) { 4645 try { 4646 mService.setMode(code, uid, packageName, mode); 4647 } catch (RemoteException e) { 4648 throw e.rethrowFromSystemServer(); 4649 } 4650 } 4651 4652 /** 4653 * Change the operating mode for the given op in the given app package. You must pass 4654 * in both the uid and name of the application whose mode is being modified; if these 4655 * do not match, the modification will not be applied. 4656 * 4657 * @param op The operation to modify. One of the OPSTR_* constants. 4658 * @param uid The user id of the application whose mode will be changed. 4659 * @param packageName The name of the application package name whose mode will 4660 * be changed. 4661 * @hide 4662 */ 4663 @TestApi 4664 @SystemApi 4665 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES) setMode(String op, int uid, String packageName, @Mode int mode)4666 public void setMode(String op, int uid, String packageName, @Mode int mode) { 4667 try { 4668 mService.setMode(strOpToOp(op), uid, packageName, mode); 4669 } catch (RemoteException e) { 4670 throw e.rethrowFromSystemServer(); 4671 } 4672 } 4673 4674 /** 4675 * Set a non-persisted restriction on an audio operation at a stream-level. 4676 * Restrictions are temporary additional constraints imposed on top of the persisted rules 4677 * defined by {@link #setMode}. 4678 * 4679 * @param code The operation to restrict. 4680 * @param usage The {@link android.media.AudioAttributes} usage value. 4681 * @param mode The restriction mode (MODE_IGNORED,MODE_ERRORED) or MODE_ALLOWED to unrestrict. 4682 * @param exceptionPackages Optional list of packages to exclude from the restriction. 4683 * @hide 4684 */ 4685 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES) 4686 @UnsupportedAppUsage setRestriction(int code, @AttributeUsage int usage, @Mode int mode, String[] exceptionPackages)4687 public void setRestriction(int code, @AttributeUsage int usage, @Mode int mode, 4688 String[] exceptionPackages) { 4689 try { 4690 final int uid = Binder.getCallingUid(); 4691 mService.setAudioRestriction(code, usage, uid, mode, exceptionPackages); 4692 } catch (RemoteException e) { 4693 throw e.rethrowFromSystemServer(); 4694 } 4695 } 4696 4697 /** @hide */ 4698 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES) 4699 @UnsupportedAppUsage resetAllModes()4700 public void resetAllModes() { 4701 try { 4702 mService.resetAllModes(mContext.getUserId(), null); 4703 } catch (RemoteException e) { 4704 throw e.rethrowFromSystemServer(); 4705 } 4706 } 4707 4708 /** 4709 * Gets the app op name associated with a given permission. 4710 * The app op name is one of the public constants defined 4711 * in this class such as {@link #OPSTR_COARSE_LOCATION}. 4712 * This API is intended to be used for mapping runtime 4713 * permissions to the corresponding app op. 4714 * 4715 * @param permission The permission. 4716 * @return The app op associated with the permission or null. 4717 */ permissionToOp(String permission)4718 public static String permissionToOp(String permission) { 4719 final Integer opCode = sPermToOp.get(permission); 4720 if (opCode == null) { 4721 return null; 4722 } 4723 return sOpToString[opCode]; 4724 } 4725 4726 /** 4727 * Monitor for changes to the operating mode for the given op in the given app package. 4728 * You can watch op changes only for your UID. 4729 * 4730 * @param op The operation to monitor, one of OPSTR_*. 4731 * @param packageName The name of the application to monitor. 4732 * @param callback Where to report changes. 4733 */ startWatchingMode(@onNull String op, @Nullable String packageName, @NonNull final OnOpChangedListener callback)4734 public void startWatchingMode(@NonNull String op, @Nullable String packageName, 4735 @NonNull final OnOpChangedListener callback) { 4736 startWatchingMode(strOpToOp(op), packageName, callback); 4737 } 4738 4739 /** 4740 * Monitor for changes to the operating mode for the given op in the given app package. 4741 * You can watch op changes only for your UID. 4742 * 4743 * @param op The operation to monitor, one of OPSTR_*. 4744 * @param packageName The name of the application to monitor. 4745 * @param flags Option flags: any combination of {@link #WATCH_FOREGROUND_CHANGES} or 0. 4746 * @param callback Where to report changes. 4747 */ startWatchingMode(@onNull String op, @Nullable String packageName, int flags, @NonNull final OnOpChangedListener callback)4748 public void startWatchingMode(@NonNull String op, @Nullable String packageName, int flags, 4749 @NonNull final OnOpChangedListener callback) { 4750 startWatchingMode(strOpToOp(op), packageName, flags, callback); 4751 } 4752 4753 /** 4754 * Monitor for changes to the operating mode for the given op in the given app package. 4755 * 4756 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission 4757 * you can watch changes only for your UID. 4758 * 4759 * @param op The operation to monitor, one of OP_*. 4760 * @param packageName The name of the application to monitor. 4761 * @param callback Where to report changes. 4762 * @hide 4763 */ 4764 @RequiresPermission(value=android.Manifest.permission.WATCH_APPOPS, conditional=true) startWatchingMode(int op, String packageName, final OnOpChangedListener callback)4765 public void startWatchingMode(int op, String packageName, final OnOpChangedListener callback) { 4766 startWatchingMode(op, packageName, 0, callback); 4767 } 4768 4769 /** 4770 * Monitor for changes to the operating mode for the given op in the given app package. 4771 * 4772 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission 4773 * you can watch changes only for your UID. 4774 * 4775 * @param op The operation to monitor, one of OP_*. 4776 * @param packageName The name of the application to monitor. 4777 * @param flags Option flags: any combination of {@link #WATCH_FOREGROUND_CHANGES} or 0. 4778 * @param callback Where to report changes. 4779 * @hide 4780 */ 4781 @RequiresPermission(value=android.Manifest.permission.WATCH_APPOPS, conditional=true) startWatchingMode(int op, String packageName, int flags, final OnOpChangedListener callback)4782 public void startWatchingMode(int op, String packageName, int flags, 4783 final OnOpChangedListener callback) { 4784 synchronized (mModeWatchers) { 4785 IAppOpsCallback cb = mModeWatchers.get(callback); 4786 if (cb == null) { 4787 cb = new IAppOpsCallback.Stub() { 4788 public void opChanged(int op, int uid, String packageName) { 4789 if (callback instanceof OnOpChangedInternalListener) { 4790 ((OnOpChangedInternalListener)callback).onOpChanged(op, packageName); 4791 } 4792 if (sOpToString[op] != null) { 4793 callback.onOpChanged(sOpToString[op], packageName); 4794 } 4795 } 4796 }; 4797 mModeWatchers.put(callback, cb); 4798 } 4799 try { 4800 mService.startWatchingModeWithFlags(op, packageName, flags, cb); 4801 } catch (RemoteException e) { 4802 throw e.rethrowFromSystemServer(); 4803 } 4804 } 4805 } 4806 4807 /** 4808 * Stop monitoring that was previously started with {@link #startWatchingMode}. All 4809 * monitoring associated with this callback will be removed. 4810 */ stopWatchingMode(@onNull OnOpChangedListener callback)4811 public void stopWatchingMode(@NonNull OnOpChangedListener callback) { 4812 synchronized (mModeWatchers) { 4813 IAppOpsCallback cb = mModeWatchers.remove(callback); 4814 if (cb != null) { 4815 try { 4816 mService.stopWatchingMode(cb); 4817 } catch (RemoteException e) { 4818 throw e.rethrowFromSystemServer(); 4819 } 4820 } 4821 } 4822 } 4823 4824 /** 4825 * Start watching for changes to the active state of app ops. An app op may be 4826 * long running and it has a clear start and stop delimiters. If an op is being 4827 * started or stopped by any package you will get a callback. To change the 4828 * watched ops for a registered callback you need to unregister and register it 4829 * again. 4830 * 4831 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission 4832 * you can watch changes only for your UID. 4833 * 4834 * @param ops The ops to watch. 4835 * @param callback Where to report changes. 4836 * 4837 * @see #isOperationActive(int, int, String) 4838 * @see #stopWatchingActive(OnOpActiveChangedListener) 4839 * @see #startOp(int, int, String) 4840 * @see #finishOp(int, int, String) 4841 * 4842 * @hide 4843 */ 4844 @TestApi 4845 // TODO: Uncomment below annotation once b/73559440 is fixed 4846 // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true) startWatchingActive(@onNull int[] ops, @NonNull OnOpActiveChangedListener callback)4847 public void startWatchingActive(@NonNull int[] ops, 4848 @NonNull OnOpActiveChangedListener callback) { 4849 Preconditions.checkNotNull(ops, "ops cannot be null"); 4850 Preconditions.checkNotNull(callback, "callback cannot be null"); 4851 IAppOpsActiveCallback cb; 4852 synchronized (mActiveWatchers) { 4853 cb = mActiveWatchers.get(callback); 4854 if (cb != null) { 4855 return; 4856 } 4857 cb = new IAppOpsActiveCallback.Stub() { 4858 @Override 4859 public void opActiveChanged(int op, int uid, String packageName, boolean active) { 4860 callback.onOpActiveChanged(op, uid, packageName, active); 4861 } 4862 }; 4863 mActiveWatchers.put(callback, cb); 4864 } 4865 try { 4866 mService.startWatchingActive(ops, cb); 4867 } catch (RemoteException e) { 4868 throw e.rethrowFromSystemServer(); 4869 } 4870 } 4871 4872 /** 4873 * Stop watching for changes to the active state of an app op. An app op may be 4874 * long running and it has a clear start and stop delimiters. Unregistering a 4875 * non-registered callback has no effect. 4876 * 4877 * @see #isOperationActive#(int, int, String) 4878 * @see #startWatchingActive(int[], OnOpActiveChangedListener) 4879 * @see #startOp(int, int, String) 4880 * @see #finishOp(int, int, String) 4881 * 4882 * @hide 4883 */ 4884 @TestApi stopWatchingActive(@onNull OnOpActiveChangedListener callback)4885 public void stopWatchingActive(@NonNull OnOpActiveChangedListener callback) { 4886 synchronized (mActiveWatchers) { 4887 final IAppOpsActiveCallback cb = mActiveWatchers.remove(callback); 4888 if (cb != null) { 4889 try { 4890 mService.stopWatchingActive(cb); 4891 } catch (RemoteException e) { 4892 throw e.rethrowFromSystemServer(); 4893 } 4894 } 4895 } 4896 } 4897 4898 /** 4899 * Start watching for noted app ops. An app op may be immediate or long running. 4900 * Immediate ops are noted while long running ones are started and stopped. This 4901 * method allows registering a listener to be notified when an app op is noted. If 4902 * an op is being noted by any package you will get a callback. To change the 4903 * watched ops for a registered callback you need to unregister and register it again. 4904 * 4905 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission 4906 * you can watch changes only for your UID. 4907 * 4908 * @param ops The ops to watch. 4909 * @param callback Where to report changes. 4910 * 4911 * @see #startWatchingActive(int[], OnOpActiveChangedListener) 4912 * @see #stopWatchingNoted(OnOpNotedListener) 4913 * @see #noteOp(String, int, String) 4914 * 4915 * @hide 4916 */ 4917 @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true) startWatchingNoted(@onNull int[] ops, @NonNull OnOpNotedListener callback)4918 public void startWatchingNoted(@NonNull int[] ops, @NonNull OnOpNotedListener callback) { 4919 IAppOpsNotedCallback cb; 4920 synchronized (mNotedWatchers) { 4921 cb = mNotedWatchers.get(callback); 4922 if (cb != null) { 4923 return; 4924 } 4925 cb = new IAppOpsNotedCallback.Stub() { 4926 @Override 4927 public void opNoted(int op, int uid, String packageName, int mode) { 4928 callback.onOpNoted(op, uid, packageName, mode); 4929 } 4930 }; 4931 mNotedWatchers.put(callback, cb); 4932 } 4933 try { 4934 mService.startWatchingNoted(ops, cb); 4935 } catch (RemoteException e) { 4936 throw e.rethrowFromSystemServer(); 4937 } 4938 } 4939 4940 /** 4941 * Stop watching for noted app ops. An app op may be immediate or long running. 4942 * Unregistering a non-registered callback has no effect. 4943 * 4944 * @see #startWatchingNoted(int[], OnOpNotedListener) 4945 * @see #noteOp(String, int, String) 4946 * 4947 * @hide 4948 */ stopWatchingNoted(@onNull OnOpNotedListener callback)4949 public void stopWatchingNoted(@NonNull OnOpNotedListener callback) { 4950 synchronized (mNotedWatchers) { 4951 final IAppOpsNotedCallback cb = mNotedWatchers.get(callback); 4952 if (cb != null) { 4953 try { 4954 mService.stopWatchingNoted(cb); 4955 } catch (RemoteException e) { 4956 throw e.rethrowFromSystemServer(); 4957 } 4958 } 4959 } 4960 } 4961 buildSecurityExceptionMsg(int op, int uid, String packageName)4962 private String buildSecurityExceptionMsg(int op, int uid, String packageName) { 4963 return packageName + " from uid " + uid + " not allowed to perform " + sOpNames[op]; 4964 } 4965 4966 /** 4967 * {@hide} 4968 */ 4969 @UnsupportedAppUsage 4970 @TestApi strOpToOp(@onNull String op)4971 public static int strOpToOp(@NonNull String op) { 4972 Integer val = sOpStrToOp.get(op); 4973 if (val == null) { 4974 throw new IllegalArgumentException("Unknown operation string: " + op); 4975 } 4976 return val; 4977 } 4978 4979 /** 4980 * Do a quick check for whether an application might be able to perform an operation. 4981 * This is <em>not</em> a security check; you must use {@link #noteOp(String, int, String)} 4982 * or {@link #startOp(String, int, String)} for your actual security checks, which also 4983 * ensure that the given uid and package name are consistent. This function can just be 4984 * used for a quick check to see if an operation has been disabled for the application, 4985 * as an early reject of some work. This does not modify the time stamp or other data 4986 * about the operation. 4987 * 4988 * <p>Important things this will not do (which you need to ultimate use 4989 * {@link #noteOp(String, int, String)} or {@link #startOp(String, int, String)} to cover):</p> 4990 * <ul> 4991 * <li>Verifying the uid and package are consistent, so callers can't spoof 4992 * their identity.</li> 4993 * <li>Taking into account the current foreground/background state of the 4994 * app; apps whose mode varies by this state will always be reported 4995 * as {@link #MODE_ALLOWED}.</li> 4996 * </ul> 4997 * 4998 * @param op The operation to check. One of the OPSTR_* constants. 4999 * @param uid The user id of the application attempting to perform the operation. 5000 * @param packageName The name of the application attempting to perform the operation. 5001 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or 5002 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without 5003 * causing the app to crash). 5004 * @throws SecurityException If the app has been configured to crash on this op. 5005 */ unsafeCheckOp(@onNull String op, int uid, @NonNull String packageName)5006 public int unsafeCheckOp(@NonNull String op, int uid, @NonNull String packageName) { 5007 return checkOp(strOpToOp(op), uid, packageName); 5008 } 5009 5010 /** 5011 * @deprecated Renamed to {@link #unsafeCheckOp(String, int, String)}. 5012 */ 5013 @Deprecated checkOp(@onNull String op, int uid, @NonNull String packageName)5014 public int checkOp(@NonNull String op, int uid, @NonNull String packageName) { 5015 return checkOp(strOpToOp(op), uid, packageName); 5016 } 5017 5018 /** 5019 * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it 5020 * returns {@link #MODE_ERRORED}. 5021 */ unsafeCheckOpNoThrow(@onNull String op, int uid, @NonNull String packageName)5022 public int unsafeCheckOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) { 5023 return checkOpNoThrow(strOpToOp(op), uid, packageName); 5024 } 5025 5026 /** 5027 * @deprecated Renamed to {@link #unsafeCheckOpNoThrow(String, int, String)}. 5028 */ 5029 @Deprecated checkOpNoThrow(@onNull String op, int uid, @NonNull String packageName)5030 public int checkOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) { 5031 return checkOpNoThrow(strOpToOp(op), uid, packageName); 5032 } 5033 5034 /** 5035 * Like {@link #checkOp} but returns the <em>raw</em> mode associated with the op. 5036 * Does not throw a security exception, does not translate {@link #MODE_FOREGROUND}. 5037 */ unsafeCheckOpRaw(@onNull String op, int uid, @NonNull String packageName)5038 public int unsafeCheckOpRaw(@NonNull String op, int uid, @NonNull String packageName) { 5039 try { 5040 return mService.checkOperationRaw(strOpToOp(op), uid, packageName); 5041 } catch (RemoteException e) { 5042 throw e.rethrowFromSystemServer(); 5043 } 5044 } 5045 5046 /** 5047 * Like {@link #unsafeCheckOpNoThrow(String, int, String)} but returns the <em>raw</em> 5048 * mode associated with the op. Does not throw a security exception, does not translate 5049 * {@link #MODE_FOREGROUND}. 5050 */ unsafeCheckOpRawNoThrow(@onNull String op, int uid, @NonNull String packageName)5051 public int unsafeCheckOpRawNoThrow(@NonNull String op, int uid, @NonNull String packageName) { 5052 try { 5053 return mService.checkOperationRaw(strOpToOp(op), uid, packageName); 5054 } catch (RemoteException e) { 5055 throw e.rethrowFromSystemServer(); 5056 } 5057 } 5058 5059 /** 5060 * Make note of an application performing an operation. Note that you must pass 5061 * in both the uid and name of the application to be checked; this function will verify 5062 * that these two match, and if not, return {@link #MODE_IGNORED}. If this call 5063 * succeeds, the last execution time of the operation for this app will be updated to 5064 * the current time. 5065 * @param op The operation to note. One of the OPSTR_* constants. 5066 * @param uid The user id of the application attempting to perform the operation. 5067 * @param packageName The name of the application attempting to perform the operation. 5068 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or 5069 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without 5070 * causing the app to crash). 5071 * @throws SecurityException If the app has been configured to crash on this op. 5072 */ noteOp(@onNull String op, int uid, @NonNull String packageName)5073 public int noteOp(@NonNull String op, int uid, @NonNull String packageName) { 5074 return noteOp(strOpToOp(op), uid, packageName); 5075 } 5076 5077 /** 5078 * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it 5079 * returns {@link #MODE_ERRORED}. 5080 */ noteOpNoThrow(@onNull String op, int uid, @NonNull String packageName)5081 public int noteOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) { 5082 return noteOpNoThrow(strOpToOp(op), uid, packageName); 5083 } 5084 5085 /** 5086 * Make note of an application performing an operation on behalf of another 5087 * application when handling an IPC. Note that you must pass the package name 5088 * of the application that is being proxied while its UID will be inferred from 5089 * the IPC state; this function will verify that the calling uid and proxied 5090 * package name match, and if not, return {@link #MODE_IGNORED}. If this call 5091 * succeeds, the last execution time of the operation for the proxied app and 5092 * your app will be updated to the current time. 5093 * @param op The operation to note. One of the OPSTR_* constants. 5094 * @param proxiedPackageName The name of the application calling into the proxy application. 5095 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or 5096 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without 5097 * causing the app to crash). 5098 * @throws SecurityException If the app has been configured to crash on this op. 5099 */ noteProxyOp(@onNull String op, @NonNull String proxiedPackageName)5100 public int noteProxyOp(@NonNull String op, @NonNull String proxiedPackageName) { 5101 return noteProxyOp(strOpToOp(op), proxiedPackageName); 5102 } 5103 5104 /** 5105 * Like {@link #noteProxyOp(String, String)} but instead 5106 * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}. 5107 * 5108 * <p>This API requires the package with the {@code proxiedPackageName} to belongs to 5109 * {@link Binder#getCallingUid()}. 5110 */ noteProxyOpNoThrow(@onNull String op, @NonNull String proxiedPackageName)5111 public int noteProxyOpNoThrow(@NonNull String op, @NonNull String proxiedPackageName) { 5112 return noteProxyOpNoThrow(strOpToOp(op), proxiedPackageName); 5113 } 5114 5115 /** 5116 * Like {@link #noteProxyOpNoThrow(String, String)} but allows to specify the proxied uid. 5117 * 5118 * <p>This API requires package with the {@code proxiedPackageName} to belong to 5119 * {@code proxiedUid}. 5120 * 5121 * @param op The op to note 5122 * @param proxiedPackageName The package to note the op for or {@code null} if the op should be 5123 * noted for the "android" package 5124 * @param proxiedUid The uid the package belongs to 5125 */ noteProxyOpNoThrow(@onNull String op, @Nullable String proxiedPackageName, int proxiedUid)5126 public int noteProxyOpNoThrow(@NonNull String op, @Nullable String proxiedPackageName, 5127 int proxiedUid) { 5128 return noteProxyOpNoThrow(strOpToOp(op), proxiedPackageName, proxiedUid); 5129 } 5130 5131 /** 5132 * Report that an application has started executing a long-running operation. Note that you 5133 * must pass in both the uid and name of the application to be checked; this function will 5134 * verify that these two match, and if not, return {@link #MODE_IGNORED}. If this call 5135 * succeeds, the last execution time of the operation for this app will be updated to 5136 * the current time and the operation will be marked as "running". In this case you must 5137 * later call {@link #finishOp(String, int, String)} to report when the application is no 5138 * longer performing the operation. 5139 * @param op The operation to start. One of the OPSTR_* constants. 5140 * @param uid The user id of the application attempting to perform the operation. 5141 * @param packageName The name of the application attempting to perform the operation. 5142 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or 5143 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without 5144 * causing the app to crash). 5145 * @throws SecurityException If the app has been configured to crash on this op. 5146 */ startOp(@onNull String op, int uid, @NonNull String packageName)5147 public int startOp(@NonNull String op, int uid, @NonNull String packageName) { 5148 return startOp(strOpToOp(op), uid, packageName); 5149 } 5150 5151 /** 5152 * Like {@link #startOp} but instead of throwing a {@link SecurityException} it 5153 * returns {@link #MODE_ERRORED}. 5154 */ startOpNoThrow(@onNull String op, int uid, @NonNull String packageName)5155 public int startOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) { 5156 return startOpNoThrow(strOpToOp(op), uid, packageName); 5157 } 5158 5159 /** 5160 * Report that an application is no longer performing an operation that had previously 5161 * been started with {@link #startOp(String, int, String)}. There is no validation of input 5162 * or result; the parameters supplied here must be the exact same ones previously passed 5163 * in when starting the operation. 5164 */ finishOp(@onNull String op, int uid, @NonNull String packageName)5165 public void finishOp(@NonNull String op, int uid, @NonNull String packageName) { 5166 finishOp(strOpToOp(op), uid, packageName); 5167 } 5168 5169 /** 5170 * Do a quick check for whether an application might be able to perform an operation. 5171 * This is <em>not</em> a security check; you must use {@link #noteOp(int, int, String)} 5172 * or {@link #startOp(int, int, String)} for your actual security checks, which also 5173 * ensure that the given uid and package name are consistent. This function can just be 5174 * used for a quick check to see if an operation has been disabled for the application, 5175 * as an early reject of some work. This does not modify the time stamp or other data 5176 * about the operation. 5177 * 5178 * <p>Important things this will not do (which you need to ultimate use 5179 * {@link #noteOp(int, int, String)} or {@link #startOp(int, int, String)} to cover):</p> 5180 * <ul> 5181 * <li>Verifying the uid and package are consistent, so callers can't spoof 5182 * their identity.</li> 5183 * <li>Taking into account the current foreground/background state of the 5184 * app; apps whose mode varies by this state will always be reported 5185 * as {@link #MODE_ALLOWED}.</li> 5186 * </ul> 5187 * 5188 * @param op The operation to check. One of the OP_* constants. 5189 * @param uid The user id of the application attempting to perform the operation. 5190 * @param packageName The name of the application attempting to perform the operation. 5191 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or 5192 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without 5193 * causing the app to crash). 5194 * @throws SecurityException If the app has been configured to crash on this op. 5195 * @hide 5196 */ 5197 @UnsupportedAppUsage checkOp(int op, int uid, String packageName)5198 public int checkOp(int op, int uid, String packageName) { 5199 try { 5200 int mode = mService.checkOperation(op, uid, packageName); 5201 if (mode == MODE_ERRORED) { 5202 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName)); 5203 } 5204 return mode; 5205 } catch (RemoteException e) { 5206 throw e.rethrowFromSystemServer(); 5207 } 5208 } 5209 5210 /** 5211 * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it 5212 * returns {@link #MODE_ERRORED}. 5213 * @hide 5214 */ 5215 @UnsupportedAppUsage checkOpNoThrow(int op, int uid, String packageName)5216 public int checkOpNoThrow(int op, int uid, String packageName) { 5217 try { 5218 int mode = mService.checkOperation(op, uid, packageName); 5219 return mode == AppOpsManager.MODE_FOREGROUND ? AppOpsManager.MODE_ALLOWED : mode; 5220 } catch (RemoteException e) { 5221 throw e.rethrowFromSystemServer(); 5222 } 5223 } 5224 5225 /** 5226 * Do a quick check to validate if a package name belongs to a UID. 5227 * 5228 * @throws SecurityException if the package name doesn't belong to the given 5229 * UID, or if ownership cannot be verified. 5230 */ checkPackage(int uid, @NonNull String packageName)5231 public void checkPackage(int uid, @NonNull String packageName) { 5232 try { 5233 if (mService.checkPackage(uid, packageName) != MODE_ALLOWED) { 5234 throw new SecurityException( 5235 "Package " + packageName + " does not belong to " + uid); 5236 } 5237 } catch (RemoteException e) { 5238 throw e.rethrowFromSystemServer(); 5239 } 5240 } 5241 5242 /** 5243 * Like {@link #checkOp} but at a stream-level for audio operations. 5244 * @hide 5245 */ checkAudioOp(int op, int stream, int uid, String packageName)5246 public int checkAudioOp(int op, int stream, int uid, String packageName) { 5247 try { 5248 final int mode = mService.checkAudioOperation(op, stream, uid, packageName); 5249 if (mode == MODE_ERRORED) { 5250 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName)); 5251 } 5252 return mode; 5253 } catch (RemoteException e) { 5254 throw e.rethrowFromSystemServer(); 5255 } 5256 } 5257 5258 /** 5259 * Like {@link #checkAudioOp} but instead of throwing a {@link SecurityException} it 5260 * returns {@link #MODE_ERRORED}. 5261 * @hide 5262 */ checkAudioOpNoThrow(int op, int stream, int uid, String packageName)5263 public int checkAudioOpNoThrow(int op, int stream, int uid, String packageName) { 5264 try { 5265 return mService.checkAudioOperation(op, stream, uid, packageName); 5266 } catch (RemoteException e) { 5267 throw e.rethrowFromSystemServer(); 5268 } 5269 } 5270 5271 /** 5272 * Make note of an application performing an operation. Note that you must pass 5273 * in both the uid and name of the application to be checked; this function will verify 5274 * that these two match, and if not, return {@link #MODE_IGNORED}. If this call 5275 * succeeds, the last execution time of the operation for this app will be updated to 5276 * the current time. 5277 * @param op The operation to note. One of the OP_* constants. 5278 * @param uid The user id of the application attempting to perform the operation. 5279 * @param packageName The name of the application attempting to perform the operation. 5280 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or 5281 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without 5282 * causing the app to crash). 5283 * @throws SecurityException If the app has been configured to crash on this op. 5284 * @hide 5285 */ 5286 @UnsupportedAppUsage noteOp(int op, int uid, String packageName)5287 public int noteOp(int op, int uid, String packageName) { 5288 final int mode = noteOpNoThrow(op, uid, packageName); 5289 if (mode == MODE_ERRORED) { 5290 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName)); 5291 } 5292 return mode; 5293 } 5294 5295 /** 5296 * Make note of an application performing an operation on behalf of another 5297 * application when handling an IPC. Note that you must pass the package name 5298 * of the application that is being proxied while its UID will be inferred from 5299 * the IPC state; this function will verify that the calling uid and proxied 5300 * package name match, and if not, return {@link #MODE_IGNORED}. If this call 5301 * succeeds, the last execution time of the operation for the proxied app and 5302 * your app will be updated to the current time. 5303 * @param op The operation to note. One of the OPSTR_* constants. 5304 * @param proxiedPackageName The name of the application calling into the proxy application. 5305 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or 5306 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without 5307 * causing the app to crash). 5308 * @throws SecurityException If the proxy or proxied app has been configured to 5309 * crash on this op. 5310 * 5311 * @hide 5312 */ 5313 @UnsupportedAppUsage noteProxyOp(int op, String proxiedPackageName)5314 public int noteProxyOp(int op, String proxiedPackageName) { 5315 int mode = noteProxyOpNoThrow(op, proxiedPackageName); 5316 if (mode == MODE_ERRORED) { 5317 throw new SecurityException("Proxy package " + mContext.getOpPackageName() 5318 + " from uid " + Process.myUid() + " or calling package " 5319 + proxiedPackageName + " from uid " + Binder.getCallingUid() 5320 + " not allowed to perform " + sOpNames[op]); 5321 } 5322 return mode; 5323 } 5324 5325 /** 5326 * Like {@link #noteProxyOp(int, String)} but instead 5327 * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}. 5328 * @hide 5329 */ noteProxyOpNoThrow(int op, String proxiedPackageName, int proxiedUid)5330 public int noteProxyOpNoThrow(int op, String proxiedPackageName, int proxiedUid) { 5331 try { 5332 return mService.noteProxyOperation(op, Process.myUid(), mContext.getOpPackageName(), 5333 proxiedUid, proxiedPackageName); 5334 } catch (RemoteException e) { 5335 throw e.rethrowFromSystemServer(); 5336 } 5337 } 5338 5339 /** 5340 * Like {@link #noteProxyOp(int, String)} but instead 5341 * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}. 5342 * 5343 * <p>This API requires the package with {@code proxiedPackageName} to belongs to 5344 * {@link Binder#getCallingUid()}. 5345 * 5346 * @hide 5347 */ noteProxyOpNoThrow(int op, String proxiedPackageName)5348 public int noteProxyOpNoThrow(int op, String proxiedPackageName) { 5349 return noteProxyOpNoThrow(op, proxiedPackageName, Binder.getCallingUid()); 5350 } 5351 5352 /** 5353 * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it 5354 * returns {@link #MODE_ERRORED}. 5355 * @hide 5356 */ 5357 @UnsupportedAppUsage noteOpNoThrow(int op, int uid, String packageName)5358 public int noteOpNoThrow(int op, int uid, String packageName) { 5359 try { 5360 return mService.noteOperation(op, uid, packageName); 5361 } catch (RemoteException e) { 5362 throw e.rethrowFromSystemServer(); 5363 } 5364 } 5365 5366 /** @hide */ 5367 @UnsupportedAppUsage noteOp(int op)5368 public int noteOp(int op) { 5369 return noteOp(op, Process.myUid(), mContext.getOpPackageName()); 5370 } 5371 5372 /** @hide */ 5373 @UnsupportedAppUsage getToken(IAppOpsService service)5374 public static IBinder getToken(IAppOpsService service) { 5375 synchronized (AppOpsManager.class) { 5376 if (sToken != null) { 5377 return sToken; 5378 } 5379 try { 5380 sToken = service.getToken(new Binder()); 5381 } catch (RemoteException e) { 5382 throw e.rethrowFromSystemServer(); 5383 } 5384 return sToken; 5385 } 5386 } 5387 5388 /** @hide */ startOp(int op)5389 public int startOp(int op) { 5390 return startOp(op, Process.myUid(), mContext.getOpPackageName()); 5391 } 5392 5393 /** 5394 * Report that an application has started executing a long-running operation. Note that you 5395 * must pass in both the uid and name of the application to be checked; this function will 5396 * verify that these two match, and if not, return {@link #MODE_IGNORED}. If this call 5397 * succeeds, the last execution time of the operation for this app will be updated to 5398 * the current time and the operation will be marked as "running". In this case you must 5399 * later call {@link #finishOp(int, int, String)} to report when the application is no 5400 * longer performing the operation. 5401 * 5402 * @param op The operation to start. One of the OP_* constants. 5403 * @param uid The user id of the application attempting to perform the operation. 5404 * @param packageName The name of the application attempting to perform the operation. 5405 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or 5406 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without 5407 * causing the app to crash). 5408 * @throws SecurityException If the app has been configured to crash on this op. 5409 * @hide 5410 */ startOp(int op, int uid, String packageName)5411 public int startOp(int op, int uid, String packageName) { 5412 return startOp(op, uid, packageName, false); 5413 } 5414 5415 /** 5416 * Report that an application has started executing a long-running operation. Similar 5417 * to {@link #startOp(String, int, String) except that if the mode is {@link #MODE_DEFAULT} 5418 * the operation should succeed since the caller has performed its standard permission 5419 * checks which passed and would perform the protected operation for this mode. 5420 * 5421 * @param op The operation to start. One of the OP_* constants. 5422 * @param uid The user id of the application attempting to perform the operation. 5423 * @param packageName The name of the application attempting to perform the operation. 5424 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or 5425 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without 5426 * causing the app to crash). 5427 * @param startIfModeDefault Whether to start if mode is {@link #MODE_DEFAULT}. 5428 * 5429 * @throws SecurityException If the app has been configured to crash on this op or 5430 * the package is not in the passed in UID. 5431 * 5432 * @hide 5433 */ startOp(int op, int uid, String packageName, boolean startIfModeDefault)5434 public int startOp(int op, int uid, String packageName, boolean startIfModeDefault) { 5435 final int mode = startOpNoThrow(op, uid, packageName, startIfModeDefault); 5436 if (mode == MODE_ERRORED) { 5437 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName)); 5438 } 5439 return mode; 5440 } 5441 5442 /** 5443 * Like {@link #startOp} but instead of throwing a {@link SecurityException} it 5444 * returns {@link #MODE_ERRORED}. 5445 * @hide 5446 */ startOpNoThrow(int op, int uid, String packageName)5447 public int startOpNoThrow(int op, int uid, String packageName) { 5448 return startOpNoThrow(op, uid, packageName, false); 5449 } 5450 5451 /** 5452 * Like {@link #startOp(int, int, String, boolean)} but instead of throwing a 5453 * {@link SecurityException} it returns {@link #MODE_ERRORED}. 5454 * 5455 * @param op The operation to start. One of the OP_* constants. 5456 * @param uid The user id of the application attempting to perform the operation. 5457 * @param packageName The name of the application attempting to perform the operation. 5458 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or 5459 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without 5460 * causing the app to crash). 5461 * @param startIfModeDefault Whether to start if mode is {@link #MODE_DEFAULT}. 5462 * 5463 * @hide 5464 */ startOpNoThrow(int op, int uid, String packageName, boolean startIfModeDefault)5465 public int startOpNoThrow(int op, int uid, String packageName, boolean startIfModeDefault) { 5466 try { 5467 return mService.startOperation(getToken(mService), op, uid, packageName, 5468 startIfModeDefault); 5469 } catch (RemoteException e) { 5470 throw e.rethrowFromSystemServer(); 5471 } 5472 } 5473 5474 /** 5475 * Report that an application is no longer performing an operation that had previously 5476 * been started with {@link #startOp(int, int, String)}. There is no validation of input 5477 * or result; the parameters supplied here must be the exact same ones previously passed 5478 * in when starting the operation. 5479 * @hide 5480 */ finishOp(int op, int uid, String packageName)5481 public void finishOp(int op, int uid, String packageName) { 5482 try { 5483 mService.finishOperation(getToken(mService), op, uid, packageName); 5484 } catch (RemoteException e) { 5485 throw e.rethrowFromSystemServer(); 5486 } 5487 } 5488 5489 /** @hide */ finishOp(int op)5490 public void finishOp(int op) { 5491 finishOp(op, Process.myUid(), mContext.getOpPackageName()); 5492 } 5493 5494 /** 5495 * Checks whether the given op for a UID and package is active. 5496 * 5497 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission 5498 * you can query only for your UID. 5499 * 5500 * @see #startWatchingActive(int[], OnOpActiveChangedListener) 5501 * @see #stopWatchingMode(OnOpChangedListener) 5502 * @see #finishOp(int) 5503 * @see #startOp(int) 5504 * 5505 * @hide */ 5506 @TestApi 5507 // TODO: Uncomment below annotation once b/73559440 is fixed 5508 // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true) isOperationActive(int code, int uid, String packageName)5509 public boolean isOperationActive(int code, int uid, String packageName) { 5510 try { 5511 return mService.isOperationActive(code, uid, packageName); 5512 } catch (RemoteException e) { 5513 throw e.rethrowFromSystemServer(); 5514 } 5515 } 5516 5517 /** 5518 * Configures the app ops persistence for testing. 5519 * 5520 * @param mode The mode in which the historical registry operates. 5521 * @param baseSnapshotInterval The base interval on which we would be persisting a snapshot of 5522 * the historical data. The history is recursive where every subsequent step encompasses 5523 * {@code compressionStep} longer interval with {@code compressionStep} distance between 5524 * snapshots. 5525 * @param compressionStep The compression step in every iteration. 5526 * 5527 * @see #HISTORICAL_MODE_DISABLED 5528 * @see #HISTORICAL_MODE_ENABLED_ACTIVE 5529 * @see #HISTORICAL_MODE_ENABLED_PASSIVE 5530 * 5531 * @hide 5532 */ 5533 @TestApi 5534 @RequiresPermission(Manifest.permission.MANAGE_APPOPS) setHistoryParameters(@istoricalMode int mode, long baseSnapshotInterval, int compressionStep)5535 public void setHistoryParameters(@HistoricalMode int mode, long baseSnapshotInterval, 5536 int compressionStep) { 5537 try { 5538 mService.setHistoryParameters(mode, baseSnapshotInterval, compressionStep); 5539 } catch (RemoteException e) { 5540 throw e.rethrowFromSystemServer(); 5541 } 5542 } 5543 5544 /** 5545 * Offsets the history by the given duration. 5546 * 5547 * @param offsetMillis The offset duration. 5548 * 5549 * @hide 5550 */ 5551 @TestApi 5552 @RequiresPermission(Manifest.permission.MANAGE_APPOPS) offsetHistory(long offsetMillis)5553 public void offsetHistory(long offsetMillis) { 5554 try { 5555 mService.offsetHistory(offsetMillis); 5556 } catch (RemoteException e) { 5557 throw e.rethrowFromSystemServer(); 5558 } 5559 } 5560 5561 /** 5562 * Adds ops to the history directly. This could be useful for testing especially 5563 * when the historical registry operates in {@link #HISTORICAL_MODE_ENABLED_PASSIVE} 5564 * mode. 5565 * 5566 * @param ops The ops to add to the history. 5567 * 5568 * @see #setHistoryParameters(int, long, int) 5569 * @see #HISTORICAL_MODE_ENABLED_PASSIVE 5570 * 5571 * @hide 5572 */ 5573 @TestApi 5574 @RequiresPermission(Manifest.permission.MANAGE_APPOPS) addHistoricalOps(@onNull HistoricalOps ops)5575 public void addHistoricalOps(@NonNull HistoricalOps ops) { 5576 try { 5577 mService.addHistoricalOps(ops); 5578 } catch (RemoteException e) { 5579 throw e.rethrowFromSystemServer(); 5580 } 5581 } 5582 5583 /** 5584 * Resets the app ops persistence for testing. 5585 * 5586 * @see #setHistoryParameters(int, long, int) 5587 * 5588 * @hide 5589 */ 5590 @TestApi 5591 @RequiresPermission(Manifest.permission.MANAGE_APPOPS) resetHistoryParameters()5592 public void resetHistoryParameters() { 5593 try { 5594 mService.resetHistoryParameters(); 5595 } catch (RemoteException e) { 5596 throw e.rethrowFromSystemServer(); 5597 } 5598 } 5599 5600 /** 5601 * Clears all app ops history. 5602 * 5603 * @hide 5604 */ 5605 @TestApi 5606 @RequiresPermission(Manifest.permission.MANAGE_APPOPS) clearHistory()5607 public void clearHistory() { 5608 try { 5609 mService.clearHistory(); 5610 } catch (RemoteException e) { 5611 throw e.rethrowFromSystemServer(); 5612 } 5613 } 5614 5615 /** 5616 * Returns all supported operation names. 5617 * @hide 5618 */ 5619 @SystemApi 5620 @TestApi getOpStrs()5621 public static String[] getOpStrs() { 5622 return Arrays.copyOf(sOpToString, sOpToString.length); 5623 } 5624 5625 5626 /** 5627 * @return number of App ops 5628 * @hide 5629 */ 5630 @TestApi getNumOps()5631 public static int getNumOps() { 5632 return _NUM_OP; 5633 } 5634 5635 /** 5636 * Computes the max for the given flags in between the begin and 5637 * end UID states. 5638 * 5639 * @param counts The data array. 5640 * @param flags The UID flags. 5641 * @param beginUidState The beginning UID state (exclusive). 5642 * @param endUidState The end UID state. 5643 * @return The sum. 5644 */ maxForFlagsInStates(@ullable LongSparseLongArray counts, @UidState int beginUidState, @UidState int endUidState, @OpFlags int flags)5645 private static long maxForFlagsInStates(@Nullable LongSparseLongArray counts, 5646 @UidState int beginUidState, @UidState int endUidState, 5647 @OpFlags int flags) { 5648 if (counts == null) { 5649 return 0; 5650 } 5651 long max = 0; 5652 while (flags != 0) { 5653 final int flag = 1 << Integer.numberOfTrailingZeros(flags); 5654 flags &= ~flag; 5655 for (int uidState : UID_STATES) { 5656 if (uidState < beginUidState || uidState > endUidState) { 5657 continue; 5658 } 5659 final long key = makeKey(uidState, flag); 5660 max = Math.max(max, counts.get(key)); 5661 } 5662 } 5663 return max; 5664 } 5665 5666 writeLongSparseLongArrayToParcel( @ullable LongSparseLongArray array, @NonNull Parcel parcel)5667 private static void writeLongSparseLongArrayToParcel( 5668 @Nullable LongSparseLongArray array, @NonNull Parcel parcel) { 5669 if (array != null) { 5670 final int size = array.size(); 5671 parcel.writeInt(size); 5672 for (int i = 0; i < size; i++) { 5673 parcel.writeLong(array.keyAt(i)); 5674 parcel.writeLong(array.valueAt(i)); 5675 } 5676 } else { 5677 parcel.writeInt(-1); 5678 } 5679 } 5680 readLongSparseLongArrayFromParcel( @onNull Parcel parcel)5681 private static @Nullable LongSparseLongArray readLongSparseLongArrayFromParcel( 5682 @NonNull Parcel parcel) { 5683 final int size = parcel.readInt(); 5684 if (size < 0) { 5685 return null; 5686 } 5687 final LongSparseLongArray array = new LongSparseLongArray(size); 5688 for (int i = 0; i < size; i++) { 5689 array.append(parcel.readLong(), parcel.readLong()); 5690 } 5691 return array; 5692 } 5693 writeLongSparseStringArrayToParcel( @ullable LongSparseArray<String> array, @NonNull Parcel parcel)5694 private static void writeLongSparseStringArrayToParcel( 5695 @Nullable LongSparseArray<String> array, @NonNull Parcel parcel) { 5696 if (array != null) { 5697 final int size = array.size(); 5698 parcel.writeInt(size); 5699 for (int i = 0; i < size; i++) { 5700 parcel.writeLong(array.keyAt(i)); 5701 parcel.writeString(array.valueAt(i)); 5702 } 5703 } else { 5704 parcel.writeInt(-1); 5705 } 5706 } 5707 readLongSparseStringArrayFromParcel( @onNull Parcel parcel)5708 private static @Nullable LongSparseArray<String> readLongSparseStringArrayFromParcel( 5709 @NonNull Parcel parcel) { 5710 final int size = parcel.readInt(); 5711 if (size < 0) { 5712 return null; 5713 } 5714 final LongSparseArray<String> array = new LongSparseArray<>(size); 5715 for (int i = 0; i < size; i++) { 5716 array.append(parcel.readLong(), parcel.readString()); 5717 } 5718 return array; 5719 } 5720 5721 /** 5722 * Collects the keys from an array to the result creating the result if needed. 5723 * 5724 * @param array The array whose keys to collect. 5725 * @param result The optional result store collected keys. 5726 * @return The result collected keys array. 5727 */ collectKeys(@ullable LongSparseLongArray array, @Nullable LongSparseArray<Object> result)5728 private static LongSparseArray<Object> collectKeys(@Nullable LongSparseLongArray array, 5729 @Nullable LongSparseArray<Object> result) { 5730 if (array != null) { 5731 if (result == null) { 5732 result = new LongSparseArray<>(); 5733 } 5734 final int accessSize = array.size(); 5735 for (int i = 0; i < accessSize; i++) { 5736 result.put(array.keyAt(i), null); 5737 } 5738 } 5739 return result; 5740 } 5741 5742 /** @hide */ uidStateToString(@idState int uidState)5743 public static String uidStateToString(@UidState int uidState) { 5744 switch (uidState) { 5745 case UID_STATE_PERSISTENT: { 5746 return "UID_STATE_PERSISTENT"; 5747 } 5748 case UID_STATE_TOP: { 5749 return "UID_STATE_TOP"; 5750 } 5751 case UID_STATE_FOREGROUND_SERVICE_LOCATION: { 5752 return "UID_STATE_FOREGROUND_SERVICE_LOCATION"; 5753 } 5754 case UID_STATE_FOREGROUND_SERVICE: { 5755 return "UID_STATE_FOREGROUND_SERVICE"; 5756 } 5757 case UID_STATE_FOREGROUND: { 5758 return "UID_STATE_FOREGROUND"; 5759 } 5760 case UID_STATE_BACKGROUND: { 5761 return "UID_STATE_BACKGROUND"; 5762 } 5763 case UID_STATE_CACHED: { 5764 return "UID_STATE_CACHED"; 5765 } 5766 default: { 5767 return "UNKNOWN"; 5768 } 5769 } 5770 } 5771 5772 /** @hide */ parseHistoricalMode(@onNull String mode)5773 public static int parseHistoricalMode(@NonNull String mode) { 5774 switch (mode) { 5775 case "HISTORICAL_MODE_ENABLED_ACTIVE": { 5776 return HISTORICAL_MODE_ENABLED_ACTIVE; 5777 } 5778 case "HISTORICAL_MODE_ENABLED_PASSIVE": { 5779 return HISTORICAL_MODE_ENABLED_PASSIVE; 5780 } 5781 default: { 5782 return HISTORICAL_MODE_DISABLED; 5783 } 5784 } 5785 } 5786 5787 /** @hide */ historicalModeToString(@istoricalMode int mode)5788 public static String historicalModeToString(@HistoricalMode int mode) { 5789 switch (mode) { 5790 case HISTORICAL_MODE_DISABLED: { 5791 return "HISTORICAL_MODE_DISABLED"; 5792 } 5793 case HISTORICAL_MODE_ENABLED_ACTIVE: { 5794 return "HISTORICAL_MODE_ENABLED_ACTIVE"; 5795 } 5796 case HISTORICAL_MODE_ENABLED_PASSIVE: { 5797 return "HISTORICAL_MODE_ENABLED_PASSIVE"; 5798 } 5799 default: { 5800 return "UNKNOWN"; 5801 } 5802 } 5803 } 5804 getSystemAlertWindowDefault()5805 private static int getSystemAlertWindowDefault() { 5806 final Context context = ActivityThread.currentApplication(); 5807 if (context == null) { 5808 return AppOpsManager.MODE_DEFAULT; 5809 } 5810 5811 // system alert window is disable on low ram phones starting from Q 5812 final PackageManager pm = context.getPackageManager(); 5813 // TVs are constantly plugged in and has less concern for memory/power 5814 if (ActivityManager.isLowRamDeviceStatic() 5815 && !pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK, 0)) { 5816 return AppOpsManager.MODE_IGNORED; 5817 } 5818 5819 return AppOpsManager.MODE_DEFAULT; 5820 } 5821 } 5822