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