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 static java.lang.Long.max; 20 21 import android.Manifest; 22 import android.annotation.CallbackExecutor; 23 import android.annotation.IntDef; 24 import android.annotation.IntRange; 25 import android.annotation.NonNull; 26 import android.annotation.Nullable; 27 import android.annotation.RequiresPermission; 28 import android.annotation.SystemApi; 29 import android.annotation.SystemService; 30 import android.annotation.TestApi; 31 import android.app.usage.UsageStatsManager; 32 import android.compat.Compatibility; 33 import android.compat.annotation.ChangeId; 34 import android.compat.annotation.EnabledAfter; 35 import android.compat.annotation.UnsupportedAppUsage; 36 import android.content.AttributionSource; 37 import android.content.ComponentName; 38 import android.content.ContentResolver; 39 import android.content.Context; 40 import android.content.pm.ApplicationInfo; 41 import android.content.pm.PackageManager; 42 import android.content.pm.ParceledListSlice; 43 import android.database.DatabaseUtils; 44 import android.media.AudioAttributes.AttributeUsage; 45 import android.os.Binder; 46 import android.os.Build; 47 import android.os.Handler; 48 import android.os.HandlerExecutor; 49 import android.os.HandlerThread; 50 import android.os.IBinder; 51 import android.os.Looper; 52 import android.os.PackageTagsList; 53 import android.os.Parcel; 54 import android.os.Parcelable; 55 import android.os.Process; 56 import android.os.RemoteCallback; 57 import android.os.RemoteException; 58 import android.os.ServiceManager; 59 import android.os.SystemClock; 60 import android.os.UserManager; 61 import android.provider.DeviceConfig; 62 import android.util.ArrayMap; 63 import android.util.ArraySet; 64 import android.util.LongSparseArray; 65 import android.util.LongSparseLongArray; 66 import android.util.Pools; 67 import android.util.SparseArray; 68 69 import com.android.internal.annotations.GuardedBy; 70 import com.android.internal.annotations.Immutable; 71 import com.android.internal.app.IAppOpsActiveCallback; 72 import com.android.internal.app.IAppOpsAsyncNotedCallback; 73 import com.android.internal.app.IAppOpsCallback; 74 import com.android.internal.app.IAppOpsNotedCallback; 75 import com.android.internal.app.IAppOpsService; 76 import com.android.internal.app.IAppOpsStartedCallback; 77 import com.android.internal.app.MessageSamplingConfig; 78 import com.android.internal.os.RuntimeInit; 79 import com.android.internal.os.ZygoteInit; 80 import com.android.internal.util.ArrayUtils; 81 import com.android.internal.util.DataClass; 82 import com.android.internal.util.FrameworkStatsLog; 83 import com.android.internal.util.Parcelling; 84 import com.android.internal.util.Preconditions; 85 86 import java.lang.annotation.ElementType; 87 import java.lang.annotation.Retention; 88 import java.lang.annotation.RetentionPolicy; 89 import java.lang.annotation.Target; 90 import java.lang.reflect.Method; 91 import java.util.ArrayList; 92 import java.util.Arrays; 93 import java.util.BitSet; 94 import java.util.Collection; 95 import java.util.Collections; 96 import java.util.HashMap; 97 import java.util.List; 98 import java.util.Map; 99 import java.util.Objects; 100 import java.util.concurrent.Executor; 101 import java.util.function.Consumer; 102 import java.util.function.Supplier; 103 104 /** 105 * App-ops are used for two purposes: Access control and tracking. 106 * 107 * <p>App-ops cover a wide variety of functionality from helping with runtime permissions access 108 * control and tracking to battery consumption tracking. 109 * 110 * <h2>Access control</h2> 111 * 112 * <p>App-ops can either be controlled for each uid or for each package. Which one is used depends 113 * on the API provider maintaining this app-op. For any security or privacy related app-op the 114 * provider needs to control the app-op for per uid as all security and privacy is based on uid in 115 * Android. 116 * 117 * <p>To control access the app-op can be set to a mode to: 118 * <dl> 119 * <dt>{@link #MODE_DEFAULT} 120 * <dd>Default behavior, might differ from app-op or app-op 121 * <dt>{@link #MODE_ALLOWED} 122 * <dd>Allow the access 123 * <dt>{@link #MODE_IGNORED} 124 * <dd>Don't allow the access, i.e. don't perform the requested action or return no or 125 * placeholder data 126 * <dt>{@link #MODE_ERRORED} 127 * <dd>Throw a {@link SecurityException} on access. This can be suppressed by using a 128 * {@code ...noThrow} method to check the mode 129 * </dl> 130 * 131 * <p>API providers need to check the mode returned by {@link #noteOp} if they are are allowing 132 * access to operations gated by the app-op. {@link #unsafeCheckOp} should be used to check the 133 * mode if no access is granted. E.g. this can be used for displaying app-op state in the UI or 134 * when checking the state before later calling {@link #noteOp} anyway. 135 * 136 * <p>If an operation refers to a time span (e.g. a audio-recording session) the API provider 137 * should use {@link #startOp} and {@link #finishOp} instead of {@link #noteOp}. 138 * 139 * <h3>Runtime permissions and app-ops</h3> 140 * 141 * <p>Each platform defined runtime permission (beside background modifiers) has an associated app 142 * op which is used for tracking but also to allow for silent failures. I.e. if the runtime 143 * permission is denied the caller gets a {@link SecurityException}, but if the permission is 144 * granted and the app-op is {@link #MODE_IGNORED} then the callers gets placeholder behavior, e.g. 145 * location callbacks would not happen. 146 * 147 * <h3>App-op permissions</h3> 148 * 149 * <p>App-ops permissions are platform defined permissions that can be overridden. The security 150 * check for app-op permissions should by {@link #MODE_DEFAULT default} check the permission grant 151 * state. If the app-op state is set to {@link #MODE_ALLOWED} or {@link #MODE_IGNORED} the app-op 152 * state should be checked instead of the permission grant state. 153 * 154 * <p>This functionality allows to grant access by default to apps fulfilling the requirements for 155 * a certain permission level. Still the behavior can be overridden when needed. 156 * 157 * <h2>Tracking</h2> 158 * 159 * <p>App-ops track many important events, including all accesses to runtime permission protected 160 * APIs. This is done by tracking when an app-op was {@link #noteOp noted} or 161 * {@link #startOp started}. The tracked data can only be read by system components. 162 * 163 * <p><b>Only {@link #noteOp}/{@link #startOp} are tracked; {@link #unsafeCheckOp} is not tracked. 164 * Hence it is important to eventually call {@link #noteOp} or {@link #startOp} when providing 165 * access to protected operations or data.</b> 166 * 167 * <p>Some apps are forwarding access to other apps. E.g. an app might get the location from the 168 * system's location provider and then send the location further to a 3rd app. In this case the 169 * app passing on the data needs to call {@link #noteProxyOp} to signal the access proxying. This 170 * might also make sense inside of a single app if the access is forwarded between two parts of 171 * the tagged with different attribution tags. 172 * 173 * <p>An app can register an {@link OnOpNotedCallback} to get informed about what accesses the 174 * system is tracking for it. As each runtime permission has an associated app-op this API is 175 * particularly useful for an app that want to find unexpected private data accesses. 176 */ 177 @SystemService(Context.APP_OPS_SERVICE) 178 public class AppOpsManager { 179 /** 180 * This is a subtle behavior change to {@link #startWatchingMode}. 181 * 182 * Before this change the system called back for the switched op. After the change the system 183 * will call back for the actually requested op or all switched ops if no op is specified. 184 * 185 * @hide 186 */ 187 @ChangeId 188 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q) 189 public static final long CALL_BACK_ON_CHANGED_LISTENER_WITH_SWITCHED_OP_CHANGE = 148180766L; 190 191 /** 192 * Enforce that all attributionTags send to {@link #noteOp}, {@link #noteProxyOp}, 193 * and {@link #startOp} are defined in the manifest of the package that is specified as 194 * parameter to the methods. 195 * 196 * <p>To enable this change both the package calling {@link #noteOp} as well as the package 197 * specified as parameter to the method need to have this change enable. 198 * 199 * @hide 200 */ 201 @TestApi 202 @ChangeId 203 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R) 204 public static final long SECURITY_EXCEPTION_ON_INVALID_ATTRIBUTION_TAG_CHANGE = 151105954L; 205 206 private static final String FULL_LOG = "privacy_attribution_tag_full_log_enabled"; 207 208 private static final int MAX_UNFORWARDED_OPS = 10; 209 210 private static Boolean sFullLog = null; 211 212 final Context mContext; 213 214 @UnsupportedAppUsage 215 final IAppOpsService mService; 216 217 /** 218 * Service for the application context, to be used by static methods via 219 * {@link #getService()} 220 */ 221 @GuardedBy("sLock") 222 static IAppOpsService sService; 223 224 @GuardedBy("mModeWatchers") 225 private final ArrayMap<OnOpChangedListener, IAppOpsCallback> mModeWatchers = 226 new ArrayMap<>(); 227 228 @GuardedBy("mActiveWatchers") 229 private final ArrayMap<OnOpActiveChangedListener, IAppOpsActiveCallback> mActiveWatchers = 230 new ArrayMap<>(); 231 232 @GuardedBy("mStartedWatchers") 233 private final ArrayMap<OnOpStartedListener, IAppOpsStartedCallback> mStartedWatchers = 234 new ArrayMap<>(); 235 236 @GuardedBy("mNotedWatchers") 237 private final ArrayMap<OnOpNotedListener, IAppOpsNotedCallback> mNotedWatchers = 238 new ArrayMap<>(); 239 240 private static final Object sLock = new Object(); 241 242 /** Current {@link OnOpNotedCallback}. Change via {@link #setOnOpNotedCallback} */ 243 @GuardedBy("sLock") 244 private static @Nullable OnOpNotedCallback sOnOpNotedCallback; 245 246 /** 247 * Sync note-ops collected from {@link #readAndLogNotedAppops(Parcel)} that have not been 248 * delivered to a callback yet. 249 * 250 * Similar to {@link com.android.server.appop.AppOpsService#mUnforwardedAsyncNotedOps} for 251 * {@link COLLECT_ASYNC}. Used in situation when AppOpsManager asks to collect stacktrace with 252 * {@link #sMessageCollector}, which forces {@link COLLECT_SYNC} mode. 253 */ 254 @GuardedBy("sLock") 255 private static ArrayList<AsyncNotedAppOp> sUnforwardedOps = new ArrayList<>(); 256 257 /** 258 * Additional collector that collect accesses and forwards a few of them them via 259 * {@link IAppOpsService#reportRuntimeAppOpAccessMessageAndGetConfig}. 260 */ 261 private static OnOpNotedCallback sMessageCollector = 262 new OnOpNotedCallback() { 263 @Override 264 public void onNoted(@NonNull SyncNotedAppOp op) { 265 reportStackTraceIfNeeded(op); 266 } 267 268 @Override 269 public void onAsyncNoted(@NonNull AsyncNotedAppOp asyncOp) { 270 // collected directly in AppOpsService 271 } 272 273 @Override 274 public void onSelfNoted(@NonNull SyncNotedAppOp op) { 275 reportStackTraceIfNeeded(op); 276 } 277 278 private void reportStackTraceIfNeeded(@NonNull SyncNotedAppOp op) { 279 if (!isCollectingStackTraces()) { 280 return; 281 } 282 MessageSamplingConfig config = sConfig; 283 if (leftCircularDistance(strOpToOp(op.getOp()), config.getSampledOpCode(), 284 _NUM_OP) <= config.getAcceptableLeftDistance() 285 || config.getExpirationTimeSinceBootMillis() 286 < SystemClock.elapsedRealtime()) { 287 String stackTrace = getFormattedStackTrace(); 288 try { 289 String packageName = ActivityThread.currentOpPackageName(); 290 sConfig = getService().reportRuntimeAppOpAccessMessageAndGetConfig( 291 packageName == null ? "" : packageName, op, stackTrace); 292 } catch (RemoteException e) { 293 e.rethrowFromSystemServer(); 294 } 295 } 296 } 297 }; 298 299 static IBinder sClientId; 300 301 /** 302 * How many seconds we want for a drop in uid state from top to settle before applying it. 303 * 304 * <>Set a parameter to {@link android.provider.Settings.Global#APP_OPS_CONSTANTS} 305 * 306 * @hide 307 */ 308 @TestApi 309 public static final String KEY_TOP_STATE_SETTLE_TIME = "top_state_settle_time"; 310 311 /** 312 * How many second we want for a drop in uid state from foreground to settle before applying it. 313 * 314 * <>Set a parameter to {@link android.provider.Settings.Global#APP_OPS_CONSTANTS} 315 * 316 * @hide 317 */ 318 @TestApi 319 public static final String KEY_FG_SERVICE_STATE_SETTLE_TIME = 320 "fg_service_state_settle_time"; 321 322 /** 323 * How many seconds we want for a drop in uid state from background to settle before applying 324 * it. 325 * 326 * <>Set a parameter to {@link android.provider.Settings.Global#APP_OPS_CONSTANTS} 327 * 328 * @hide 329 */ 330 @TestApi 331 public static final String KEY_BG_STATE_SETTLE_TIME = "bg_state_settle_time"; 332 333 /** @hide */ 334 @Retention(RetentionPolicy.SOURCE) 335 @IntDef(flag = true, prefix = { "HISTORICAL_MODE_" }, value = { 336 HISTORICAL_MODE_DISABLED, 337 HISTORICAL_MODE_ENABLED_ACTIVE, 338 HISTORICAL_MODE_ENABLED_PASSIVE 339 }) 340 public @interface HistoricalMode {} 341 342 /** 343 * Mode in which app op history is completely disabled. 344 * @hide 345 */ 346 @TestApi 347 public static final int HISTORICAL_MODE_DISABLED = 0; 348 349 /** 350 * Mode in which app op history is enabled and app ops performed by apps would 351 * be tracked. This is the mode in which the feature is completely enabled. 352 * @hide 353 */ 354 @TestApi 355 public static final int HISTORICAL_MODE_ENABLED_ACTIVE = 1; 356 357 /** 358 * Mode in which app op history is enabled but app ops performed by apps would 359 * not be tracked and the only way to add ops to the history is via explicit calls 360 * to dedicated APIs. This mode is useful for testing to allow full control of 361 * the historical content. 362 * @hide 363 */ 364 @TestApi 365 public static final int HISTORICAL_MODE_ENABLED_PASSIVE = 2; 366 367 /** @hide */ 368 @Retention(RetentionPolicy.SOURCE) 369 @IntDef(prefix = { "MODE_" }, value = { 370 MODE_ALLOWED, 371 MODE_IGNORED, 372 MODE_ERRORED, 373 MODE_DEFAULT, 374 MODE_FOREGROUND 375 }) 376 public @interface Mode {} 377 378 /** 379 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is 380 * allowed to perform the given operation. 381 */ 382 public static final int MODE_ALLOWED = 0; 383 384 /** 385 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is 386 * not allowed to perform the given operation, and this attempt should 387 * <em>silently fail</em> (it should not cause the app to crash). 388 */ 389 public static final int MODE_IGNORED = 1; 390 391 /** 392 * Result from {@link #checkOpNoThrow}, {@link #noteOpNoThrow}, {@link #startOpNoThrow}: the 393 * given caller is not allowed to perform the given operation, and this attempt should 394 * cause it to have a fatal error, typically a {@link SecurityException}. 395 */ 396 public static final int MODE_ERRORED = 2; 397 398 /** 399 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller should 400 * use its default security check. This mode is not normally used; it should only be used 401 * with appop permissions, and callers must explicitly check for it and deal with it. 402 */ 403 public static final int MODE_DEFAULT = 3; 404 405 /** 406 * Special mode that means "allow only when app is in foreground." This is <b>not</b> 407 * returned from {@link #unsafeCheckOp}, {@link #noteOp}, {@link #startOp}. Rather, 408 * {@link #unsafeCheckOp} will always return {@link #MODE_ALLOWED} (because it is always 409 * possible for it to be ultimately allowed, depending on the app's background state), 410 * and {@link #noteOp} and {@link #startOp} will return {@link #MODE_ALLOWED} when the app 411 * being checked is currently in the foreground, otherwise {@link #MODE_IGNORED}. 412 * 413 * <p>The only place you will this normally see this value is through 414 * {@link #unsafeCheckOpRaw}, which returns the actual raw mode of the op. Note that because 415 * you can't know the current state of the app being checked (and it can change at any 416 * point), you can only treat the result here as an indication that it will vary between 417 * {@link #MODE_ALLOWED} and {@link #MODE_IGNORED} depending on changes in the background 418 * state of the app. You thus must always use {@link #noteOp} or {@link #startOp} to do 419 * the actual check for access to the op.</p> 420 */ 421 public static final int MODE_FOREGROUND = 4; 422 423 /** 424 * Flag for {@link #startWatchingMode(String, String, int, OnOpChangedListener)}: 425 * Also get reports if the foreground state of an op's uid changes. This only works 426 * when watching a particular op, not when watching a package. 427 */ 428 public static final int WATCH_FOREGROUND_CHANGES = 1 << 0; 429 430 /** 431 * Flag for {@link #startWatchingMode} that causes the callback to happen on the switch-op 432 * instead the op the callback was registered. (This simulates pre-R behavior). 433 * 434 * @hide 435 */ 436 public static final int CALL_BACK_ON_SWITCHED_OP = 1 << 1; 437 438 /** 439 * Flag to determine whether we should log noteOp/startOp calls to make sure they 440 * are correctly used 441 * 442 * @hide 443 */ 444 public static final boolean NOTE_OP_COLLECTION_ENABLED = false; 445 446 /** 447 * @hide 448 */ 449 public static final String[] MODE_NAMES = new String[] { 450 "allow", // MODE_ALLOWED 451 "ignore", // MODE_IGNORED 452 "deny", // MODE_ERRORED 453 "default", // MODE_DEFAULT 454 "foreground", // MODE_FOREGROUND 455 }; 456 457 /** @hide */ 458 @Retention(RetentionPolicy.SOURCE) 459 @IntDef(prefix = { "UID_STATE_" }, value = { 460 UID_STATE_PERSISTENT, 461 UID_STATE_TOP, 462 UID_STATE_FOREGROUND_SERVICE_LOCATION, 463 UID_STATE_FOREGROUND_SERVICE, 464 UID_STATE_FOREGROUND, 465 UID_STATE_BACKGROUND, 466 UID_STATE_CACHED 467 }) 468 public @interface UidState {} 469 470 /** 471 * Uid state: The UID is a foreground persistent app. The lower the UID 472 * state the more important the UID is for the user. 473 * @hide 474 */ 475 @SystemApi 476 public static final int UID_STATE_PERSISTENT = 100; 477 478 /** 479 * Uid state: The UID is top foreground app. The lower the UID 480 * state the more important the UID is for the user. 481 * @hide 482 */ 483 @SystemApi 484 public static final int UID_STATE_TOP = 200; 485 486 /** 487 * Uid state: The UID is running a foreground service of location type. 488 * The lower the UID state the more important the UID is for the user. 489 * This uid state is a counterpart to PROCESS_STATE_FOREGROUND_SERVICE_LOCATION which has been 490 * deprecated. 491 * @hide 492 * @deprecated 493 */ 494 @SystemApi 495 @Deprecated 496 public static final int UID_STATE_FOREGROUND_SERVICE_LOCATION = 300; 497 498 /** 499 * Uid state: The UID is running a foreground service. The lower the UID 500 * state the more important the UID is for the user. 501 * @hide 502 */ 503 @SystemApi 504 public static final int UID_STATE_FOREGROUND_SERVICE = 400; 505 506 /** 507 * Uid state: The UID is a foreground app. The lower the UID 508 * state the more important the UID is for the user. 509 * @hide 510 */ 511 @SystemApi 512 public static final int UID_STATE_FOREGROUND = 500; 513 514 /** 515 * The max, which is min priority, UID state for which any app op 516 * would be considered as performed in the foreground. 517 * @hide 518 */ 519 public static final int UID_STATE_MAX_LAST_NON_RESTRICTED = UID_STATE_FOREGROUND; 520 521 /** 522 * Uid state: The UID is a background app. The lower the UID 523 * state the more important the UID is for the user. 524 * @hide 525 */ 526 @SystemApi 527 public static final int UID_STATE_BACKGROUND = 600; 528 529 /** 530 * Uid state: The UID is a cached app. The lower the UID 531 * state the more important the UID is for the user. 532 * @hide 533 */ 534 @SystemApi 535 public static final int UID_STATE_CACHED = 700; 536 537 /** 538 * Uid state: The UID state with the highest priority. 539 * @hide 540 */ 541 public static final int MAX_PRIORITY_UID_STATE = UID_STATE_PERSISTENT; 542 543 /** 544 * Uid state: The UID state with the lowest priority. 545 * @hide 546 */ 547 public static final int MIN_PRIORITY_UID_STATE = UID_STATE_CACHED; 548 549 /** 550 * Resolves the first unrestricted state given an app op. 551 * @param op The op to resolve. 552 * @return The last restricted UID state. 553 * 554 * @hide 555 */ resolveFirstUnrestrictedUidState(int op)556 public static int resolveFirstUnrestrictedUidState(int op) { 557 return UID_STATE_FOREGROUND; 558 } 559 560 /** 561 * Resolves the last restricted state given an app op. 562 * @param op The op to resolve. 563 * @return The last restricted UID state. 564 * 565 * @hide 566 */ resolveLastRestrictedUidState(int op)567 public static int resolveLastRestrictedUidState(int op) { 568 return UID_STATE_BACKGROUND; 569 } 570 571 /** @hide Note: Keep these sorted */ 572 public static final int[] UID_STATES = { 573 UID_STATE_PERSISTENT, 574 UID_STATE_TOP, 575 UID_STATE_FOREGROUND_SERVICE_LOCATION, 576 UID_STATE_FOREGROUND_SERVICE, 577 UID_STATE_FOREGROUND, 578 UID_STATE_BACKGROUND, 579 UID_STATE_CACHED 580 }; 581 582 /** @hide */ getUidStateName(@idState int uidState)583 public static String getUidStateName(@UidState int uidState) { 584 switch (uidState) { 585 case UID_STATE_PERSISTENT: 586 return "pers"; 587 case UID_STATE_TOP: 588 return "top"; 589 case UID_STATE_FOREGROUND_SERVICE_LOCATION: 590 return "fgsvcl"; 591 case UID_STATE_FOREGROUND_SERVICE: 592 return "fgsvc"; 593 case UID_STATE_FOREGROUND: 594 return "fg"; 595 case UID_STATE_BACKGROUND: 596 return "bg"; 597 case UID_STATE_CACHED: 598 return "cch"; 599 default: 600 return "unknown"; 601 } 602 } 603 604 /** 605 * Flag: non proxy operations. These are operations 606 * performed on behalf of the app itself and not on behalf of 607 * another one. 608 * 609 * @hide 610 */ 611 @SystemApi 612 public static final int OP_FLAG_SELF = 0x1; 613 614 /** 615 * Flag: trusted proxy operations. These are operations 616 * performed on behalf of another app by a trusted app. 617 * Which is work a trusted app blames on another app. 618 * 619 * @hide 620 */ 621 @SystemApi 622 public static final int OP_FLAG_TRUSTED_PROXY = 0x2; 623 624 /** 625 * Flag: untrusted proxy operations. These are operations 626 * performed on behalf of another app by an untrusted app. 627 * Which is work an untrusted app blames on another app. 628 * 629 * @hide 630 */ 631 @SystemApi 632 public static final int OP_FLAG_UNTRUSTED_PROXY = 0x4; 633 634 /** 635 * Flag: trusted proxied operations. These are operations 636 * performed by a trusted other app on behalf of an app. 637 * Which is work an app was blamed for by a trusted app. 638 * 639 * @hide 640 */ 641 @SystemApi 642 public static final int OP_FLAG_TRUSTED_PROXIED = 0x8; 643 644 /** 645 * Flag: untrusted proxied operations. These are operations 646 * performed by an untrusted other app on behalf of an app. 647 * Which is work an app was blamed for by an untrusted app. 648 * 649 * @hide 650 */ 651 @SystemApi 652 public static final int OP_FLAG_UNTRUSTED_PROXIED = 0x10; 653 654 /** 655 * Flags: all operations. These include operations matched 656 * by {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXIED}, 657 * {@link #OP_FLAG_UNTRUSTED_PROXIED}, {@link #OP_FLAG_TRUSTED_PROXIED}, 658 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. 659 * 660 * @hide 661 */ 662 @SystemApi 663 public static final int OP_FLAGS_ALL = 664 OP_FLAG_SELF 665 | OP_FLAG_TRUSTED_PROXY 666 | OP_FLAG_UNTRUSTED_PROXY 667 | OP_FLAG_TRUSTED_PROXIED 668 | OP_FLAG_UNTRUSTED_PROXIED; 669 670 /** 671 * Flags: all trusted operations which is ones either the app did {@link #OP_FLAG_SELF}, 672 * or it was blamed for by a trusted app {@link #OP_FLAG_TRUSTED_PROXIED}, or ones the 673 * app if untrusted blamed on other apps {@link #OP_FLAG_UNTRUSTED_PROXY}. 674 * 675 * @hide 676 */ 677 @SystemApi 678 public static final int OP_FLAGS_ALL_TRUSTED = AppOpsManager.OP_FLAG_SELF 679 | AppOpsManager.OP_FLAG_UNTRUSTED_PROXY 680 | AppOpsManager.OP_FLAG_TRUSTED_PROXIED; 681 682 /** @hide */ 683 @Retention(RetentionPolicy.SOURCE) 684 @IntDef(flag = true, prefix = { "FLAG_" }, value = { 685 OP_FLAG_SELF, 686 OP_FLAG_TRUSTED_PROXY, 687 OP_FLAG_UNTRUSTED_PROXY, 688 OP_FLAG_TRUSTED_PROXIED, 689 OP_FLAG_UNTRUSTED_PROXIED 690 }) 691 public @interface OpFlags {} 692 693 /** @hide */ getFlagName(@pFlags int flag)694 public static final String getFlagName(@OpFlags int flag) { 695 switch (flag) { 696 case OP_FLAG_SELF: 697 return "s"; 698 case OP_FLAG_TRUSTED_PROXY: 699 return "tp"; 700 case OP_FLAG_UNTRUSTED_PROXY: 701 return "up"; 702 case OP_FLAG_TRUSTED_PROXIED: 703 return "tpd"; 704 case OP_FLAG_UNTRUSTED_PROXIED: 705 return "upd"; 706 default: 707 return "unknown"; 708 } 709 } 710 711 /** 712 * Attribution chain flag: specifies that this is the accessor. When 713 * an app A accesses the data that is then passed to app B that is then 714 * passed to C, we call app A accessor, app B intermediary, and app C 715 * receiver. If A accesses the data for itself, then it is the accessor 716 * and the receiver. 717 * @hide 718 */ 719 @TestApi 720 public static final int ATTRIBUTION_FLAG_ACCESSOR = 0x1; 721 722 /** 723 * Attribution chain flag: specifies that this is the intermediary. When 724 * an app A accesses the data that is then passed to app B that is then 725 * passed to C, we call app A accessor, app B intermediary, and app C 726 * receiver. If A accesses the data for itself, then it is the accessor 727 * and the receiver. 728 * @hide 729 */ 730 @TestApi 731 public static final int ATTRIBUTION_FLAG_INTERMEDIARY = 0x2; 732 733 /** 734 * Attribution chain flag: specifies that this is the receiver. When 735 * an app A accesses the data that is then passed to app B that is then 736 * passed to C, we call app A accessor, app B intermediary, and app C 737 * receiver. If A accesses the data for itself, then it is the accessor 738 * and the receiver. 739 * @hide 740 */ 741 @TestApi 742 public static final int ATTRIBUTION_FLAG_RECEIVER = 0x4; 743 744 /** 745 * Attribution chain flag: Specifies that all attribution sources in the chain were trusted. 746 * Must only be set by system server. 747 * @hide 748 */ 749 public static final int ATTRIBUTION_FLAG_TRUSTED = 0x8; 750 751 /** 752 * No attribution flags. 753 * @hide 754 */ 755 @TestApi 756 public static final int ATTRIBUTION_FLAGS_NONE = 0x0; 757 758 /** 759 * No attribution chain id. 760 * @hide 761 */ 762 @TestApi 763 public static final int ATTRIBUTION_CHAIN_ID_NONE = -1; 764 765 /** @hide */ 766 @Retention(RetentionPolicy.SOURCE) 767 @IntDef(flag = true, prefix = { "FLAG_" }, value = { 768 ATTRIBUTION_FLAG_ACCESSOR, 769 ATTRIBUTION_FLAG_INTERMEDIARY, 770 ATTRIBUTION_FLAG_RECEIVER, 771 ATTRIBUTION_FLAG_TRUSTED 772 }) 773 public @interface AttributionFlags {} 774 775 // These constants are redefined here to work around a metalava limitation/bug where 776 // @IntDef is not able to see @hide symbols when they are hidden via package hiding: 777 // frameworks/base/core/java/com/android/internal/package.html 778 779 /** @hide */ 780 public static final int SAMPLING_STRATEGY_DEFAULT = 781 FrameworkStatsLog.RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__DEFAULT; 782 783 /** @hide */ 784 public static final int SAMPLING_STRATEGY_UNIFORM = 785 FrameworkStatsLog.RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__UNIFORM; 786 787 /** @hide */ 788 public static final int SAMPLING_STRATEGY_RARELY_USED = 789 FrameworkStatsLog.RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__RARELY_USED; 790 791 /** @hide */ 792 public static final int SAMPLING_STRATEGY_BOOT_TIME_SAMPLING = 793 FrameworkStatsLog.RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__BOOT_TIME_SAMPLING; 794 795 /** @hide */ 796 public static final int SAMPLING_STRATEGY_UNIFORM_OPS = 797 FrameworkStatsLog.RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__UNIFORM_OPS; 798 799 /** 800 * Strategies used for message sampling 801 * @hide 802 */ 803 @Retention(RetentionPolicy.SOURCE) 804 @IntDef(prefix = {"SAMPLING_STRATEGY_"}, value = { 805 SAMPLING_STRATEGY_DEFAULT, 806 SAMPLING_STRATEGY_UNIFORM, 807 SAMPLING_STRATEGY_RARELY_USED, 808 SAMPLING_STRATEGY_BOOT_TIME_SAMPLING, 809 SAMPLING_STRATEGY_UNIFORM_OPS 810 }) 811 public @interface SamplingStrategy {} 812 813 private static final int UID_STATE_OFFSET = 31; 814 private static final int FLAGS_MASK = 0xFFFFFFFF; 815 816 /** 817 * Key for a data bucket storing app op state. The bucket 818 * is composed of the uid state and state flags. This way 819 * we can query data for given uid state and a set of flags where 820 * the flags control which type of data to get. For example, 821 * one can get the ops an app did on behalf of other apps 822 * while in the background. 823 * 824 * @hide 825 */ 826 @Retention(RetentionPolicy.SOURCE) 827 @Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD}) 828 public @interface DataBucketKey { 829 } 830 831 /** @hide */ keyToString(@ataBucketKey long key)832 public static String keyToString(@DataBucketKey long key) { 833 final int uidState = extractUidStateFromKey(key); 834 final int flags = extractFlagsFromKey(key); 835 return "[" + getUidStateName(uidState) + "-" + flagsToString(flags) + "]"; 836 } 837 838 /** @hide */ makeKey(@idState int uidState, @OpFlags int flags)839 public static @DataBucketKey long makeKey(@UidState int uidState, @OpFlags int flags) { 840 return ((long) uidState << UID_STATE_OFFSET) | flags; 841 } 842 843 /** @hide */ extractUidStateFromKey(@ataBucketKey long key)844 public static int extractUidStateFromKey(@DataBucketKey long key) { 845 return (int) (key >> UID_STATE_OFFSET); 846 } 847 848 /** @hide */ extractFlagsFromKey(@ataBucketKey long key)849 public static int extractFlagsFromKey(@DataBucketKey long key) { 850 return (int) (key & FLAGS_MASK); 851 } 852 853 /** @hide */ flagsToString(@pFlags int flags)854 public static String flagsToString(@OpFlags int flags) { 855 final StringBuilder flagsBuilder = new StringBuilder(); 856 while (flags != 0) { 857 final int flag = 1 << Integer.numberOfTrailingZeros(flags); 858 flags &= ~flag; 859 if (flagsBuilder.length() > 0) { 860 flagsBuilder.append('|'); 861 } 862 flagsBuilder.append(getFlagName(flag)); 863 } 864 return flagsBuilder.toString(); 865 } 866 867 // when adding one of these: 868 // - increment _NUM_OP 869 // - define an OPSTR_* constant (marked as @SystemApi) 870 // - add rows to sOpToSwitch, sOpToString, sOpNames, sOpPerms, sOpDefaultMode, sOpDisableReset, 871 // sOpRestrictions, sOpAllowSystemRestrictionBypass 872 // - add descriptive strings to Settings/res/values/arrays.xml 873 // - add the op to the appropriate template in AppOpsState.OpsTemplate (settings app) 874 875 /** @hide No operation specified. */ 876 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 877 public static final int OP_NONE = AppProtoEnums.APP_OP_NONE; 878 /** @hide Access to coarse location information. */ 879 @UnsupportedAppUsage 880 @TestApi 881 public static final int OP_COARSE_LOCATION = AppProtoEnums.APP_OP_COARSE_LOCATION; 882 /** @hide Access to fine location information. */ 883 @UnsupportedAppUsage 884 public static final int OP_FINE_LOCATION = AppProtoEnums.APP_OP_FINE_LOCATION; 885 /** @hide Causing GPS to run. */ 886 @UnsupportedAppUsage 887 public static final int OP_GPS = AppProtoEnums.APP_OP_GPS; 888 /** @hide */ 889 @UnsupportedAppUsage 890 public static final int OP_VIBRATE = AppProtoEnums.APP_OP_VIBRATE; 891 /** @hide */ 892 @UnsupportedAppUsage 893 public static final int OP_READ_CONTACTS = AppProtoEnums.APP_OP_READ_CONTACTS; 894 /** @hide */ 895 @UnsupportedAppUsage 896 public static final int OP_WRITE_CONTACTS = AppProtoEnums.APP_OP_WRITE_CONTACTS; 897 /** @hide */ 898 @UnsupportedAppUsage 899 public static final int OP_READ_CALL_LOG = AppProtoEnums.APP_OP_READ_CALL_LOG; 900 /** @hide */ 901 @UnsupportedAppUsage 902 public static final int OP_WRITE_CALL_LOG = AppProtoEnums.APP_OP_WRITE_CALL_LOG; 903 /** @hide */ 904 @UnsupportedAppUsage 905 public static final int OP_READ_CALENDAR = AppProtoEnums.APP_OP_READ_CALENDAR; 906 /** @hide */ 907 @UnsupportedAppUsage 908 public static final int OP_WRITE_CALENDAR = AppProtoEnums.APP_OP_WRITE_CALENDAR; 909 /** @hide */ 910 @UnsupportedAppUsage 911 public static final int OP_WIFI_SCAN = AppProtoEnums.APP_OP_WIFI_SCAN; 912 /** @hide */ 913 @UnsupportedAppUsage 914 public static final int OP_POST_NOTIFICATION = AppProtoEnums.APP_OP_POST_NOTIFICATION; 915 /** @hide */ 916 @UnsupportedAppUsage 917 public static final int OP_NEIGHBORING_CELLS = AppProtoEnums.APP_OP_NEIGHBORING_CELLS; 918 /** @hide */ 919 @UnsupportedAppUsage 920 public static final int OP_CALL_PHONE = AppProtoEnums.APP_OP_CALL_PHONE; 921 /** @hide */ 922 @UnsupportedAppUsage 923 public static final int OP_READ_SMS = AppProtoEnums.APP_OP_READ_SMS; 924 /** @hide */ 925 @UnsupportedAppUsage 926 public static final int OP_WRITE_SMS = AppProtoEnums.APP_OP_WRITE_SMS; 927 /** @hide */ 928 @UnsupportedAppUsage 929 public static final int OP_RECEIVE_SMS = AppProtoEnums.APP_OP_RECEIVE_SMS; 930 /** @hide */ 931 @UnsupportedAppUsage 932 public static final int OP_RECEIVE_EMERGECY_SMS = 933 AppProtoEnums.APP_OP_RECEIVE_EMERGENCY_SMS; 934 /** @hide */ 935 @UnsupportedAppUsage 936 public static final int OP_RECEIVE_MMS = AppProtoEnums.APP_OP_RECEIVE_MMS; 937 /** @hide */ 938 @UnsupportedAppUsage 939 public static final int OP_RECEIVE_WAP_PUSH = AppProtoEnums.APP_OP_RECEIVE_WAP_PUSH; 940 /** @hide */ 941 @UnsupportedAppUsage 942 public static final int OP_SEND_SMS = AppProtoEnums.APP_OP_SEND_SMS; 943 /** @hide */ 944 public static final int OP_MANAGE_ONGOING_CALLS = AppProtoEnums.APP_OP_MANAGE_ONGOING_CALLS; 945 /** @hide */ 946 @UnsupportedAppUsage 947 public static final int OP_READ_ICC_SMS = AppProtoEnums.APP_OP_READ_ICC_SMS; 948 /** @hide */ 949 @UnsupportedAppUsage 950 public static final int OP_WRITE_ICC_SMS = AppProtoEnums.APP_OP_WRITE_ICC_SMS; 951 /** @hide */ 952 @UnsupportedAppUsage 953 public static final int OP_WRITE_SETTINGS = AppProtoEnums.APP_OP_WRITE_SETTINGS; 954 /** @hide Required to draw on top of other apps. */ 955 @UnsupportedAppUsage 956 @TestApi 957 public static final int OP_SYSTEM_ALERT_WINDOW = AppProtoEnums.APP_OP_SYSTEM_ALERT_WINDOW; 958 /** @hide */ 959 @UnsupportedAppUsage 960 public static final int OP_ACCESS_NOTIFICATIONS = 961 AppProtoEnums.APP_OP_ACCESS_NOTIFICATIONS; 962 /** @hide */ 963 @UnsupportedAppUsage 964 public static final int OP_CAMERA = AppProtoEnums.APP_OP_CAMERA; 965 /** @hide */ 966 @UnsupportedAppUsage 967 @TestApi 968 public static final int OP_RECORD_AUDIO = AppProtoEnums.APP_OP_RECORD_AUDIO; 969 /** @hide */ 970 @UnsupportedAppUsage 971 public static final int OP_PLAY_AUDIO = AppProtoEnums.APP_OP_PLAY_AUDIO; 972 /** @hide */ 973 @UnsupportedAppUsage 974 public static final int OP_READ_CLIPBOARD = AppProtoEnums.APP_OP_READ_CLIPBOARD; 975 /** @hide */ 976 @UnsupportedAppUsage 977 public static final int OP_WRITE_CLIPBOARD = AppProtoEnums.APP_OP_WRITE_CLIPBOARD; 978 /** @hide */ 979 @UnsupportedAppUsage 980 public static final int OP_TAKE_MEDIA_BUTTONS = AppProtoEnums.APP_OP_TAKE_MEDIA_BUTTONS; 981 /** @hide */ 982 @UnsupportedAppUsage 983 public static final int OP_TAKE_AUDIO_FOCUS = AppProtoEnums.APP_OP_TAKE_AUDIO_FOCUS; 984 /** @hide */ 985 @UnsupportedAppUsage 986 public static final int OP_AUDIO_MASTER_VOLUME = AppProtoEnums.APP_OP_AUDIO_MASTER_VOLUME; 987 /** @hide */ 988 @UnsupportedAppUsage 989 public static final int OP_AUDIO_VOICE_VOLUME = AppProtoEnums.APP_OP_AUDIO_VOICE_VOLUME; 990 /** @hide */ 991 @UnsupportedAppUsage 992 public static final int OP_AUDIO_RING_VOLUME = AppProtoEnums.APP_OP_AUDIO_RING_VOLUME; 993 /** @hide */ 994 @UnsupportedAppUsage 995 public static final int OP_AUDIO_MEDIA_VOLUME = AppProtoEnums.APP_OP_AUDIO_MEDIA_VOLUME; 996 /** @hide */ 997 @UnsupportedAppUsage 998 public static final int OP_AUDIO_ALARM_VOLUME = AppProtoEnums.APP_OP_AUDIO_ALARM_VOLUME; 999 /** @hide */ 1000 @UnsupportedAppUsage 1001 public static final int OP_AUDIO_NOTIFICATION_VOLUME = 1002 AppProtoEnums.APP_OP_AUDIO_NOTIFICATION_VOLUME; 1003 /** @hide */ 1004 @UnsupportedAppUsage 1005 public static final int OP_AUDIO_BLUETOOTH_VOLUME = 1006 AppProtoEnums.APP_OP_AUDIO_BLUETOOTH_VOLUME; 1007 /** @hide */ 1008 @UnsupportedAppUsage 1009 public static final int OP_WAKE_LOCK = AppProtoEnums.APP_OP_WAKE_LOCK; 1010 /** @hide Continually monitoring location data. */ 1011 @UnsupportedAppUsage 1012 public static final int OP_MONITOR_LOCATION = 1013 AppProtoEnums.APP_OP_MONITOR_LOCATION; 1014 /** @hide Continually monitoring location data with a relatively high power request. */ 1015 @UnsupportedAppUsage 1016 public static final int OP_MONITOR_HIGH_POWER_LOCATION = 1017 AppProtoEnums.APP_OP_MONITOR_HIGH_POWER_LOCATION; 1018 /** @hide Retrieve current usage stats via {@link UsageStatsManager}. */ 1019 @UnsupportedAppUsage 1020 public static final int OP_GET_USAGE_STATS = AppProtoEnums.APP_OP_GET_USAGE_STATS; 1021 /** @hide */ 1022 @UnsupportedAppUsage 1023 public static final int OP_MUTE_MICROPHONE = AppProtoEnums.APP_OP_MUTE_MICROPHONE; 1024 /** @hide */ 1025 @UnsupportedAppUsage 1026 public static final int OP_TOAST_WINDOW = AppProtoEnums.APP_OP_TOAST_WINDOW; 1027 /** @hide Capture the device's display contents and/or audio */ 1028 @UnsupportedAppUsage 1029 public static final int OP_PROJECT_MEDIA = AppProtoEnums.APP_OP_PROJECT_MEDIA; 1030 /** 1031 * Start (without additional user intervention) a VPN connection, as used by {@link 1032 * android.net.VpnService} along with as Platform VPN connections, as used by {@link 1033 * android.net.VpnManager} 1034 * 1035 * <p>This appop is granted to apps that have already been given user consent to start 1036 * VpnService based VPN connections. As this is a superset of OP_ACTIVATE_PLATFORM_VPN, this 1037 * appop also allows the starting of Platform VPNs. 1038 * 1039 * @hide 1040 */ 1041 @UnsupportedAppUsage 1042 public static final int OP_ACTIVATE_VPN = AppProtoEnums.APP_OP_ACTIVATE_VPN; 1043 /** @hide Access the WallpaperManagerAPI to write wallpapers. */ 1044 @UnsupportedAppUsage 1045 public static final int OP_WRITE_WALLPAPER = AppProtoEnums.APP_OP_WRITE_WALLPAPER; 1046 /** @hide Received the assist structure from an app. */ 1047 @UnsupportedAppUsage 1048 public static final int OP_ASSIST_STRUCTURE = AppProtoEnums.APP_OP_ASSIST_STRUCTURE; 1049 /** @hide Received a screenshot from assist. */ 1050 @UnsupportedAppUsage 1051 public static final int OP_ASSIST_SCREENSHOT = AppProtoEnums.APP_OP_ASSIST_SCREENSHOT; 1052 /** @hide Read the phone state. */ 1053 @UnsupportedAppUsage 1054 public static final int OP_READ_PHONE_STATE = AppProtoEnums.APP_OP_READ_PHONE_STATE; 1055 /** @hide Add voicemail messages to the voicemail content provider. */ 1056 @UnsupportedAppUsage 1057 public static final int OP_ADD_VOICEMAIL = AppProtoEnums.APP_OP_ADD_VOICEMAIL; 1058 /** @hide Access APIs for SIP calling over VOIP or WiFi. */ 1059 @UnsupportedAppUsage 1060 public static final int OP_USE_SIP = AppProtoEnums.APP_OP_USE_SIP; 1061 /** @hide Intercept outgoing calls. */ 1062 @UnsupportedAppUsage 1063 public static final int OP_PROCESS_OUTGOING_CALLS = 1064 AppProtoEnums.APP_OP_PROCESS_OUTGOING_CALLS; 1065 /** @hide User the fingerprint API. */ 1066 @UnsupportedAppUsage 1067 public static final int OP_USE_FINGERPRINT = AppProtoEnums.APP_OP_USE_FINGERPRINT; 1068 /** @hide Access to body sensors such as heart rate, etc. */ 1069 @UnsupportedAppUsage 1070 public static final int OP_BODY_SENSORS = AppProtoEnums.APP_OP_BODY_SENSORS; 1071 /** @hide Read previously received cell broadcast messages. */ 1072 @UnsupportedAppUsage 1073 public static final int OP_READ_CELL_BROADCASTS = AppProtoEnums.APP_OP_READ_CELL_BROADCASTS; 1074 /** @hide Inject mock location into the system. */ 1075 @UnsupportedAppUsage 1076 public static final int OP_MOCK_LOCATION = AppProtoEnums.APP_OP_MOCK_LOCATION; 1077 /** @hide Read external storage. */ 1078 @UnsupportedAppUsage 1079 public static final int OP_READ_EXTERNAL_STORAGE = AppProtoEnums.APP_OP_READ_EXTERNAL_STORAGE; 1080 /** @hide Write external storage. */ 1081 @UnsupportedAppUsage 1082 public static final int OP_WRITE_EXTERNAL_STORAGE = 1083 AppProtoEnums.APP_OP_WRITE_EXTERNAL_STORAGE; 1084 /** @hide Turned on the screen. */ 1085 @UnsupportedAppUsage 1086 public static final int OP_TURN_SCREEN_ON = AppProtoEnums.APP_OP_TURN_SCREEN_ON; 1087 /** @hide Get device accounts. */ 1088 @UnsupportedAppUsage 1089 public static final int OP_GET_ACCOUNTS = AppProtoEnums.APP_OP_GET_ACCOUNTS; 1090 /** @hide Control whether an application is allowed to run in the background. */ 1091 @UnsupportedAppUsage 1092 public static final int OP_RUN_IN_BACKGROUND = 1093 AppProtoEnums.APP_OP_RUN_IN_BACKGROUND; 1094 /** @hide */ 1095 @UnsupportedAppUsage 1096 public static final int OP_AUDIO_ACCESSIBILITY_VOLUME = 1097 AppProtoEnums.APP_OP_AUDIO_ACCESSIBILITY_VOLUME; 1098 /** @hide Read the phone number. */ 1099 @UnsupportedAppUsage 1100 public static final int OP_READ_PHONE_NUMBERS = AppProtoEnums.APP_OP_READ_PHONE_NUMBERS; 1101 /** @hide Request package installs through package installer */ 1102 @UnsupportedAppUsage 1103 public static final int OP_REQUEST_INSTALL_PACKAGES = 1104 AppProtoEnums.APP_OP_REQUEST_INSTALL_PACKAGES; 1105 /** @hide Enter picture-in-picture. */ 1106 @UnsupportedAppUsage 1107 public static final int OP_PICTURE_IN_PICTURE = AppProtoEnums.APP_OP_PICTURE_IN_PICTURE; 1108 /** @hide Instant app start foreground service. */ 1109 @UnsupportedAppUsage 1110 public static final int OP_INSTANT_APP_START_FOREGROUND = 1111 AppProtoEnums.APP_OP_INSTANT_APP_START_FOREGROUND; 1112 /** @hide Answer incoming phone calls */ 1113 @UnsupportedAppUsage 1114 public static final int OP_ANSWER_PHONE_CALLS = AppProtoEnums.APP_OP_ANSWER_PHONE_CALLS; 1115 /** @hide Run jobs when in background */ 1116 @UnsupportedAppUsage 1117 public static final int OP_RUN_ANY_IN_BACKGROUND = AppProtoEnums.APP_OP_RUN_ANY_IN_BACKGROUND; 1118 /** @hide Change Wi-Fi connectivity state */ 1119 @UnsupportedAppUsage 1120 public static final int OP_CHANGE_WIFI_STATE = AppProtoEnums.APP_OP_CHANGE_WIFI_STATE; 1121 /** @hide Request package deletion through package installer */ 1122 @UnsupportedAppUsage 1123 public static final int OP_REQUEST_DELETE_PACKAGES = 1124 AppProtoEnums.APP_OP_REQUEST_DELETE_PACKAGES; 1125 /** @hide Bind an accessibility service. */ 1126 @UnsupportedAppUsage 1127 public static final int OP_BIND_ACCESSIBILITY_SERVICE = 1128 AppProtoEnums.APP_OP_BIND_ACCESSIBILITY_SERVICE; 1129 /** @hide Continue handover of a call from another app */ 1130 @UnsupportedAppUsage 1131 public static final int OP_ACCEPT_HANDOVER = AppProtoEnums.APP_OP_ACCEPT_HANDOVER; 1132 /** @hide Create and Manage IPsec Tunnels */ 1133 @UnsupportedAppUsage 1134 public static final int OP_MANAGE_IPSEC_TUNNELS = AppProtoEnums.APP_OP_MANAGE_IPSEC_TUNNELS; 1135 /** @hide Any app start foreground service. */ 1136 @UnsupportedAppUsage 1137 @TestApi 1138 public static final int OP_START_FOREGROUND = AppProtoEnums.APP_OP_START_FOREGROUND; 1139 /** @hide */ 1140 @UnsupportedAppUsage 1141 public static final int OP_BLUETOOTH_SCAN = AppProtoEnums.APP_OP_BLUETOOTH_SCAN; 1142 /** @hide */ 1143 public static final int OP_BLUETOOTH_CONNECT = AppProtoEnums.APP_OP_BLUETOOTH_CONNECT; 1144 /** @hide */ 1145 public static final int OP_BLUETOOTH_ADVERTISE = AppProtoEnums.APP_OP_BLUETOOTH_ADVERTISE; 1146 /** @hide Use the BiometricPrompt/BiometricManager APIs. */ 1147 public static final int OP_USE_BIOMETRIC = AppProtoEnums.APP_OP_USE_BIOMETRIC; 1148 /** @hide Physical activity recognition. */ 1149 public static final int OP_ACTIVITY_RECOGNITION = AppProtoEnums.APP_OP_ACTIVITY_RECOGNITION; 1150 /** @hide Financial app sms read. */ 1151 public static final int OP_SMS_FINANCIAL_TRANSACTIONS = 1152 AppProtoEnums.APP_OP_SMS_FINANCIAL_TRANSACTIONS; 1153 /** @hide Read media of audio type. */ 1154 public static final int OP_READ_MEDIA_AUDIO = AppProtoEnums.APP_OP_READ_MEDIA_AUDIO; 1155 /** @hide Write media of audio type. */ 1156 public static final int OP_WRITE_MEDIA_AUDIO = AppProtoEnums.APP_OP_WRITE_MEDIA_AUDIO; 1157 /** @hide Read media of video type. */ 1158 public static final int OP_READ_MEDIA_VIDEO = AppProtoEnums.APP_OP_READ_MEDIA_VIDEO; 1159 /** @hide Write media of video type. */ 1160 public static final int OP_WRITE_MEDIA_VIDEO = AppProtoEnums.APP_OP_WRITE_MEDIA_VIDEO; 1161 /** @hide Read media of image type. */ 1162 public static final int OP_READ_MEDIA_IMAGES = AppProtoEnums.APP_OP_READ_MEDIA_IMAGES; 1163 /** @hide Write media of image type. */ 1164 public static final int OP_WRITE_MEDIA_IMAGES = AppProtoEnums.APP_OP_WRITE_MEDIA_IMAGES; 1165 /** @hide Has a legacy (non-isolated) view of storage. */ 1166 public static final int OP_LEGACY_STORAGE = AppProtoEnums.APP_OP_LEGACY_STORAGE; 1167 /** @hide Accessing accessibility features */ 1168 public static final int OP_ACCESS_ACCESSIBILITY = AppProtoEnums.APP_OP_ACCESS_ACCESSIBILITY; 1169 /** @hide Read the device identifiers (IMEI / MEID, IMSI, SIM / Build serial) */ 1170 public static final int OP_READ_DEVICE_IDENTIFIERS = 1171 AppProtoEnums.APP_OP_READ_DEVICE_IDENTIFIERS; 1172 /** @hide Read location metadata from media */ 1173 public static final int OP_ACCESS_MEDIA_LOCATION = AppProtoEnums.APP_OP_ACCESS_MEDIA_LOCATION; 1174 /** @hide Query all apps on device, regardless of declarations in the calling app manifest */ 1175 public static final int OP_QUERY_ALL_PACKAGES = AppProtoEnums.APP_OP_QUERY_ALL_PACKAGES; 1176 /** @hide Access all external storage */ 1177 public static final int OP_MANAGE_EXTERNAL_STORAGE = 1178 AppProtoEnums.APP_OP_MANAGE_EXTERNAL_STORAGE; 1179 /** @hide Communicate cross-profile within the same profile group. */ 1180 public static final int OP_INTERACT_ACROSS_PROFILES = 1181 AppProtoEnums.APP_OP_INTERACT_ACROSS_PROFILES; 1182 /** 1183 * Start (without additional user intervention) a Platform VPN connection, as used by {@link 1184 * android.net.VpnManager} 1185 * 1186 * <p>This appop is granted to apps that have already been given user consent to start Platform 1187 * VPN connections. This appop is insufficient to start VpnService based VPNs; OP_ACTIVATE_VPN 1188 * is needed for that. 1189 * 1190 * @hide 1191 */ 1192 public static final int OP_ACTIVATE_PLATFORM_VPN = AppProtoEnums.APP_OP_ACTIVATE_PLATFORM_VPN; 1193 /** @hide Controls whether or not read logs are available for incremental installations. */ 1194 public static final int OP_LOADER_USAGE_STATS = AppProtoEnums.APP_OP_LOADER_USAGE_STATS; 1195 1196 // App op deprecated/removed. 1197 private static final int OP_DEPRECATED_1 = AppProtoEnums.APP_OP_DEPRECATED_1; 1198 1199 /** @hide Auto-revoke app permissions if app is unused for an extended period */ 1200 public static final int OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED = 1201 AppProtoEnums.APP_OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED; 1202 1203 /** 1204 * Whether {@link #OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED} is allowed to be changed by 1205 * the installer 1206 * 1207 * @hide 1208 */ 1209 public static final int OP_AUTO_REVOKE_MANAGED_BY_INSTALLER = 1210 AppProtoEnums.APP_OP_AUTO_REVOKE_MANAGED_BY_INSTALLER; 1211 1212 /** @hide */ 1213 public static final int OP_NO_ISOLATED_STORAGE = AppProtoEnums.APP_OP_NO_ISOLATED_STORAGE; 1214 1215 /** 1216 * Phone call is using microphone 1217 * 1218 * @hide 1219 */ 1220 public static final int OP_PHONE_CALL_MICROPHONE = AppProtoEnums.APP_OP_PHONE_CALL_MICROPHONE; 1221 /** 1222 * Phone call is using camera 1223 * 1224 * @hide 1225 */ 1226 public static final int OP_PHONE_CALL_CAMERA = AppProtoEnums.APP_OP_PHONE_CALL_CAMERA; 1227 1228 /** 1229 * Audio is being recorded for hotword detection. 1230 * 1231 * @hide 1232 */ 1233 public static final int OP_RECORD_AUDIO_HOTWORD = AppProtoEnums.APP_OP_RECORD_AUDIO_HOTWORD; 1234 1235 /** 1236 * Manage credentials in the system KeyChain. 1237 * 1238 * @hide 1239 */ 1240 public static final int OP_MANAGE_CREDENTIALS = AppProtoEnums.APP_OP_MANAGE_CREDENTIALS; 1241 1242 /** @hide */ 1243 public static final int OP_USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER = 1244 AppProtoEnums.APP_OP_USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER; 1245 1246 /** 1247 * App output audio is being recorded 1248 * 1249 * @hide 1250 */ 1251 public static final int OP_RECORD_AUDIO_OUTPUT = AppProtoEnums.APP_OP_RECORD_AUDIO_OUTPUT; 1252 1253 /** 1254 * App can schedule exact alarm to perform timing based background work 1255 * 1256 * @hide 1257 */ 1258 public static final int OP_SCHEDULE_EXACT_ALARM = AppProtoEnums.APP_OP_SCHEDULE_EXACT_ALARM; 1259 1260 /** 1261 * Fine location being accessed by a location source, which is 1262 * a component that already has location data since it is the one 1263 * that produces location, which is it is a data source for 1264 * location data. 1265 * 1266 * @hide 1267 */ 1268 public static final int OP_FINE_LOCATION_SOURCE = AppProtoEnums.APP_OP_FINE_LOCATION_SOURCE; 1269 1270 /** 1271 * Coarse location being accessed by a location source, which is 1272 * a component that already has location data since it is the one 1273 * that produces location, which is it is a data source for 1274 * location data. 1275 * 1276 * @hide 1277 */ 1278 public static final int OP_COARSE_LOCATION_SOURCE = AppProtoEnums.APP_OP_COARSE_LOCATION_SOURCE; 1279 1280 /** 1281 * Allow apps to create the requests to manage the media files without user confirmation. 1282 * 1283 * @see android.Manifest.permission#MANAGE_MEDIA 1284 * @see android.provider.MediaStore#createDeleteRequest(ContentResolver, Collection) 1285 * @see android.provider.MediaStore#createTrashRequest(ContentResolver, Collection, boolean) 1286 * @see android.provider.MediaStore#createWriteRequest(ContentResolver, Collection) 1287 * 1288 * @hide 1289 */ 1290 public static final int OP_MANAGE_MEDIA = AppProtoEnums.APP_OP_MANAGE_MEDIA; 1291 1292 /** @hide */ 1293 public static final int OP_UWB_RANGING = AppProtoEnums.APP_OP_UWB_RANGING; 1294 1295 /** @hide */ 1296 public static final int OP_NEARBY_WIFI_DEVICES = AppProtoEnums.APP_OP_NEARBY_WIFI_DEVICES; 1297 1298 /** 1299 * Activity recognition being accessed by an activity recognition source, which 1300 * is a component that already has access since it is the one that detects 1301 * activity recognition. 1302 * 1303 * @hide 1304 */ 1305 public static final int OP_ACTIVITY_RECOGNITION_SOURCE = 1306 AppProtoEnums.APP_OP_ACTIVITY_RECOGNITION_SOURCE; 1307 1308 /** 1309 * Incoming phone audio is being recorded 1310 * 1311 * @hide 1312 */ 1313 public static final int OP_RECORD_INCOMING_PHONE_AUDIO = 1314 AppProtoEnums.APP_OP_RECORD_INCOMING_PHONE_AUDIO; 1315 1316 /** 1317 * VPN app establishes a connection through the VpnService API. 1318 * 1319 * @hide 1320 */ 1321 public static final int OP_ESTABLISH_VPN_SERVICE = AppProtoEnums.APP_OP_ESTABLISH_VPN_SERVICE; 1322 1323 /** 1324 * VPN app establishes a connection through the VpnManager API. 1325 * 1326 * @hide 1327 */ 1328 public static final int OP_ESTABLISH_VPN_MANAGER = AppProtoEnums.APP_OP_ESTABLISH_VPN_MANAGER; 1329 1330 /** 1331 * Access restricted settings. 1332 * 1333 * @hide 1334 */ 1335 public static final int OP_ACCESS_RESTRICTED_SETTINGS = 1336 AppProtoEnums.APP_OP_ACCESS_RESTRICTED_SETTINGS; 1337 1338 /** 1339 * Receive microphone audio from an ambient sound detection event 1340 * 1341 * @hide 1342 */ 1343 public static final int OP_RECEIVE_AMBIENT_TRIGGER_AUDIO = 1344 AppProtoEnums.APP_OP_RECEIVE_AMBIENT_TRIGGER_AUDIO; 1345 1346 /** @hide */ 1347 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 1348 public static final int _NUM_OP = 121; 1349 1350 /** Access to coarse location information. */ 1351 public static final String OPSTR_COARSE_LOCATION = "android:coarse_location"; 1352 /** Access to fine location information. */ 1353 public static final String OPSTR_FINE_LOCATION = 1354 "android:fine_location"; 1355 /** Continually monitoring location data. */ 1356 public static final String OPSTR_MONITOR_LOCATION 1357 = "android:monitor_location"; 1358 /** Continually monitoring location data with a relatively high power request. */ 1359 public static final String OPSTR_MONITOR_HIGH_POWER_LOCATION 1360 = "android:monitor_location_high_power"; 1361 /** Access to {@link android.app.usage.UsageStatsManager}. */ 1362 public static final String OPSTR_GET_USAGE_STATS 1363 = "android:get_usage_stats"; 1364 /** Activate a VPN connection without user intervention. @hide */ 1365 @SystemApi 1366 public static final String OPSTR_ACTIVATE_VPN 1367 = "android:activate_vpn"; 1368 /** Allows an application to read the user's contacts data. */ 1369 public static final String OPSTR_READ_CONTACTS 1370 = "android:read_contacts"; 1371 /** Allows an application to write to the user's contacts data. */ 1372 public static final String OPSTR_WRITE_CONTACTS 1373 = "android:write_contacts"; 1374 /** Allows an application to read the user's call log. */ 1375 public static final String OPSTR_READ_CALL_LOG 1376 = "android:read_call_log"; 1377 /** Allows an application to write to the user's call log. */ 1378 public static final String OPSTR_WRITE_CALL_LOG 1379 = "android:write_call_log"; 1380 /** Allows an application to read the user's calendar data. */ 1381 public static final String OPSTR_READ_CALENDAR 1382 = "android:read_calendar"; 1383 /** Allows an application to write to the user's calendar data. */ 1384 public static final String OPSTR_WRITE_CALENDAR 1385 = "android:write_calendar"; 1386 /** Allows an application to initiate a phone call. */ 1387 public static final String OPSTR_CALL_PHONE 1388 = "android:call_phone"; 1389 /** Allows an application to read SMS messages. */ 1390 public static final String OPSTR_READ_SMS 1391 = "android:read_sms"; 1392 /** Allows an application to receive SMS messages. */ 1393 public static final String OPSTR_RECEIVE_SMS 1394 = "android:receive_sms"; 1395 /** Allows an application to receive MMS messages. */ 1396 public static final String OPSTR_RECEIVE_MMS 1397 = "android:receive_mms"; 1398 /** Allows an application to receive WAP push messages. */ 1399 public static final String OPSTR_RECEIVE_WAP_PUSH 1400 = "android:receive_wap_push"; 1401 /** Allows an application to send SMS messages. */ 1402 public static final String OPSTR_SEND_SMS 1403 = "android:send_sms"; 1404 /** Required to be able to access the camera device. */ 1405 public static final String OPSTR_CAMERA 1406 = "android:camera"; 1407 /** Required to be able to access the microphone device. */ 1408 public static final String OPSTR_RECORD_AUDIO 1409 = "android:record_audio"; 1410 /** Required to access phone state related information. */ 1411 public static final String OPSTR_READ_PHONE_STATE 1412 = "android:read_phone_state"; 1413 /** Required to access phone state related information. */ 1414 public static final String OPSTR_ADD_VOICEMAIL 1415 = "android:add_voicemail"; 1416 /** Access APIs for SIP calling over VOIP or WiFi */ 1417 public static final String OPSTR_USE_SIP 1418 = "android:use_sip"; 1419 /** Access APIs for diverting outgoing calls */ 1420 public static final String OPSTR_PROCESS_OUTGOING_CALLS 1421 = "android:process_outgoing_calls"; 1422 /** Use the fingerprint API. */ 1423 public static final String OPSTR_USE_FINGERPRINT 1424 = "android:use_fingerprint"; 1425 /** Access to body sensors such as heart rate, etc. */ 1426 public static final String OPSTR_BODY_SENSORS 1427 = "android:body_sensors"; 1428 /** Read previously received cell broadcast messages. */ 1429 public static final String OPSTR_READ_CELL_BROADCASTS 1430 = "android:read_cell_broadcasts"; 1431 /** Inject mock location into the system. */ 1432 public static final String OPSTR_MOCK_LOCATION 1433 = "android:mock_location"; 1434 /** Read external storage. */ 1435 public static final String OPSTR_READ_EXTERNAL_STORAGE 1436 = "android:read_external_storage"; 1437 /** Write external storage. */ 1438 public static final String OPSTR_WRITE_EXTERNAL_STORAGE 1439 = "android:write_external_storage"; 1440 /** Required to draw on top of other apps. */ 1441 public static final String OPSTR_SYSTEM_ALERT_WINDOW 1442 = "android:system_alert_window"; 1443 /** Required to write/modify/update system settings. */ 1444 public static final String OPSTR_WRITE_SETTINGS 1445 = "android:write_settings"; 1446 /** @hide Get device accounts. */ 1447 @SystemApi 1448 public static final String OPSTR_GET_ACCOUNTS 1449 = "android:get_accounts"; 1450 public static final String OPSTR_READ_PHONE_NUMBERS 1451 = "android:read_phone_numbers"; 1452 /** Access to picture-in-picture. */ 1453 public static final String OPSTR_PICTURE_IN_PICTURE 1454 = "android:picture_in_picture"; 1455 /** @hide */ 1456 @SystemApi 1457 public static final String OPSTR_INSTANT_APP_START_FOREGROUND 1458 = "android:instant_app_start_foreground"; 1459 /** Answer incoming phone calls */ 1460 public static final String OPSTR_ANSWER_PHONE_CALLS 1461 = "android:answer_phone_calls"; 1462 /** 1463 * Accept call handover 1464 * @hide 1465 */ 1466 @SystemApi 1467 public static final String OPSTR_ACCEPT_HANDOVER 1468 = "android:accept_handover"; 1469 /** @hide */ 1470 @SystemApi 1471 public static final String OPSTR_GPS = "android:gps"; 1472 /** @hide */ 1473 @SystemApi 1474 public static final String OPSTR_VIBRATE = "android:vibrate"; 1475 /** @hide */ 1476 @SystemApi 1477 public static final String OPSTR_WIFI_SCAN = "android:wifi_scan"; 1478 /** @hide */ 1479 @SystemApi 1480 public static final String OPSTR_POST_NOTIFICATION = "android:post_notification"; 1481 /** @hide */ 1482 @SystemApi 1483 public static final String OPSTR_NEIGHBORING_CELLS = "android:neighboring_cells"; 1484 /** @hide */ 1485 @SystemApi 1486 public static final String OPSTR_WRITE_SMS = "android:write_sms"; 1487 /** @hide */ 1488 @SystemApi 1489 public static final String OPSTR_RECEIVE_EMERGENCY_BROADCAST = 1490 "android:receive_emergency_broadcast"; 1491 /** @hide */ 1492 @SystemApi 1493 public static final String OPSTR_READ_ICC_SMS = "android:read_icc_sms"; 1494 /** @hide */ 1495 @SystemApi 1496 public static final String OPSTR_WRITE_ICC_SMS = "android:write_icc_sms"; 1497 /** @hide */ 1498 @SystemApi 1499 public static final String OPSTR_ACCESS_NOTIFICATIONS = "android:access_notifications"; 1500 /** @hide */ 1501 @SystemApi 1502 public static final String OPSTR_PLAY_AUDIO = "android:play_audio"; 1503 /** @hide */ 1504 @SystemApi 1505 public static final String OPSTR_READ_CLIPBOARD = "android:read_clipboard"; 1506 /** @hide */ 1507 @SystemApi 1508 public static final String OPSTR_WRITE_CLIPBOARD = "android:write_clipboard"; 1509 /** @hide */ 1510 @SystemApi 1511 public static final String OPSTR_TAKE_MEDIA_BUTTONS = "android:take_media_buttons"; 1512 /** @hide */ 1513 @SystemApi 1514 public static final String OPSTR_TAKE_AUDIO_FOCUS = "android:take_audio_focus"; 1515 /** @hide */ 1516 @SystemApi 1517 public static final String OPSTR_AUDIO_MASTER_VOLUME = "android:audio_master_volume"; 1518 /** @hide */ 1519 @SystemApi 1520 public static final String OPSTR_AUDIO_VOICE_VOLUME = "android:audio_voice_volume"; 1521 /** @hide */ 1522 @SystemApi 1523 public static final String OPSTR_AUDIO_RING_VOLUME = "android:audio_ring_volume"; 1524 /** @hide */ 1525 @SystemApi 1526 public static final String OPSTR_AUDIO_MEDIA_VOLUME = "android:audio_media_volume"; 1527 /** @hide */ 1528 @SystemApi 1529 public static final String OPSTR_AUDIO_ALARM_VOLUME = "android:audio_alarm_volume"; 1530 /** @hide */ 1531 @SystemApi 1532 public static final String OPSTR_AUDIO_NOTIFICATION_VOLUME = 1533 "android:audio_notification_volume"; 1534 /** @hide */ 1535 @SystemApi 1536 public static final String OPSTR_AUDIO_BLUETOOTH_VOLUME = "android:audio_bluetooth_volume"; 1537 /** @hide */ 1538 @SystemApi 1539 public static final String OPSTR_WAKE_LOCK = "android:wake_lock"; 1540 /** @hide */ 1541 @SystemApi 1542 public static final String OPSTR_MUTE_MICROPHONE = "android:mute_microphone"; 1543 /** @hide */ 1544 @SystemApi 1545 public static final String OPSTR_TOAST_WINDOW = "android:toast_window"; 1546 /** @hide */ 1547 @SystemApi 1548 public static final String OPSTR_PROJECT_MEDIA = "android:project_media"; 1549 /** @hide */ 1550 @SystemApi 1551 public static final String OPSTR_WRITE_WALLPAPER = "android:write_wallpaper"; 1552 /** @hide */ 1553 @SystemApi 1554 public static final String OPSTR_ASSIST_STRUCTURE = "android:assist_structure"; 1555 /** @hide */ 1556 @SystemApi 1557 public static final String OPSTR_ASSIST_SCREENSHOT = "android:assist_screenshot"; 1558 /** @hide */ 1559 @SystemApi 1560 public static final String OPSTR_TURN_SCREEN_ON = "android:turn_screen_on"; 1561 /** @hide */ 1562 @SystemApi 1563 public static final String OPSTR_RUN_IN_BACKGROUND = "android:run_in_background"; 1564 /** @hide */ 1565 @SystemApi 1566 public static final String OPSTR_AUDIO_ACCESSIBILITY_VOLUME = 1567 "android:audio_accessibility_volume"; 1568 /** @hide */ 1569 @SystemApi 1570 public static final String OPSTR_REQUEST_INSTALL_PACKAGES = "android:request_install_packages"; 1571 /** @hide */ 1572 @SystemApi 1573 public static final String OPSTR_RUN_ANY_IN_BACKGROUND = "android:run_any_in_background"; 1574 /** @hide */ 1575 @SystemApi 1576 public static final String OPSTR_CHANGE_WIFI_STATE = "android:change_wifi_state"; 1577 /** @hide */ 1578 @SystemApi 1579 public static final String OPSTR_REQUEST_DELETE_PACKAGES = "android:request_delete_packages"; 1580 /** @hide */ 1581 @SystemApi 1582 public static final String OPSTR_BIND_ACCESSIBILITY_SERVICE = 1583 "android:bind_accessibility_service"; 1584 /** @hide */ 1585 @SystemApi 1586 public static final String OPSTR_MANAGE_IPSEC_TUNNELS = "android:manage_ipsec_tunnels"; 1587 /** @hide */ 1588 @SystemApi 1589 public static final String OPSTR_START_FOREGROUND = "android:start_foreground"; 1590 /** @hide */ 1591 public static final String OPSTR_BLUETOOTH_SCAN = "android:bluetooth_scan"; 1592 /** @hide */ 1593 public static final String OPSTR_BLUETOOTH_CONNECT = "android:bluetooth_connect"; 1594 /** @hide */ 1595 public static final String OPSTR_BLUETOOTH_ADVERTISE = "android:bluetooth_advertise"; 1596 1597 /** @hide Use the BiometricPrompt/BiometricManager APIs. */ 1598 public static final String OPSTR_USE_BIOMETRIC = "android:use_biometric"; 1599 1600 /** @hide Recognize physical activity. */ 1601 @TestApi 1602 public static final String OPSTR_ACTIVITY_RECOGNITION = "android:activity_recognition"; 1603 1604 /** @hide Financial app read sms. */ 1605 public static final String OPSTR_SMS_FINANCIAL_TRANSACTIONS = 1606 "android:sms_financial_transactions"; 1607 1608 /** @hide Read media of audio type. */ 1609 @SystemApi 1610 public static final String OPSTR_READ_MEDIA_AUDIO = "android:read_media_audio"; 1611 /** @hide Write media of audio type. */ 1612 @SystemApi 1613 public static final String OPSTR_WRITE_MEDIA_AUDIO = "android:write_media_audio"; 1614 /** @hide Read media of video type. */ 1615 @SystemApi 1616 public static final String OPSTR_READ_MEDIA_VIDEO = "android:read_media_video"; 1617 /** @hide Write media of video type. */ 1618 @SystemApi 1619 public static final String OPSTR_WRITE_MEDIA_VIDEO = "android:write_media_video"; 1620 /** @hide Read media of image type. */ 1621 @SystemApi 1622 public static final String OPSTR_READ_MEDIA_IMAGES = "android:read_media_images"; 1623 /** @hide Write media of image type. */ 1624 @SystemApi 1625 public static final String OPSTR_WRITE_MEDIA_IMAGES = "android:write_media_images"; 1626 /** @hide Has a legacy (non-isolated) view of storage. */ 1627 @SystemApi 1628 public static final String OPSTR_LEGACY_STORAGE = "android:legacy_storage"; 1629 /** @hide Read location metadata from media */ 1630 public static final String OPSTR_ACCESS_MEDIA_LOCATION = "android:access_media_location"; 1631 1632 /** @hide Interact with accessibility. */ 1633 @SystemApi 1634 public static final String OPSTR_ACCESS_ACCESSIBILITY = "android:access_accessibility"; 1635 /** @hide Read device identifiers */ 1636 public static final String OPSTR_READ_DEVICE_IDENTIFIERS = "android:read_device_identifiers"; 1637 /** @hide Query all packages on device */ 1638 public static final String OPSTR_QUERY_ALL_PACKAGES = "android:query_all_packages"; 1639 /** @hide Access all external storage */ 1640 @SystemApi 1641 public static final String OPSTR_MANAGE_EXTERNAL_STORAGE = 1642 "android:manage_external_storage"; 1643 1644 /** @hide Auto-revoke app permissions if app is unused for an extended period */ 1645 @SystemApi 1646 public static final String OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED = 1647 "android:auto_revoke_permissions_if_unused"; 1648 1649 /** @hide Auto-revoke app permissions if app is unused for an extended period */ 1650 @SystemApi 1651 public static final String OPSTR_AUTO_REVOKE_MANAGED_BY_INSTALLER = 1652 "android:auto_revoke_managed_by_installer"; 1653 1654 /** @hide Communicate cross-profile within the same profile group. */ 1655 @SystemApi 1656 public static final String OPSTR_INTERACT_ACROSS_PROFILES = "android:interact_across_profiles"; 1657 /** @hide Start Platform VPN without user intervention */ 1658 @SystemApi 1659 public static final String OPSTR_ACTIVATE_PLATFORM_VPN = "android:activate_platform_vpn"; 1660 /** @hide */ 1661 @SystemApi 1662 public static final String OPSTR_LOADER_USAGE_STATS = "android:loader_usage_stats"; 1663 1664 /** 1665 * Grants an app access to the {@link android.telecom.InCallService} API to see 1666 * information about ongoing calls and to enable control of calls. 1667 * @hide 1668 */ 1669 @SystemApi 1670 @TestApi 1671 public static final String OPSTR_MANAGE_ONGOING_CALLS = "android:manage_ongoing_calls"; 1672 1673 /** 1674 * AppOp granted to apps that we are started via {@code am instrument -e --no-isolated-storage} 1675 * 1676 * <p>MediaProvider is the only component (outside of system server) that should care about this 1677 * app op, hence {@code SystemApi.Client.MODULE_LIBRARIES}. 1678 * 1679 * @hide 1680 */ 1681 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 1682 public static final String OPSTR_NO_ISOLATED_STORAGE = "android:no_isolated_storage"; 1683 1684 /** 1685 * Phone call is using microphone 1686 * 1687 * @hide 1688 */ 1689 @SystemApi 1690 public static final String OPSTR_PHONE_CALL_MICROPHONE = "android:phone_call_microphone"; 1691 /** 1692 * Phone call is using camera 1693 * 1694 * @hide 1695 */ 1696 @SystemApi 1697 public static final String OPSTR_PHONE_CALL_CAMERA = "android:phone_call_camera"; 1698 1699 /** 1700 * Audio is being recorded for hotword detection. 1701 * 1702 * @hide 1703 */ 1704 @TestApi 1705 public static final String OPSTR_RECORD_AUDIO_HOTWORD = "android:record_audio_hotword"; 1706 1707 /** 1708 * Manage credentials in the system KeyChain. 1709 * 1710 * @hide 1711 */ 1712 public static final String OPSTR_MANAGE_CREDENTIALS = "android:manage_credentials"; 1713 1714 /** 1715 * Allows to read device identifiers and use ICC based authentication like EAP-AKA. 1716 * 1717 * @hide 1718 */ 1719 @TestApi 1720 public static final String OPSTR_USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER = 1721 "android:use_icc_auth_with_device_identifier"; 1722 /** 1723 * App output audio is being recorded 1724 * 1725 * @hide 1726 */ 1727 public static final String OPSTR_RECORD_AUDIO_OUTPUT = "android:record_audio_output"; 1728 1729 /** 1730 * App can schedule exact alarm to perform timing based background work. 1731 * 1732 * @hide 1733 */ 1734 public static final String OPSTR_SCHEDULE_EXACT_ALARM = "android:schedule_exact_alarm"; 1735 1736 /** 1737 * Fine location being accessed by a location source, which is 1738 * a component that already has location since it is the one that 1739 * produces location. 1740 * 1741 * @hide 1742 */ 1743 public static final String OPSTR_FINE_LOCATION_SOURCE = "android:fine_location_source"; 1744 1745 /** 1746 * Coarse location being accessed by a location source, which is 1747 * a component that already has location since it is the one that 1748 * produces location. 1749 * 1750 * @hide 1751 */ 1752 public static final String OPSTR_COARSE_LOCATION_SOURCE = "android:coarse_location_source"; 1753 1754 /** 1755 * Allow apps to create the requests to manage the media files without user confirmation. 1756 * 1757 * @see android.Manifest.permission#MANAGE_MEDIA 1758 * @see android.provider.MediaStore#createDeleteRequest(ContentResolver, Collection) 1759 * @see android.provider.MediaStore#createTrashRequest(ContentResolver, Collection, boolean) 1760 * @see android.provider.MediaStore#createWriteRequest(ContentResolver, Collection) 1761 * 1762 * @hide 1763 */ 1764 public static final String OPSTR_MANAGE_MEDIA = "android:manage_media"; 1765 /** @hide */ 1766 public static final String OPSTR_UWB_RANGING = "android:uwb_ranging"; 1767 /** @hide */ 1768 public static final String OPSTR_NEARBY_WIFI_DEVICES = "android:nearby_wifi_devices"; 1769 1770 /** 1771 * Activity recognition being accessed by an activity recognition source, which 1772 * is a component that already has access since it is the one that detects 1773 * activity recognition. 1774 * 1775 * @hide 1776 */ 1777 @TestApi 1778 public static final String OPSTR_ACTIVITY_RECOGNITION_SOURCE = 1779 "android:activity_recognition_source"; 1780 1781 /** 1782 * @hide 1783 */ 1784 public static final String OPSTR_RECORD_INCOMING_PHONE_AUDIO = 1785 "android:record_incoming_phone_audio"; 1786 1787 /** 1788 * VPN app establishes a connection through the VpnService API. 1789 * 1790 * @hide 1791 */ 1792 @SystemApi 1793 public static final String OPSTR_ESTABLISH_VPN_SERVICE = "android:establish_vpn_service"; 1794 1795 /** 1796 * VPN app establishes a connection through the VpnManager API. 1797 * 1798 * @hide 1799 */ 1800 @SystemApi 1801 public static final String OPSTR_ESTABLISH_VPN_MANAGER = "android:establish_vpn_manager"; 1802 1803 /** 1804 * Limit user accessing restricted settings. 1805 * 1806 * @hide 1807 */ 1808 public static final String OPSTR_ACCESS_RESTRICTED_SETTINGS = 1809 "android:access_restricted_settings"; 1810 1811 /** 1812 * Receive microphone audio from an ambient sound detection event 1813 * 1814 * @hide 1815 */ 1816 public static final String OPSTR_RECEIVE_AMBIENT_TRIGGER_AUDIO = 1817 "android:receive_ambient_trigger_audio"; 1818 1819 /** {@link #sAppOpsToNote} not initialized yet for this op */ 1820 private static final byte SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED = 0; 1821 /** Should not collect noting of this app-op in {@link #sAppOpsToNote} */ 1822 private static final byte SHOULD_NOT_COLLECT_NOTE_OP = 1; 1823 /** Should collect noting of this app-op in {@link #sAppOpsToNote} */ 1824 private static final byte SHOULD_COLLECT_NOTE_OP = 2; 1825 1826 @Retention(RetentionPolicy.SOURCE) 1827 @IntDef(flag = true, prefix = { "SHOULD_" }, value = { 1828 SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED, 1829 SHOULD_NOT_COLLECT_NOTE_OP, 1830 SHOULD_COLLECT_NOTE_OP 1831 }) 1832 private @interface ShouldCollectNoteOp {} 1833 1834 private static final int[] RUNTIME_AND_APPOP_PERMISSIONS_OPS = { 1835 // RUNTIME PERMISSIONS 1836 // Contacts 1837 OP_READ_CONTACTS, 1838 OP_WRITE_CONTACTS, 1839 OP_GET_ACCOUNTS, 1840 // Calendar 1841 OP_READ_CALENDAR, 1842 OP_WRITE_CALENDAR, 1843 // SMS 1844 OP_SEND_SMS, 1845 OP_RECEIVE_SMS, 1846 OP_READ_SMS, 1847 OP_RECEIVE_WAP_PUSH, 1848 OP_RECEIVE_MMS, 1849 OP_READ_CELL_BROADCASTS, 1850 // Storage 1851 OP_READ_EXTERNAL_STORAGE, 1852 OP_WRITE_EXTERNAL_STORAGE, 1853 OP_ACCESS_MEDIA_LOCATION, 1854 // Location 1855 OP_COARSE_LOCATION, 1856 OP_FINE_LOCATION, 1857 // Phone 1858 OP_READ_PHONE_STATE, 1859 OP_READ_PHONE_NUMBERS, 1860 OP_CALL_PHONE, 1861 OP_READ_CALL_LOG, 1862 OP_WRITE_CALL_LOG, 1863 OP_ADD_VOICEMAIL, 1864 OP_USE_SIP, 1865 OP_PROCESS_OUTGOING_CALLS, 1866 OP_ANSWER_PHONE_CALLS, 1867 OP_ACCEPT_HANDOVER, 1868 // Microphone 1869 OP_RECORD_AUDIO, 1870 // Camera 1871 OP_CAMERA, 1872 // Body sensors 1873 OP_BODY_SENSORS, 1874 // Activity recognition 1875 OP_ACTIVITY_RECOGNITION, 1876 // Aural 1877 OP_READ_MEDIA_AUDIO, 1878 OP_WRITE_MEDIA_AUDIO, 1879 // Visual 1880 OP_READ_MEDIA_VIDEO, 1881 OP_WRITE_MEDIA_VIDEO, 1882 OP_READ_MEDIA_IMAGES, 1883 OP_WRITE_MEDIA_IMAGES, 1884 // Nearby devices 1885 OP_BLUETOOTH_SCAN, 1886 OP_BLUETOOTH_CONNECT, 1887 OP_BLUETOOTH_ADVERTISE, 1888 OP_UWB_RANGING, 1889 OP_NEARBY_WIFI_DEVICES, 1890 // Notifications 1891 OP_POST_NOTIFICATION, 1892 1893 // APPOP PERMISSIONS 1894 OP_ACCESS_NOTIFICATIONS, 1895 OP_SYSTEM_ALERT_WINDOW, 1896 OP_WRITE_SETTINGS, 1897 OP_REQUEST_INSTALL_PACKAGES, 1898 OP_START_FOREGROUND, 1899 OP_SMS_FINANCIAL_TRANSACTIONS, 1900 OP_MANAGE_IPSEC_TUNNELS, 1901 OP_INSTANT_APP_START_FOREGROUND, 1902 OP_MANAGE_EXTERNAL_STORAGE, 1903 OP_INTERACT_ACROSS_PROFILES, 1904 OP_LOADER_USAGE_STATS, 1905 OP_MANAGE_ONGOING_CALLS, 1906 OP_USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER, 1907 OP_SCHEDULE_EXACT_ALARM, 1908 OP_MANAGE_MEDIA, 1909 }; 1910 1911 /** 1912 * This maps each operation to the operation that serves as the 1913 * switch to determine whether it is allowed. Generally this is 1914 * a 1:1 mapping, but for some things (like location) that have 1915 * multiple low-level operations being tracked that should be 1916 * presented to the user as one switch then this can be used to 1917 * make them all controlled by the same single operation. 1918 */ 1919 private static int[] sOpToSwitch = new int[] { 1920 OP_COARSE_LOCATION, // COARSE_LOCATION 1921 OP_FINE_LOCATION, // FINE_LOCATION 1922 OP_COARSE_LOCATION, // GPS 1923 OP_VIBRATE, // VIBRATE 1924 OP_READ_CONTACTS, // READ_CONTACTS 1925 OP_WRITE_CONTACTS, // WRITE_CONTACTS 1926 OP_READ_CALL_LOG, // READ_CALL_LOG 1927 OP_WRITE_CALL_LOG, // WRITE_CALL_LOG 1928 OP_READ_CALENDAR, // READ_CALENDAR 1929 OP_WRITE_CALENDAR, // WRITE_CALENDAR 1930 OP_COARSE_LOCATION, // WIFI_SCAN 1931 OP_POST_NOTIFICATION, // POST_NOTIFICATION 1932 OP_COARSE_LOCATION, // NEIGHBORING_CELLS 1933 OP_CALL_PHONE, // CALL_PHONE 1934 OP_READ_SMS, // READ_SMS 1935 OP_WRITE_SMS, // WRITE_SMS 1936 OP_RECEIVE_SMS, // RECEIVE_SMS 1937 OP_RECEIVE_SMS, // RECEIVE_EMERGECY_SMS 1938 OP_RECEIVE_MMS, // RECEIVE_MMS 1939 OP_RECEIVE_WAP_PUSH, // RECEIVE_WAP_PUSH 1940 OP_SEND_SMS, // SEND_SMS 1941 OP_READ_SMS, // READ_ICC_SMS 1942 OP_WRITE_SMS, // WRITE_ICC_SMS 1943 OP_WRITE_SETTINGS, // WRITE_SETTINGS 1944 OP_SYSTEM_ALERT_WINDOW, // SYSTEM_ALERT_WINDOW 1945 OP_ACCESS_NOTIFICATIONS, // ACCESS_NOTIFICATIONS 1946 OP_CAMERA, // CAMERA 1947 OP_RECORD_AUDIO, // RECORD_AUDIO 1948 OP_PLAY_AUDIO, // PLAY_AUDIO 1949 OP_READ_CLIPBOARD, // READ_CLIPBOARD 1950 OP_WRITE_CLIPBOARD, // WRITE_CLIPBOARD 1951 OP_TAKE_MEDIA_BUTTONS, // TAKE_MEDIA_BUTTONS 1952 OP_TAKE_AUDIO_FOCUS, // TAKE_AUDIO_FOCUS 1953 OP_AUDIO_MASTER_VOLUME, // AUDIO_MASTER_VOLUME 1954 OP_AUDIO_VOICE_VOLUME, // AUDIO_VOICE_VOLUME 1955 OP_AUDIO_RING_VOLUME, // AUDIO_RING_VOLUME 1956 OP_AUDIO_MEDIA_VOLUME, // AUDIO_MEDIA_VOLUME 1957 OP_AUDIO_ALARM_VOLUME, // AUDIO_ALARM_VOLUME 1958 OP_AUDIO_NOTIFICATION_VOLUME, // AUDIO_NOTIFICATION_VOLUME 1959 OP_AUDIO_BLUETOOTH_VOLUME, // AUDIO_BLUETOOTH_VOLUME 1960 OP_WAKE_LOCK, // WAKE_LOCK 1961 OP_COARSE_LOCATION, // MONITOR_LOCATION 1962 OP_COARSE_LOCATION, // MONITOR_HIGH_POWER_LOCATION 1963 OP_GET_USAGE_STATS, // GET_USAGE_STATS 1964 OP_MUTE_MICROPHONE, // MUTE_MICROPHONE 1965 OP_TOAST_WINDOW, // TOAST_WINDOW 1966 OP_PROJECT_MEDIA, // PROJECT_MEDIA 1967 OP_ACTIVATE_VPN, // ACTIVATE_VPN 1968 OP_WRITE_WALLPAPER, // WRITE_WALLPAPER 1969 OP_ASSIST_STRUCTURE, // ASSIST_STRUCTURE 1970 OP_ASSIST_SCREENSHOT, // ASSIST_SCREENSHOT 1971 OP_READ_PHONE_STATE, // READ_PHONE_STATE 1972 OP_ADD_VOICEMAIL, // ADD_VOICEMAIL 1973 OP_USE_SIP, // USE_SIP 1974 OP_PROCESS_OUTGOING_CALLS, // PROCESS_OUTGOING_CALLS 1975 OP_USE_FINGERPRINT, // USE_FINGERPRINT 1976 OP_BODY_SENSORS, // BODY_SENSORS 1977 OP_READ_CELL_BROADCASTS, // READ_CELL_BROADCASTS 1978 OP_MOCK_LOCATION, // MOCK_LOCATION 1979 OP_READ_EXTERNAL_STORAGE, // READ_EXTERNAL_STORAGE 1980 OP_WRITE_EXTERNAL_STORAGE, // WRITE_EXTERNAL_STORAGE 1981 OP_TURN_SCREEN_ON, // TURN_SCREEN_ON 1982 OP_GET_ACCOUNTS, // GET_ACCOUNTS 1983 OP_RUN_IN_BACKGROUND, // RUN_IN_BACKGROUND 1984 OP_AUDIO_ACCESSIBILITY_VOLUME, // AUDIO_ACCESSIBILITY_VOLUME 1985 OP_READ_PHONE_NUMBERS, // READ_PHONE_NUMBERS 1986 OP_REQUEST_INSTALL_PACKAGES, // REQUEST_INSTALL_PACKAGES 1987 OP_PICTURE_IN_PICTURE, // ENTER_PICTURE_IN_PICTURE_ON_HIDE 1988 OP_INSTANT_APP_START_FOREGROUND, // INSTANT_APP_START_FOREGROUND 1989 OP_ANSWER_PHONE_CALLS, // ANSWER_PHONE_CALLS 1990 OP_RUN_ANY_IN_BACKGROUND, // OP_RUN_ANY_IN_BACKGROUND 1991 OP_CHANGE_WIFI_STATE, // OP_CHANGE_WIFI_STATE 1992 OP_REQUEST_DELETE_PACKAGES, // OP_REQUEST_DELETE_PACKAGES 1993 OP_BIND_ACCESSIBILITY_SERVICE, // OP_BIND_ACCESSIBILITY_SERVICE 1994 OP_ACCEPT_HANDOVER, // ACCEPT_HANDOVER 1995 OP_MANAGE_IPSEC_TUNNELS, // MANAGE_IPSEC_HANDOVERS 1996 OP_START_FOREGROUND, // START_FOREGROUND 1997 OP_BLUETOOTH_SCAN, // BLUETOOTH_SCAN 1998 OP_USE_BIOMETRIC, // BIOMETRIC 1999 OP_ACTIVITY_RECOGNITION, // ACTIVITY_RECOGNITION 2000 OP_SMS_FINANCIAL_TRANSACTIONS, // SMS_FINANCIAL_TRANSACTIONS 2001 OP_READ_MEDIA_AUDIO, // READ_MEDIA_AUDIO 2002 OP_WRITE_MEDIA_AUDIO, // WRITE_MEDIA_AUDIO 2003 OP_READ_MEDIA_VIDEO, // READ_MEDIA_VIDEO 2004 OP_WRITE_MEDIA_VIDEO, // WRITE_MEDIA_VIDEO 2005 OP_READ_MEDIA_IMAGES, // READ_MEDIA_IMAGES 2006 OP_WRITE_MEDIA_IMAGES, // WRITE_MEDIA_IMAGES 2007 OP_LEGACY_STORAGE, // LEGACY_STORAGE 2008 OP_ACCESS_ACCESSIBILITY, // ACCESS_ACCESSIBILITY 2009 OP_READ_DEVICE_IDENTIFIERS, // READ_DEVICE_IDENTIFIERS 2010 OP_ACCESS_MEDIA_LOCATION, // ACCESS_MEDIA_LOCATION 2011 OP_QUERY_ALL_PACKAGES, // QUERY_ALL_PACKAGES 2012 OP_MANAGE_EXTERNAL_STORAGE, // MANAGE_EXTERNAL_STORAGE 2013 OP_INTERACT_ACROSS_PROFILES, //INTERACT_ACROSS_PROFILES 2014 OP_ACTIVATE_PLATFORM_VPN, // ACTIVATE_PLATFORM_VPN 2015 OP_LOADER_USAGE_STATS, // LOADER_USAGE_STATS 2016 OP_DEPRECATED_1, // deprecated 2017 OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED, //AUTO_REVOKE_PERMISSIONS_IF_UNUSED 2018 OP_AUTO_REVOKE_MANAGED_BY_INSTALLER, //OP_AUTO_REVOKE_MANAGED_BY_INSTALLER 2019 OP_NO_ISOLATED_STORAGE, // NO_ISOLATED_STORAGE 2020 OP_PHONE_CALL_MICROPHONE, // OP_PHONE_CALL_MICROPHONE 2021 OP_PHONE_CALL_CAMERA, // OP_PHONE_CALL_CAMERA 2022 OP_RECORD_AUDIO_HOTWORD, // RECORD_AUDIO_HOTWORD 2023 OP_MANAGE_ONGOING_CALLS, // MANAGE_ONGOING_CALLS 2024 OP_MANAGE_CREDENTIALS, // MANAGE_CREDENTIALS 2025 OP_USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER, // USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER 2026 OP_RECORD_AUDIO_OUTPUT, // RECORD_AUDIO_OUTPUT 2027 OP_SCHEDULE_EXACT_ALARM, // SCHEDULE_EXACT_ALARM 2028 OP_FINE_LOCATION, // OP_FINE_LOCATION_SOURCE 2029 OP_COARSE_LOCATION, // OP_COARSE_LOCATION_SOURCE 2030 OP_MANAGE_MEDIA, // MANAGE_MEDIA 2031 OP_BLUETOOTH_CONNECT, // OP_BLUETOOTH_CONNECT 2032 OP_UWB_RANGING, // OP_UWB_RANGING 2033 OP_ACTIVITY_RECOGNITION, // OP_ACTIVITY_RECOGNITION_SOURCE 2034 OP_BLUETOOTH_ADVERTISE, // OP_BLUETOOTH_ADVERTISE 2035 OP_RECORD_INCOMING_PHONE_AUDIO, // OP_RECORD_INCOMING_PHONE_AUDIO 2036 OP_NEARBY_WIFI_DEVICES, // OP_NEARBY_WIFI_DEVICES 2037 OP_ESTABLISH_VPN_SERVICE, // OP_ESTABLISH_VPN_SERVICE 2038 OP_ESTABLISH_VPN_MANAGER, // OP_ESTABLISH_VPN_MANAGER 2039 OP_ACCESS_RESTRICTED_SETTINGS, // OP_ACCESS_RESTRICTED_SETTINGS 2040 OP_RECEIVE_AMBIENT_TRIGGER_AUDIO, // RECEIVE_SOUNDTRIGGER_AUDIO 2041 }; 2042 2043 /** 2044 * This maps each operation to the public string constant for it. 2045 */ 2046 private static String[] sOpToString = new String[]{ 2047 OPSTR_COARSE_LOCATION, 2048 OPSTR_FINE_LOCATION, 2049 OPSTR_GPS, 2050 OPSTR_VIBRATE, 2051 OPSTR_READ_CONTACTS, 2052 OPSTR_WRITE_CONTACTS, 2053 OPSTR_READ_CALL_LOG, 2054 OPSTR_WRITE_CALL_LOG, 2055 OPSTR_READ_CALENDAR, 2056 OPSTR_WRITE_CALENDAR, 2057 OPSTR_WIFI_SCAN, 2058 OPSTR_POST_NOTIFICATION, 2059 OPSTR_NEIGHBORING_CELLS, 2060 OPSTR_CALL_PHONE, 2061 OPSTR_READ_SMS, 2062 OPSTR_WRITE_SMS, 2063 OPSTR_RECEIVE_SMS, 2064 OPSTR_RECEIVE_EMERGENCY_BROADCAST, 2065 OPSTR_RECEIVE_MMS, 2066 OPSTR_RECEIVE_WAP_PUSH, 2067 OPSTR_SEND_SMS, 2068 OPSTR_READ_ICC_SMS, 2069 OPSTR_WRITE_ICC_SMS, 2070 OPSTR_WRITE_SETTINGS, 2071 OPSTR_SYSTEM_ALERT_WINDOW, 2072 OPSTR_ACCESS_NOTIFICATIONS, 2073 OPSTR_CAMERA, 2074 OPSTR_RECORD_AUDIO, 2075 OPSTR_PLAY_AUDIO, 2076 OPSTR_READ_CLIPBOARD, 2077 OPSTR_WRITE_CLIPBOARD, 2078 OPSTR_TAKE_MEDIA_BUTTONS, 2079 OPSTR_TAKE_AUDIO_FOCUS, 2080 OPSTR_AUDIO_MASTER_VOLUME, 2081 OPSTR_AUDIO_VOICE_VOLUME, 2082 OPSTR_AUDIO_RING_VOLUME, 2083 OPSTR_AUDIO_MEDIA_VOLUME, 2084 OPSTR_AUDIO_ALARM_VOLUME, 2085 OPSTR_AUDIO_NOTIFICATION_VOLUME, 2086 OPSTR_AUDIO_BLUETOOTH_VOLUME, 2087 OPSTR_WAKE_LOCK, 2088 OPSTR_MONITOR_LOCATION, 2089 OPSTR_MONITOR_HIGH_POWER_LOCATION, 2090 OPSTR_GET_USAGE_STATS, 2091 OPSTR_MUTE_MICROPHONE, 2092 OPSTR_TOAST_WINDOW, 2093 OPSTR_PROJECT_MEDIA, 2094 OPSTR_ACTIVATE_VPN, 2095 OPSTR_WRITE_WALLPAPER, 2096 OPSTR_ASSIST_STRUCTURE, 2097 OPSTR_ASSIST_SCREENSHOT, 2098 OPSTR_READ_PHONE_STATE, 2099 OPSTR_ADD_VOICEMAIL, 2100 OPSTR_USE_SIP, 2101 OPSTR_PROCESS_OUTGOING_CALLS, 2102 OPSTR_USE_FINGERPRINT, 2103 OPSTR_BODY_SENSORS, 2104 OPSTR_READ_CELL_BROADCASTS, 2105 OPSTR_MOCK_LOCATION, 2106 OPSTR_READ_EXTERNAL_STORAGE, 2107 OPSTR_WRITE_EXTERNAL_STORAGE, 2108 OPSTR_TURN_SCREEN_ON, 2109 OPSTR_GET_ACCOUNTS, 2110 OPSTR_RUN_IN_BACKGROUND, 2111 OPSTR_AUDIO_ACCESSIBILITY_VOLUME, 2112 OPSTR_READ_PHONE_NUMBERS, 2113 OPSTR_REQUEST_INSTALL_PACKAGES, 2114 OPSTR_PICTURE_IN_PICTURE, 2115 OPSTR_INSTANT_APP_START_FOREGROUND, 2116 OPSTR_ANSWER_PHONE_CALLS, 2117 OPSTR_RUN_ANY_IN_BACKGROUND, 2118 OPSTR_CHANGE_WIFI_STATE, 2119 OPSTR_REQUEST_DELETE_PACKAGES, 2120 OPSTR_BIND_ACCESSIBILITY_SERVICE, 2121 OPSTR_ACCEPT_HANDOVER, 2122 OPSTR_MANAGE_IPSEC_TUNNELS, 2123 OPSTR_START_FOREGROUND, 2124 OPSTR_BLUETOOTH_SCAN, 2125 OPSTR_USE_BIOMETRIC, 2126 OPSTR_ACTIVITY_RECOGNITION, 2127 OPSTR_SMS_FINANCIAL_TRANSACTIONS, 2128 OPSTR_READ_MEDIA_AUDIO, 2129 OPSTR_WRITE_MEDIA_AUDIO, 2130 OPSTR_READ_MEDIA_VIDEO, 2131 OPSTR_WRITE_MEDIA_VIDEO, 2132 OPSTR_READ_MEDIA_IMAGES, 2133 OPSTR_WRITE_MEDIA_IMAGES, 2134 OPSTR_LEGACY_STORAGE, 2135 OPSTR_ACCESS_ACCESSIBILITY, 2136 OPSTR_READ_DEVICE_IDENTIFIERS, 2137 OPSTR_ACCESS_MEDIA_LOCATION, 2138 OPSTR_QUERY_ALL_PACKAGES, 2139 OPSTR_MANAGE_EXTERNAL_STORAGE, 2140 OPSTR_INTERACT_ACROSS_PROFILES, 2141 OPSTR_ACTIVATE_PLATFORM_VPN, 2142 OPSTR_LOADER_USAGE_STATS, 2143 "", // deprecated 2144 OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED, 2145 OPSTR_AUTO_REVOKE_MANAGED_BY_INSTALLER, 2146 OPSTR_NO_ISOLATED_STORAGE, 2147 OPSTR_PHONE_CALL_MICROPHONE, 2148 OPSTR_PHONE_CALL_CAMERA, 2149 OPSTR_RECORD_AUDIO_HOTWORD, 2150 OPSTR_MANAGE_ONGOING_CALLS, 2151 OPSTR_MANAGE_CREDENTIALS, 2152 OPSTR_USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER, 2153 OPSTR_RECORD_AUDIO_OUTPUT, 2154 OPSTR_SCHEDULE_EXACT_ALARM, 2155 OPSTR_FINE_LOCATION_SOURCE, 2156 OPSTR_COARSE_LOCATION_SOURCE, 2157 OPSTR_MANAGE_MEDIA, 2158 OPSTR_BLUETOOTH_CONNECT, 2159 OPSTR_UWB_RANGING, 2160 OPSTR_ACTIVITY_RECOGNITION_SOURCE, 2161 OPSTR_BLUETOOTH_ADVERTISE, 2162 OPSTR_RECORD_INCOMING_PHONE_AUDIO, 2163 OPSTR_NEARBY_WIFI_DEVICES, 2164 OPSTR_ESTABLISH_VPN_SERVICE, 2165 OPSTR_ESTABLISH_VPN_MANAGER, 2166 OPSTR_ACCESS_RESTRICTED_SETTINGS, 2167 OPSTR_RECEIVE_AMBIENT_TRIGGER_AUDIO, 2168 }; 2169 2170 /** 2171 * This provides a simple name for each operation to be used 2172 * in debug output. 2173 */ 2174 private static String[] sOpNames = new String[] { 2175 "COARSE_LOCATION", 2176 "FINE_LOCATION", 2177 "GPS", 2178 "VIBRATE", 2179 "READ_CONTACTS", 2180 "WRITE_CONTACTS", 2181 "READ_CALL_LOG", 2182 "WRITE_CALL_LOG", 2183 "READ_CALENDAR", 2184 "WRITE_CALENDAR", 2185 "WIFI_SCAN", 2186 "POST_NOTIFICATION", 2187 "NEIGHBORING_CELLS", 2188 "CALL_PHONE", 2189 "READ_SMS", 2190 "WRITE_SMS", 2191 "RECEIVE_SMS", 2192 "RECEIVE_EMERGECY_SMS", 2193 "RECEIVE_MMS", 2194 "RECEIVE_WAP_PUSH", 2195 "SEND_SMS", 2196 "READ_ICC_SMS", 2197 "WRITE_ICC_SMS", 2198 "WRITE_SETTINGS", 2199 "SYSTEM_ALERT_WINDOW", 2200 "ACCESS_NOTIFICATIONS", 2201 "CAMERA", 2202 "RECORD_AUDIO", 2203 "PLAY_AUDIO", 2204 "READ_CLIPBOARD", 2205 "WRITE_CLIPBOARD", 2206 "TAKE_MEDIA_BUTTONS", 2207 "TAKE_AUDIO_FOCUS", 2208 "AUDIO_MASTER_VOLUME", 2209 "AUDIO_VOICE_VOLUME", 2210 "AUDIO_RING_VOLUME", 2211 "AUDIO_MEDIA_VOLUME", 2212 "AUDIO_ALARM_VOLUME", 2213 "AUDIO_NOTIFICATION_VOLUME", 2214 "AUDIO_BLUETOOTH_VOLUME", 2215 "WAKE_LOCK", 2216 "MONITOR_LOCATION", 2217 "MONITOR_HIGH_POWER_LOCATION", 2218 "GET_USAGE_STATS", 2219 "MUTE_MICROPHONE", 2220 "TOAST_WINDOW", 2221 "PROJECT_MEDIA", 2222 "ACTIVATE_VPN", 2223 "WRITE_WALLPAPER", 2224 "ASSIST_STRUCTURE", 2225 "ASSIST_SCREENSHOT", 2226 "READ_PHONE_STATE", 2227 "ADD_VOICEMAIL", 2228 "USE_SIP", 2229 "PROCESS_OUTGOING_CALLS", 2230 "USE_FINGERPRINT", 2231 "BODY_SENSORS", 2232 "READ_CELL_BROADCASTS", 2233 "MOCK_LOCATION", 2234 "READ_EXTERNAL_STORAGE", 2235 "WRITE_EXTERNAL_STORAGE", 2236 "TURN_ON_SCREEN", 2237 "GET_ACCOUNTS", 2238 "RUN_IN_BACKGROUND", 2239 "AUDIO_ACCESSIBILITY_VOLUME", 2240 "READ_PHONE_NUMBERS", 2241 "REQUEST_INSTALL_PACKAGES", 2242 "PICTURE_IN_PICTURE", 2243 "INSTANT_APP_START_FOREGROUND", 2244 "ANSWER_PHONE_CALLS", 2245 "RUN_ANY_IN_BACKGROUND", 2246 "CHANGE_WIFI_STATE", 2247 "REQUEST_DELETE_PACKAGES", 2248 "BIND_ACCESSIBILITY_SERVICE", 2249 "ACCEPT_HANDOVER", 2250 "MANAGE_IPSEC_TUNNELS", 2251 "START_FOREGROUND", 2252 "BLUETOOTH_SCAN", 2253 "USE_BIOMETRIC", 2254 "ACTIVITY_RECOGNITION", 2255 "SMS_FINANCIAL_TRANSACTIONS", 2256 "READ_MEDIA_AUDIO", 2257 "WRITE_MEDIA_AUDIO", 2258 "READ_MEDIA_VIDEO", 2259 "WRITE_MEDIA_VIDEO", 2260 "READ_MEDIA_IMAGES", 2261 "WRITE_MEDIA_IMAGES", 2262 "LEGACY_STORAGE", 2263 "ACCESS_ACCESSIBILITY", 2264 "READ_DEVICE_IDENTIFIERS", 2265 "ACCESS_MEDIA_LOCATION", 2266 "QUERY_ALL_PACKAGES", 2267 "MANAGE_EXTERNAL_STORAGE", 2268 "INTERACT_ACROSS_PROFILES", 2269 "ACTIVATE_PLATFORM_VPN", 2270 "LOADER_USAGE_STATS", 2271 "deprecated", 2272 "AUTO_REVOKE_PERMISSIONS_IF_UNUSED", 2273 "AUTO_REVOKE_MANAGED_BY_INSTALLER", 2274 "NO_ISOLATED_STORAGE", 2275 "PHONE_CALL_MICROPHONE", 2276 "PHONE_CALL_CAMERA", 2277 "RECORD_AUDIO_HOTWORD", 2278 "MANAGE_ONGOING_CALLS", 2279 "MANAGE_CREDENTIALS", 2280 "USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER", 2281 "RECORD_AUDIO_OUTPUT", 2282 "SCHEDULE_EXACT_ALARM", 2283 "FINE_LOCATION_SOURCE", 2284 "COARSE_LOCATION_SOURCE", 2285 "MANAGE_MEDIA", 2286 "BLUETOOTH_CONNECT", 2287 "UWB_RANGING", 2288 "ACTIVITY_RECOGNITION_SOURCE", 2289 "BLUETOOTH_ADVERTISE", 2290 "RECORD_INCOMING_PHONE_AUDIO", 2291 "NEARBY_WIFI_DEVICES", 2292 "ESTABLISH_VPN_SERVICE", 2293 "ESTABLISH_VPN_MANAGER", 2294 "ACCESS_RESTRICTED_SETTINGS", 2295 "RECEIVE_SOUNDTRIGGER_AUDIO", 2296 }; 2297 2298 /** 2299 * This optionally maps a permission to an operation. If there 2300 * is no permission associated with an operation, it is null. 2301 */ 2302 @UnsupportedAppUsage 2303 private static String[] sOpPerms = new String[] { 2304 android.Manifest.permission.ACCESS_COARSE_LOCATION, 2305 android.Manifest.permission.ACCESS_FINE_LOCATION, 2306 null, 2307 android.Manifest.permission.VIBRATE, 2308 android.Manifest.permission.READ_CONTACTS, 2309 android.Manifest.permission.WRITE_CONTACTS, 2310 android.Manifest.permission.READ_CALL_LOG, 2311 android.Manifest.permission.WRITE_CALL_LOG, 2312 android.Manifest.permission.READ_CALENDAR, 2313 android.Manifest.permission.WRITE_CALENDAR, 2314 android.Manifest.permission.ACCESS_WIFI_STATE, 2315 android.Manifest.permission.POST_NOTIFICATIONS, 2316 null, // neighboring cells shares the coarse location perm 2317 android.Manifest.permission.CALL_PHONE, 2318 android.Manifest.permission.READ_SMS, 2319 null, // no permission required for writing sms 2320 android.Manifest.permission.RECEIVE_SMS, 2321 android.Manifest.permission.RECEIVE_EMERGENCY_BROADCAST, 2322 android.Manifest.permission.RECEIVE_MMS, 2323 android.Manifest.permission.RECEIVE_WAP_PUSH, 2324 android.Manifest.permission.SEND_SMS, 2325 android.Manifest.permission.READ_SMS, 2326 null, // no permission required for writing icc sms 2327 android.Manifest.permission.WRITE_SETTINGS, 2328 android.Manifest.permission.SYSTEM_ALERT_WINDOW, 2329 android.Manifest.permission.ACCESS_NOTIFICATIONS, 2330 android.Manifest.permission.CAMERA, 2331 android.Manifest.permission.RECORD_AUDIO, 2332 null, // no permission for playing audio 2333 null, // no permission for reading clipboard 2334 null, // no permission for writing clipboard 2335 null, // no permission for taking media buttons 2336 null, // no permission for taking audio focus 2337 null, // no permission for changing global volume 2338 null, // no permission for changing voice volume 2339 null, // no permission for changing ring volume 2340 null, // no permission for changing media volume 2341 null, // no permission for changing alarm volume 2342 null, // no permission for changing notification volume 2343 null, // no permission for changing bluetooth volume 2344 android.Manifest.permission.WAKE_LOCK, 2345 null, // no permission for generic location monitoring 2346 null, // no permission for high power location monitoring 2347 android.Manifest.permission.PACKAGE_USAGE_STATS, 2348 null, // no permission for muting/unmuting microphone 2349 null, // no permission for displaying toasts 2350 null, // no permission for projecting media 2351 null, // no permission for activating vpn 2352 null, // no permission for supporting wallpaper 2353 null, // no permission for receiving assist structure 2354 null, // no permission for receiving assist screenshot 2355 Manifest.permission.READ_PHONE_STATE, 2356 Manifest.permission.ADD_VOICEMAIL, 2357 Manifest.permission.USE_SIP, 2358 Manifest.permission.PROCESS_OUTGOING_CALLS, 2359 Manifest.permission.USE_FINGERPRINT, 2360 Manifest.permission.BODY_SENSORS, 2361 Manifest.permission.READ_CELL_BROADCASTS, 2362 null, 2363 Manifest.permission.READ_EXTERNAL_STORAGE, 2364 Manifest.permission.WRITE_EXTERNAL_STORAGE, 2365 null, // no permission for turning the screen on 2366 Manifest.permission.GET_ACCOUNTS, 2367 null, // no permission for running in background 2368 null, // no permission for changing accessibility volume 2369 Manifest.permission.READ_PHONE_NUMBERS, 2370 Manifest.permission.REQUEST_INSTALL_PACKAGES, 2371 null, // no permission for entering picture-in-picture on hide 2372 Manifest.permission.INSTANT_APP_FOREGROUND_SERVICE, 2373 Manifest.permission.ANSWER_PHONE_CALLS, 2374 null, // no permission for OP_RUN_ANY_IN_BACKGROUND 2375 Manifest.permission.CHANGE_WIFI_STATE, 2376 Manifest.permission.REQUEST_DELETE_PACKAGES, 2377 Manifest.permission.BIND_ACCESSIBILITY_SERVICE, 2378 Manifest.permission.ACCEPT_HANDOVER, 2379 Manifest.permission.MANAGE_IPSEC_TUNNELS, 2380 Manifest.permission.FOREGROUND_SERVICE, 2381 Manifest.permission.BLUETOOTH_SCAN, 2382 Manifest.permission.USE_BIOMETRIC, 2383 Manifest.permission.ACTIVITY_RECOGNITION, 2384 Manifest.permission.SMS_FINANCIAL_TRANSACTIONS, 2385 Manifest.permission.READ_MEDIA_AUDIO, 2386 null, // no permission for OP_WRITE_MEDIA_AUDIO 2387 Manifest.permission.READ_MEDIA_VIDEO, 2388 null, // no permission for OP_WRITE_MEDIA_VIDEO 2389 Manifest.permission.READ_MEDIA_IMAGES, 2390 null, // no permission for OP_WRITE_MEDIA_IMAGES 2391 null, // no permission for OP_LEGACY_STORAGE 2392 null, // no permission for OP_ACCESS_ACCESSIBILITY 2393 null, // no direct permission for OP_READ_DEVICE_IDENTIFIERS 2394 Manifest.permission.ACCESS_MEDIA_LOCATION, 2395 null, // no permission for OP_QUERY_ALL_PACKAGES 2396 Manifest.permission.MANAGE_EXTERNAL_STORAGE, 2397 android.Manifest.permission.INTERACT_ACROSS_PROFILES, 2398 null, // no permission for OP_ACTIVATE_PLATFORM_VPN 2399 android.Manifest.permission.LOADER_USAGE_STATS, 2400 null, // deprecated operation 2401 null, // no permission for OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED 2402 null, // no permission for OP_AUTO_REVOKE_MANAGED_BY_INSTALLER 2403 null, // no permission for OP_NO_ISOLATED_STORAGE 2404 null, // no permission for OP_PHONE_CALL_MICROPHONE 2405 null, // no permission for OP_PHONE_CALL_CAMERA 2406 null, // no permission for OP_RECORD_AUDIO_HOTWORD 2407 Manifest.permission.MANAGE_ONGOING_CALLS, 2408 null, // no permission for OP_MANAGE_CREDENTIALS 2409 Manifest.permission.USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER, 2410 null, // no permission for OP_RECORD_AUDIO_OUTPUT 2411 Manifest.permission.SCHEDULE_EXACT_ALARM, 2412 null, // no permission for OP_ACCESS_FINE_LOCATION_SOURCE, 2413 null, // no permission for OP_ACCESS_COARSE_LOCATION_SOURCE, 2414 Manifest.permission.MANAGE_MEDIA, 2415 Manifest.permission.BLUETOOTH_CONNECT, 2416 Manifest.permission.UWB_RANGING, 2417 null, // no permission for OP_ACTIVITY_RECOGNITION_SOURCE, 2418 Manifest.permission.BLUETOOTH_ADVERTISE, 2419 null, // no permission for OP_RECORD_INCOMING_PHONE_AUDIO, 2420 Manifest.permission.NEARBY_WIFI_DEVICES, 2421 null, // no permission for OP_ESTABLISH_VPN_SERVICE 2422 null, // no permission for OP_ESTABLISH_VPN_MANAGER 2423 null, // no permission for OP_ACCESS_RESTRICTED_SETTINGS, 2424 null, // no permission for OP_RECEIVE_SOUNDTRIGGER_AUDIO 2425 }; 2426 2427 /** 2428 * Specifies whether an Op should be restricted by a user restriction. 2429 * Each Op should be filled with a restriction string from UserManager or 2430 * null to specify it is not affected by any user restriction. 2431 */ 2432 private static String[] sOpRestrictions = new String[] { 2433 UserManager.DISALLOW_SHARE_LOCATION, //COARSE_LOCATION 2434 UserManager.DISALLOW_SHARE_LOCATION, //FINE_LOCATION 2435 UserManager.DISALLOW_SHARE_LOCATION, //GPS 2436 null, //VIBRATE 2437 null, //READ_CONTACTS 2438 null, //WRITE_CONTACTS 2439 UserManager.DISALLOW_OUTGOING_CALLS, //READ_CALL_LOG 2440 UserManager.DISALLOW_OUTGOING_CALLS, //WRITE_CALL_LOG 2441 null, //READ_CALENDAR 2442 null, //WRITE_CALENDAR 2443 UserManager.DISALLOW_SHARE_LOCATION, //WIFI_SCAN 2444 null, //POST_NOTIFICATION 2445 null, //NEIGHBORING_CELLS 2446 null, //CALL_PHONE 2447 UserManager.DISALLOW_SMS, //READ_SMS 2448 UserManager.DISALLOW_SMS, //WRITE_SMS 2449 UserManager.DISALLOW_SMS, //RECEIVE_SMS 2450 null, //RECEIVE_EMERGENCY_SMS 2451 UserManager.DISALLOW_SMS, //RECEIVE_MMS 2452 null, //RECEIVE_WAP_PUSH 2453 UserManager.DISALLOW_SMS, //SEND_SMS 2454 UserManager.DISALLOW_SMS, //READ_ICC_SMS 2455 UserManager.DISALLOW_SMS, //WRITE_ICC_SMS 2456 null, //WRITE_SETTINGS 2457 UserManager.DISALLOW_CREATE_WINDOWS, //SYSTEM_ALERT_WINDOW 2458 null, //ACCESS_NOTIFICATIONS 2459 UserManager.DISALLOW_CAMERA, //CAMERA 2460 UserManager.DISALLOW_RECORD_AUDIO, //RECORD_AUDIO 2461 null, //PLAY_AUDIO 2462 null, //READ_CLIPBOARD 2463 null, //WRITE_CLIPBOARD 2464 null, //TAKE_MEDIA_BUTTONS 2465 null, //TAKE_AUDIO_FOCUS 2466 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MASTER_VOLUME 2467 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_VOICE_VOLUME 2468 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_RING_VOLUME 2469 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MEDIA_VOLUME 2470 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ALARM_VOLUME 2471 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_NOTIFICATION_VOLUME 2472 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_BLUETOOTH_VOLUME 2473 null, //WAKE_LOCK 2474 UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_LOCATION 2475 UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_HIGH_POWER_LOCATION 2476 null, //GET_USAGE_STATS 2477 UserManager.DISALLOW_UNMUTE_MICROPHONE, // MUTE_MICROPHONE 2478 UserManager.DISALLOW_CREATE_WINDOWS, // TOAST_WINDOW 2479 null, //PROJECT_MEDIA 2480 null, // ACTIVATE_VPN 2481 UserManager.DISALLOW_WALLPAPER, // WRITE_WALLPAPER 2482 null, // ASSIST_STRUCTURE 2483 null, // ASSIST_SCREENSHOT 2484 null, // READ_PHONE_STATE 2485 null, // ADD_VOICEMAIL 2486 null, // USE_SIP 2487 null, // PROCESS_OUTGOING_CALLS 2488 null, // USE_FINGERPRINT 2489 null, // BODY_SENSORS 2490 null, // READ_CELL_BROADCASTS 2491 null, // MOCK_LOCATION 2492 null, // READ_EXTERNAL_STORAGE 2493 null, // WRITE_EXTERNAL_STORAGE 2494 null, // TURN_ON_SCREEN 2495 null, // GET_ACCOUNTS 2496 null, // RUN_IN_BACKGROUND 2497 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ACCESSIBILITY_VOLUME 2498 null, // READ_PHONE_NUMBERS 2499 null, // REQUEST_INSTALL_PACKAGES 2500 null, // ENTER_PICTURE_IN_PICTURE_ON_HIDE 2501 null, // INSTANT_APP_START_FOREGROUND 2502 null, // ANSWER_PHONE_CALLS 2503 null, // OP_RUN_ANY_IN_BACKGROUND 2504 null, // OP_CHANGE_WIFI_STATE 2505 null, // REQUEST_DELETE_PACKAGES 2506 null, // OP_BIND_ACCESSIBILITY_SERVICE 2507 null, // ACCEPT_HANDOVER 2508 null, // MANAGE_IPSEC_TUNNELS 2509 null, // START_FOREGROUND 2510 null, // maybe should be UserManager.DISALLOW_SHARE_LOCATION, //BLUETOOTH_SCAN 2511 null, // USE_BIOMETRIC 2512 null, // ACTIVITY_RECOGNITION 2513 UserManager.DISALLOW_SMS, // SMS_FINANCIAL_TRANSACTIONS 2514 null, // READ_MEDIA_AUDIO 2515 null, // WRITE_MEDIA_AUDIO 2516 null, // READ_MEDIA_VIDEO 2517 null, // WRITE_MEDIA_VIDEO 2518 null, // READ_MEDIA_IMAGES 2519 null, // WRITE_MEDIA_IMAGES 2520 null, // LEGACY_STORAGE 2521 null, // ACCESS_ACCESSIBILITY 2522 null, // READ_DEVICE_IDENTIFIERS 2523 null, // ACCESS_MEDIA_LOCATION 2524 null, // QUERY_ALL_PACKAGES 2525 null, // MANAGE_EXTERNAL_STORAGE 2526 null, // INTERACT_ACROSS_PROFILES 2527 null, // ACTIVATE_PLATFORM_VPN 2528 null, // LOADER_USAGE_STATS 2529 null, // deprecated operation 2530 null, // AUTO_REVOKE_PERMISSIONS_IF_UNUSED 2531 null, // AUTO_REVOKE_MANAGED_BY_INSTALLER 2532 null, // NO_ISOLATED_STORAGE 2533 null, // PHONE_CALL_MICROPHONE 2534 null, // PHONE_CALL_MICROPHONE 2535 null, // RECORD_AUDIO_HOTWORD 2536 null, // MANAGE_ONGOING_CALLS 2537 null, // MANAGE_CREDENTIALS 2538 null, // USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER 2539 null, // RECORD_AUDIO_OUTPUT 2540 null, // SCHEDULE_EXACT_ALARM 2541 null, // ACCESS_FINE_LOCATION_SOURCE 2542 null, // ACCESS_COARSE_LOCATION_SOURCE 2543 null, // MANAGE_MEDIA 2544 null, // BLUETOOTH_CONNECT 2545 null, // UWB_RANGING 2546 null, // ACTIVITY_RECOGNITION_SOURCE 2547 null, // BLUETOOTH_ADVERTISE 2548 null, // RECORD_INCOMING_PHONE_AUDIO 2549 null, // NEARBY_WIFI_DEVICES 2550 null, // ESTABLISH_VPN_SERVICE 2551 null, // ESTABLISH_VPN_MANAGER 2552 null, // ACCESS_RESTRICTED_SETTINGS 2553 null, // RECEIVE_SOUNDTRIGGER_AUDIO 2554 }; 2555 2556 /** 2557 * In which cases should an app be allowed to bypass the {@link #setUserRestriction user 2558 * restriction} for a certain app-op. 2559 */ 2560 private static RestrictionBypass[] sOpAllowSystemRestrictionBypass = new RestrictionBypass[] { 2561 new RestrictionBypass(true, false, false), //COARSE_LOCATION 2562 new RestrictionBypass(true, false, false), //FINE_LOCATION 2563 null, //GPS 2564 null, //VIBRATE 2565 null, //READ_CONTACTS 2566 null, //WRITE_CONTACTS 2567 null, //READ_CALL_LOG 2568 null, //WRITE_CALL_LOG 2569 null, //READ_CALENDAR 2570 null, //WRITE_CALENDAR 2571 new RestrictionBypass(false, true, false), //WIFI_SCAN 2572 null, //POST_NOTIFICATION 2573 null, //NEIGHBORING_CELLS 2574 null, //CALL_PHONE 2575 null, //READ_SMS 2576 null, //WRITE_SMS 2577 null, //RECEIVE_SMS 2578 null, //RECEIVE_EMERGECY_SMS 2579 null, //RECEIVE_MMS 2580 null, //RECEIVE_WAP_PUSH 2581 null, //SEND_SMS 2582 null, //READ_ICC_SMS 2583 null, //WRITE_ICC_SMS 2584 null, //WRITE_SETTINGS 2585 new RestrictionBypass(false, true, false), //SYSTEM_ALERT_WINDOW 2586 null, //ACCESS_NOTIFICATIONS 2587 null, //CAMERA 2588 new RestrictionBypass(false, false, true), //RECORD_AUDIO 2589 null, //PLAY_AUDIO 2590 null, //READ_CLIPBOARD 2591 null, //WRITE_CLIPBOARD 2592 null, //TAKE_MEDIA_BUTTONS 2593 null, //TAKE_AUDIO_FOCUS 2594 null, //AUDIO_MASTER_VOLUME 2595 null, //AUDIO_VOICE_VOLUME 2596 null, //AUDIO_RING_VOLUME 2597 null, //AUDIO_MEDIA_VOLUME 2598 null, //AUDIO_ALARM_VOLUME 2599 null, //AUDIO_NOTIFICATION_VOLUME 2600 null, //AUDIO_BLUETOOTH_VOLUME 2601 null, //WAKE_LOCK 2602 null, //MONITOR_LOCATION 2603 null, //MONITOR_HIGH_POWER_LOCATION 2604 null, //GET_USAGE_STATS 2605 null, //MUTE_MICROPHONE 2606 new RestrictionBypass(false, true, false), //TOAST_WINDOW 2607 null, //PROJECT_MEDIA 2608 null, //ACTIVATE_VPN 2609 null, //WALLPAPER 2610 null, //ASSIST_STRUCTURE 2611 null, //ASSIST_SCREENSHOT 2612 null, //READ_PHONE_STATE 2613 null, //ADD_VOICEMAIL 2614 null, // USE_SIP 2615 null, // PROCESS_OUTGOING_CALLS 2616 null, // USE_FINGERPRINT 2617 null, // BODY_SENSORS 2618 null, // READ_CELL_BROADCASTS 2619 null, // MOCK_LOCATION 2620 null, // READ_EXTERNAL_STORAGE 2621 null, // WRITE_EXTERNAL_STORAGE 2622 null, // TURN_ON_SCREEN 2623 null, // GET_ACCOUNTS 2624 null, // RUN_IN_BACKGROUND 2625 null, // AUDIO_ACCESSIBILITY_VOLUME 2626 null, // READ_PHONE_NUMBERS 2627 null, // REQUEST_INSTALL_PACKAGES 2628 null, // ENTER_PICTURE_IN_PICTURE_ON_HIDE 2629 null, // INSTANT_APP_START_FOREGROUND 2630 null, // ANSWER_PHONE_CALLS 2631 null, // OP_RUN_ANY_IN_BACKGROUND 2632 null, // OP_CHANGE_WIFI_STATE 2633 null, // OP_REQUEST_DELETE_PACKAGES 2634 null, // OP_BIND_ACCESSIBILITY_SERVICE 2635 null, // ACCEPT_HANDOVER 2636 null, // MANAGE_IPSEC_HANDOVERS 2637 null, // START_FOREGROUND 2638 new RestrictionBypass(false, true, false), // BLUETOOTH_SCAN 2639 null, // USE_BIOMETRIC 2640 null, // ACTIVITY_RECOGNITION 2641 null, // SMS_FINANCIAL_TRANSACTIONS 2642 null, // READ_MEDIA_AUDIO 2643 null, // WRITE_MEDIA_AUDIO 2644 null, // READ_MEDIA_VIDEO 2645 null, // WRITE_MEDIA_VIDEO 2646 null, // READ_MEDIA_IMAGES 2647 null, // WRITE_MEDIA_IMAGES 2648 null, // LEGACY_STORAGE 2649 null, // ACCESS_ACCESSIBILITY 2650 null, // READ_DEVICE_IDENTIFIERS 2651 null, // ACCESS_MEDIA_LOCATION 2652 null, // QUERY_ALL_PACKAGES 2653 null, // MANAGE_EXTERNAL_STORAGE 2654 null, // INTERACT_ACROSS_PROFILES 2655 null, // ACTIVATE_PLATFORM_VPN 2656 null, // LOADER_USAGE_STATS 2657 null, // deprecated operation 2658 null, // AUTO_REVOKE_PERMISSIONS_IF_UNUSED 2659 null, // AUTO_REVOKE_MANAGED_BY_INSTALLER 2660 null, // NO_ISOLATED_STORAGE 2661 null, // PHONE_CALL_MICROPHONE 2662 null, // PHONE_CALL_CAMERA 2663 null, // RECORD_AUDIO_HOTWORD 2664 null, // MANAGE_ONGOING_CALLS 2665 null, // MANAGE_CREDENTIALS 2666 null, // USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER 2667 null, // RECORD_AUDIO_OUTPUT 2668 null, // SCHEDULE_EXACT_ALARM 2669 null, // ACCESS_FINE_LOCATION_SOURCE 2670 null, // ACCESS_COARSE_LOCATION_SOURCE 2671 null, // MANAGE_MEDIA 2672 null, // BLUETOOTH_CONNECT 2673 null, // UWB_RANGING 2674 null, // ACTIVITY_RECOGNITION_SOURCE 2675 null, // BLUETOOTH_ADVERTISE 2676 null, // RECORD_INCOMING_PHONE_AUDIO 2677 null, // NEARBY_WIFI_DEVICES 2678 null, // ESTABLISH_VPN_SERVICE 2679 null, // ESTABLISH_VPN_MANAGER 2680 null, // ACCESS_RESTRICTED_SETTINGS 2681 null, // RECEIVE_SOUNDTRIGGER_AUDIO 2682 }; 2683 2684 /** 2685 * This specifies the default mode for each operation. 2686 */ 2687 private static int[] sOpDefaultMode = new int[] { 2688 AppOpsManager.MODE_ALLOWED, // COARSE_LOCATION 2689 AppOpsManager.MODE_ALLOWED, // FINE_LOCATION 2690 AppOpsManager.MODE_ALLOWED, // GPS 2691 AppOpsManager.MODE_ALLOWED, // VIBRATE 2692 AppOpsManager.MODE_ALLOWED, // READ_CONTACTS 2693 AppOpsManager.MODE_ALLOWED, // WRITE_CONTACTS 2694 AppOpsManager.MODE_ALLOWED, // READ_CALL_LOG 2695 AppOpsManager.MODE_ALLOWED, // WRITE_CALL_LOG 2696 AppOpsManager.MODE_ALLOWED, // READ_CALENDAR 2697 AppOpsManager.MODE_ALLOWED, // WRITE_CALENDAR 2698 AppOpsManager.MODE_ALLOWED, // WIFI_SCAN 2699 AppOpsManager.MODE_ALLOWED, // POST_NOTIFICATION 2700 AppOpsManager.MODE_ALLOWED, // NEIGHBORING_CELLS 2701 AppOpsManager.MODE_ALLOWED, // CALL_PHONE 2702 AppOpsManager.MODE_ALLOWED, // READ_SMS 2703 AppOpsManager.MODE_IGNORED, // WRITE_SMS 2704 AppOpsManager.MODE_ALLOWED, // RECEIVE_SMS 2705 AppOpsManager.MODE_ALLOWED, // RECEIVE_EMERGENCY_BROADCAST 2706 AppOpsManager.MODE_ALLOWED, // RECEIVE_MMS 2707 AppOpsManager.MODE_ALLOWED, // RECEIVE_WAP_PUSH 2708 AppOpsManager.MODE_ALLOWED, // SEND_SMS 2709 AppOpsManager.MODE_ALLOWED, // READ_ICC_SMS 2710 AppOpsManager.MODE_ALLOWED, // WRITE_ICC_SMS 2711 AppOpsManager.MODE_DEFAULT, // WRITE_SETTINGS 2712 getSystemAlertWindowDefault(), // SYSTEM_ALERT_WINDOW 2713 AppOpsManager.MODE_ALLOWED, // ACCESS_NOTIFICATIONS 2714 AppOpsManager.MODE_ALLOWED, // CAMERA 2715 AppOpsManager.MODE_ALLOWED, // RECORD_AUDIO 2716 AppOpsManager.MODE_ALLOWED, // PLAY_AUDIO 2717 AppOpsManager.MODE_ALLOWED, // READ_CLIPBOARD 2718 AppOpsManager.MODE_ALLOWED, // WRITE_CLIPBOARD 2719 AppOpsManager.MODE_ALLOWED, // TAKE_MEDIA_BUTTONS 2720 AppOpsManager.MODE_ALLOWED, // TAKE_AUDIO_FOCUS 2721 AppOpsManager.MODE_ALLOWED, // AUDIO_MASTER_VOLUME 2722 AppOpsManager.MODE_ALLOWED, // AUDIO_VOICE_VOLUME 2723 AppOpsManager.MODE_ALLOWED, // AUDIO_RING_VOLUME 2724 AppOpsManager.MODE_ALLOWED, // AUDIO_MEDIA_VOLUME 2725 AppOpsManager.MODE_ALLOWED, // AUDIO_ALARM_VOLUME 2726 AppOpsManager.MODE_ALLOWED, // AUDIO_NOTIFICATION_VOLUME 2727 AppOpsManager.MODE_ALLOWED, // AUDIO_BLUETOOTH_VOLUME 2728 AppOpsManager.MODE_ALLOWED, // WAKE_LOCK 2729 AppOpsManager.MODE_ALLOWED, // MONITOR_LOCATION 2730 AppOpsManager.MODE_ALLOWED, // MONITOR_HIGH_POWER_LOCATION 2731 AppOpsManager.MODE_DEFAULT, // GET_USAGE_STATS 2732 AppOpsManager.MODE_ALLOWED, // MUTE_MICROPHONE 2733 AppOpsManager.MODE_ALLOWED, // TOAST_WINDOW 2734 AppOpsManager.MODE_IGNORED, // PROJECT_MEDIA 2735 AppOpsManager.MODE_IGNORED, // ACTIVATE_VPN 2736 AppOpsManager.MODE_ALLOWED, // WRITE_WALLPAPER 2737 AppOpsManager.MODE_ALLOWED, // ASSIST_STRUCTURE 2738 AppOpsManager.MODE_ALLOWED, // ASSIST_SCREENSHOT 2739 AppOpsManager.MODE_ALLOWED, // READ_PHONE_STATE 2740 AppOpsManager.MODE_ALLOWED, // ADD_VOICEMAIL 2741 AppOpsManager.MODE_ALLOWED, // USE_SIP 2742 AppOpsManager.MODE_ALLOWED, // PROCESS_OUTGOING_CALLS 2743 AppOpsManager.MODE_ALLOWED, // USE_FINGERPRINT 2744 AppOpsManager.MODE_ALLOWED, // BODY_SENSORS 2745 AppOpsManager.MODE_ALLOWED, // READ_CELL_BROADCASTS 2746 AppOpsManager.MODE_ERRORED, // MOCK_LOCATION 2747 AppOpsManager.MODE_ALLOWED, // READ_EXTERNAL_STORAGE 2748 AppOpsManager.MODE_ALLOWED, // WRITE_EXTERNAL_STORAGE 2749 AppOpsManager.MODE_ALLOWED, // TURN_SCREEN_ON 2750 AppOpsManager.MODE_ALLOWED, // GET_ACCOUNTS 2751 AppOpsManager.MODE_ALLOWED, // RUN_IN_BACKGROUND 2752 AppOpsManager.MODE_ALLOWED, // AUDIO_ACCESSIBILITY_VOLUME 2753 AppOpsManager.MODE_ALLOWED, // READ_PHONE_NUMBERS 2754 AppOpsManager.MODE_DEFAULT, // REQUEST_INSTALL_PACKAGES 2755 AppOpsManager.MODE_ALLOWED, // PICTURE_IN_PICTURE 2756 AppOpsManager.MODE_DEFAULT, // INSTANT_APP_START_FOREGROUND 2757 AppOpsManager.MODE_ALLOWED, // ANSWER_PHONE_CALLS 2758 AppOpsManager.MODE_ALLOWED, // RUN_ANY_IN_BACKGROUND 2759 AppOpsManager.MODE_ALLOWED, // CHANGE_WIFI_STATE 2760 AppOpsManager.MODE_ALLOWED, // REQUEST_DELETE_PACKAGES 2761 AppOpsManager.MODE_ALLOWED, // BIND_ACCESSIBILITY_SERVICE 2762 AppOpsManager.MODE_ALLOWED, // ACCEPT_HANDOVER 2763 AppOpsManager.MODE_ERRORED, // MANAGE_IPSEC_TUNNELS 2764 AppOpsManager.MODE_ALLOWED, // START_FOREGROUND 2765 AppOpsManager.MODE_ALLOWED, // BLUETOOTH_SCAN 2766 AppOpsManager.MODE_ALLOWED, // USE_BIOMETRIC 2767 AppOpsManager.MODE_ALLOWED, // ACTIVITY_RECOGNITION 2768 AppOpsManager.MODE_DEFAULT, // SMS_FINANCIAL_TRANSACTIONS 2769 AppOpsManager.MODE_ALLOWED, // READ_MEDIA_AUDIO 2770 AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_AUDIO 2771 AppOpsManager.MODE_ALLOWED, // READ_MEDIA_VIDEO 2772 AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_VIDEO 2773 AppOpsManager.MODE_ALLOWED, // READ_MEDIA_IMAGES 2774 AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_IMAGES 2775 AppOpsManager.MODE_DEFAULT, // LEGACY_STORAGE 2776 AppOpsManager.MODE_ALLOWED, // ACCESS_ACCESSIBILITY 2777 AppOpsManager.MODE_ERRORED, // READ_DEVICE_IDENTIFIERS 2778 AppOpsManager.MODE_ALLOWED, // ALLOW_MEDIA_LOCATION 2779 AppOpsManager.MODE_DEFAULT, // QUERY_ALL_PACKAGES 2780 AppOpsManager.MODE_DEFAULT, // MANAGE_EXTERNAL_STORAGE 2781 AppOpsManager.MODE_DEFAULT, // INTERACT_ACROSS_PROFILES 2782 AppOpsManager.MODE_IGNORED, // ACTIVATE_PLATFORM_VPN 2783 AppOpsManager.MODE_DEFAULT, // LOADER_USAGE_STATS 2784 AppOpsManager.MODE_IGNORED, // deprecated operation 2785 AppOpsManager.MODE_DEFAULT, // OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED 2786 AppOpsManager.MODE_ALLOWED, // OP_AUTO_REVOKE_MANAGED_BY_INSTALLER 2787 AppOpsManager.MODE_ERRORED, // OP_NO_ISOLATED_STORAGE 2788 AppOpsManager.MODE_ALLOWED, // PHONE_CALL_MICROPHONE 2789 AppOpsManager.MODE_ALLOWED, // PHONE_CALL_CAMERA 2790 AppOpsManager.MODE_ALLOWED, // RECORD_AUDIO_HOTWORD 2791 AppOpsManager.MODE_DEFAULT, // MANAGE_ONGOING_CALLS 2792 AppOpsManager.MODE_DEFAULT, // MANAGE_CREDENTIALS 2793 AppOpsManager.MODE_DEFAULT, // USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER 2794 AppOpsManager.MODE_ALLOWED, // RECORD_AUDIO_OUTPUT 2795 AppOpsManager.MODE_DEFAULT, // SCHEDULE_EXACT_ALARM 2796 AppOpsManager.MODE_ALLOWED, // ACCESS_FINE_LOCATION_SOURCE 2797 AppOpsManager.MODE_ALLOWED, // ACCESS_COARSE_LOCATION_SOURCE 2798 AppOpsManager.MODE_DEFAULT, // MANAGE_MEDIA 2799 AppOpsManager.MODE_ALLOWED, // BLUETOOTH_CONNECT 2800 AppOpsManager.MODE_ALLOWED, // UWB_RANGING 2801 AppOpsManager.MODE_ALLOWED, // ACTIVITY_RECOGNITION_SOURCE 2802 AppOpsManager.MODE_ALLOWED, // BLUETOOTH_ADVERTISE 2803 AppOpsManager.MODE_ALLOWED, // RECORD_INCOMING_PHONE_AUDIO 2804 AppOpsManager.MODE_ALLOWED, // NEARBY_WIFI_DEVICES 2805 AppOpsManager.MODE_ALLOWED, // ESTABLISH_VPN_SERVICE 2806 AppOpsManager.MODE_ALLOWED, // ESTABLISH_VPN_MANAGER 2807 AppOpsManager.MODE_ALLOWED, // ACCESS_RESTRICTED_SETTINGS, 2808 AppOpsManager.MODE_ALLOWED, // RECEIVE_SOUNDTRIGGER_AUDIO 2809 }; 2810 2811 /** 2812 * This specifies whether each option is allowed to be reset 2813 * when resetting all app preferences. Disable reset for 2814 * app ops that are under strong control of some part of the 2815 * system (such as OP_WRITE_SMS, which should be allowed only 2816 * for whichever app is selected as the current SMS app). 2817 */ 2818 private static boolean[] sOpDisableReset = new boolean[] { 2819 false, // COARSE_LOCATION 2820 false, // FINE_LOCATION 2821 false, // GPS 2822 false, // VIBRATE 2823 false, // READ_CONTACTS 2824 false, // WRITE_CONTACTS 2825 false, // READ_CALL_LOG 2826 false, // WRITE_CALL_LOG 2827 false, // READ_CALENDAR 2828 false, // WRITE_CALENDAR 2829 false, // WIFI_SCAN 2830 false, // POST_NOTIFICATION 2831 false, // NEIGHBORING_CELLS 2832 false, // CALL_PHONE 2833 true, // READ_SMS 2834 true, // WRITE_SMS 2835 true, // RECEIVE_SMS 2836 false, // RECEIVE_EMERGENCY_BROADCAST 2837 false, // RECEIVE_MMS 2838 true, // RECEIVE_WAP_PUSH 2839 true, // SEND_SMS 2840 false, // READ_ICC_SMS 2841 false, // WRITE_ICC_SMS 2842 false, // WRITE_SETTINGS 2843 false, // SYSTEM_ALERT_WINDOW 2844 false, // ACCESS_NOTIFICATIONS 2845 false, // CAMERA 2846 false, // RECORD_AUDIO 2847 false, // PLAY_AUDIO 2848 false, // READ_CLIPBOARD 2849 false, // WRITE_CLIPBOARD 2850 false, // TAKE_MEDIA_BUTTONS 2851 false, // TAKE_AUDIO_FOCUS 2852 false, // AUDIO_MASTER_VOLUME 2853 false, // AUDIO_VOICE_VOLUME 2854 false, // AUDIO_RING_VOLUME 2855 false, // AUDIO_MEDIA_VOLUME 2856 false, // AUDIO_ALARM_VOLUME 2857 false, // AUDIO_NOTIFICATION_VOLUME 2858 false, // AUDIO_BLUETOOTH_VOLUME 2859 false, // WAKE_LOCK 2860 false, // MONITOR_LOCATION 2861 false, // MONITOR_HIGH_POWER_LOCATION 2862 false, // GET_USAGE_STATS 2863 false, // MUTE_MICROPHONE 2864 false, // TOAST_WINDOW 2865 false, // PROJECT_MEDIA 2866 false, // ACTIVATE_VPN 2867 false, // WRITE_WALLPAPER 2868 false, // ASSIST_STRUCTURE 2869 false, // ASSIST_SCREENSHOT 2870 false, // READ_PHONE_STATE 2871 false, // ADD_VOICEMAIL 2872 false, // USE_SIP 2873 false, // PROCESS_OUTGOING_CALLS 2874 false, // USE_FINGERPRINT 2875 false, // BODY_SENSORS 2876 true, // READ_CELL_BROADCASTS 2877 false, // MOCK_LOCATION 2878 false, // READ_EXTERNAL_STORAGE 2879 false, // WRITE_EXTERNAL_STORAGE 2880 false, // TURN_SCREEN_ON 2881 false, // GET_ACCOUNTS 2882 false, // RUN_IN_BACKGROUND 2883 false, // AUDIO_ACCESSIBILITY_VOLUME 2884 false, // READ_PHONE_NUMBERS 2885 false, // REQUEST_INSTALL_PACKAGES 2886 false, // PICTURE_IN_PICTURE 2887 false, // INSTANT_APP_START_FOREGROUND 2888 false, // ANSWER_PHONE_CALLS 2889 false, // RUN_ANY_IN_BACKGROUND 2890 false, // CHANGE_WIFI_STATE 2891 false, // REQUEST_DELETE_PACKAGES 2892 false, // BIND_ACCESSIBILITY_SERVICE 2893 false, // ACCEPT_HANDOVER 2894 false, // MANAGE_IPSEC_TUNNELS 2895 false, // START_FOREGROUND 2896 false, // BLUETOOTH_SCAN 2897 false, // USE_BIOMETRIC 2898 false, // ACTIVITY_RECOGNITION 2899 false, // SMS_FINANCIAL_TRANSACTIONS 2900 false, // READ_MEDIA_AUDIO 2901 false, // WRITE_MEDIA_AUDIO 2902 false, // READ_MEDIA_VIDEO 2903 true, // WRITE_MEDIA_VIDEO 2904 false, // READ_MEDIA_IMAGES 2905 true, // WRITE_MEDIA_IMAGES 2906 true, // LEGACY_STORAGE 2907 false, // ACCESS_ACCESSIBILITY 2908 false, // READ_DEVICE_IDENTIFIERS 2909 false, // ACCESS_MEDIA_LOCATION 2910 false, // QUERY_ALL_PACKAGES 2911 false, // MANAGE_EXTERNAL_STORAGE 2912 false, // INTERACT_ACROSS_PROFILES 2913 false, // ACTIVATE_PLATFORM_VPN 2914 false, // LOADER_USAGE_STATS 2915 false, // deprecated operation 2916 false, // AUTO_REVOKE_PERMISSIONS_IF_UNUSED 2917 false, // AUTO_REVOKE_MANAGED_BY_INSTALLER 2918 true, // NO_ISOLATED_STORAGE 2919 false, // PHONE_CALL_MICROPHONE 2920 false, // PHONE_CALL_CAMERA 2921 false, // RECORD_AUDIO_HOTWORD 2922 true, // MANAGE_ONGOING_CALLS 2923 false, // MANAGE_CREDENTIALS 2924 true, // USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER 2925 false, // RECORD_AUDIO_OUTPUT 2926 false, // SCHEDULE_EXACT_ALARM 2927 false, // ACCESS_FINE_LOCATION_SOURCE 2928 false, // ACCESS_COARSE_LOCATION_SOURCE 2929 false, // MANAGE_MEDIA 2930 false, // BLUETOOTH_CONNECT 2931 false, // UWB_RANGING 2932 false, // ACTIVITY_RECOGNITION_SOURCE 2933 false, // BLUETOOTH_ADVERTISE 2934 false, // RECORD_INCOMING_PHONE_AUDIO 2935 false, // NEARBY_WIFI_DEVICES 2936 false, // OP_ESTABLISH_VPN_SERVICE 2937 false, // OP_ESTABLISH_VPN_MANAGER 2938 true, // ACCESS_RESTRICTED_SETTINGS 2939 false, // RECEIVE_SOUNDTRIGGER_AUDIO 2940 }; 2941 2942 /** 2943 * This specifies whether each option is only allowed to be read 2944 * by apps with manage appops permission. 2945 */ 2946 private static boolean[] sOpRestrictRead = new boolean[] { 2947 false, // COARSE_LOCATION 2948 false, // FINE_LOCATION 2949 false, // GPS 2950 false, // VIBRATE 2951 false, // READ_CONTACTS 2952 false, // WRITE_CONTACTS 2953 false, // READ_CALL_LOG 2954 false, // WRITE_CALL_LOG 2955 false, // READ_CALENDAR 2956 false, // WRITE_CALENDAR 2957 false, // WIFI_SCAN 2958 false, // POST_NOTIFICATION 2959 false, // NEIGHBORING_CELLS 2960 false, // CALL_PHONE 2961 false, // READ_SMS 2962 false, // WRITE_SMS 2963 false, // RECEIVE_SMS 2964 false, // RECEIVE_EMERGENCY_BROADCAST 2965 false, // RECEIVE_MMS 2966 false, // RECEIVE_WAP_PUSH 2967 false, // SEND_SMS 2968 false, // READ_ICC_SMS 2969 false, // WRITE_ICC_SMS 2970 false, // WRITE_SETTINGS 2971 false, // SYSTEM_ALERT_WINDOW 2972 false, // ACCESS_NOTIFICATIONS 2973 false, // CAMERA 2974 false, // RECORD_AUDIO 2975 false, // PLAY_AUDIO 2976 false, // READ_CLIPBOARD 2977 false, // WRITE_CLIPBOARD 2978 false, // TAKE_MEDIA_BUTTONS 2979 false, // TAKE_AUDIO_FOCUS 2980 false, // AUDIO_MASTER_VOLUME 2981 false, // AUDIO_VOICE_VOLUME 2982 false, // AUDIO_RING_VOLUME 2983 false, // AUDIO_MEDIA_VOLUME 2984 false, // AUDIO_ALARM_VOLUME 2985 false, // AUDIO_NOTIFICATION_VOLUME 2986 false, // AUDIO_BLUETOOTH_VOLUME 2987 false, // WAKE_LOCK 2988 false, // MONITOR_LOCATION 2989 false, // MONITOR_HIGH_POWER_LOCATION 2990 false, // GET_USAGE_STATS 2991 false, // MUTE_MICROPHONE 2992 false, // TOAST_WINDOW 2993 false, // PROJECT_MEDIA 2994 false, // ACTIVATE_VPN 2995 false, // WRITE_WALLPAPER 2996 false, // ASSIST_STRUCTURE 2997 false, // ASSIST_SCREENSHOT 2998 false, // READ_PHONE_STATE 2999 false, // ADD_VOICEMAIL 3000 false, // USE_SIP 3001 false, // PROCESS_OUTGOING_CALLS 3002 false, // USE_FINGERPRINT 3003 false, // BODY_SENSORS 3004 false, // READ_CELL_BROADCASTS 3005 false, // MOCK_LOCATION 3006 false, // READ_EXTERNAL_STORAGE 3007 false, // WRITE_EXTERNAL_STORAGE 3008 false, // TURN_SCREEN_ON 3009 false, // GET_ACCOUNTS 3010 false, // RUN_IN_BACKGROUND 3011 false, // AUDIO_ACCESSIBILITY_VOLUME 3012 false, // READ_PHONE_NUMBERS 3013 false, // REQUEST_INSTALL_PACKAGES 3014 false, // PICTURE_IN_PICTURE 3015 false, // INSTANT_APP_START_FOREGROUND 3016 false, // ANSWER_PHONE_CALLS 3017 false, // RUN_ANY_IN_BACKGROUND 3018 false, // CHANGE_WIFI_STATE 3019 false, // REQUEST_DELETE_PACKAGES 3020 false, // BIND_ACCESSIBILITY_SERVICE 3021 false, // ACCEPT_HANDOVER 3022 false, // MANAGE_IPSEC_TUNNELS 3023 false, // START_FOREGROUND 3024 false, // BLUETOOTH_SCAN 3025 false, // USE_BIOMETRIC 3026 false, // ACTIVITY_RECOGNITION 3027 false, // SMS_FINANCIAL_TRANSACTIONS 3028 false, // READ_MEDIA_AUDIO 3029 false, // WRITE_MEDIA_AUDIO 3030 false, // READ_MEDIA_VIDEO 3031 false, // WRITE_MEDIA_VIDEO 3032 false, // READ_MEDIA_IMAGES 3033 false, // WRITE_MEDIA_IMAGES 3034 false, // LEGACY_STORAGE 3035 false, // ACCESS_ACCESSIBILITY 3036 false, // READ_DEVICE_IDENTIFIERS 3037 false, // ACCESS_MEDIA_LOCATION 3038 false, // QUERY_ALL_PACKAGES 3039 false, // MANAGE_EXTERNAL_STORAGE 3040 false, // INTERACT_ACROSS_PROFILES 3041 false, // ACTIVATE_PLATFORM_VPN 3042 false, // LOADER_USAGE_STATS 3043 false, // deprecated operation 3044 false, // AUTO_REVOKE_PERMISSIONS_IF_UNUSED 3045 false, // AUTO_REVOKE_MANAGED_BY_INSTALLER 3046 false, // NO_ISOLATED_STORAGE 3047 false, // PHONE_CALL_MICROPHONE 3048 false, // PHONE_CALL_CAMERA 3049 false, // RECORD_AUDIO_HOTWORD 3050 false, // MANAGE_ONGOING_CALLS 3051 false, // MANAGE_CREDENTIALS 3052 false, // USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER 3053 false, // RECORD_AUDIO_OUTPUT 3054 false, // SCHEDULE_EXACT_ALARM 3055 false, // ACCESS_FINE_LOCATION_SOURCE 3056 false, // ACCESS_COARSE_LOCATION_SOURCE 3057 false, // MANAGE_MEDIA 3058 false, // BLUETOOTH_CONNECT 3059 false, // UWB_RANGING 3060 false, // ACTIVITY_RECOGNITION_SOURCE 3061 false, // BLUETOOTH_ADVERTISE 3062 false, // RECORD_INCOMING_PHONE_AUDIO 3063 false, // NEARBY_WIFI_DEVICES 3064 false, // OP_ESTABLISH_VPN_SERVICE 3065 false, // OP_ESTABLISH_VPN_MANAGER 3066 true, // ACCESS_RESTRICTED_SETTINGS 3067 false, // RECEIVE_SOUNDTRIGGER_AUDIO 3068 }; 3069 3070 /** 3071 * Mapping from an app op name to the app op code. 3072 */ 3073 private static HashMap<String, Integer> sOpStrToOp = new HashMap<>(); 3074 3075 /** 3076 * Mapping from a permission to the corresponding app op. 3077 */ 3078 private static HashMap<String, Integer> sPermToOp = new HashMap<>(); 3079 3080 /** 3081 * Set to the uid of the caller if this thread is currently executing a two-way binder 3082 * transaction. Not set if this thread is currently not executing a two way binder transaction. 3083 * 3084 * @see #startNotedAppOpsCollection 3085 * @see #getNotedOpCollectionMode 3086 */ 3087 private static final ThreadLocal<Integer> sBinderThreadCallingUid = new ThreadLocal<>(); 3088 3089 /** 3090 * If a thread is currently executing a two-way binder transaction, this stores the op-codes of 3091 * the app-ops that were noted during this transaction. 3092 * 3093 * @see #getNotedOpCollectionMode 3094 * @see #collectNotedOpSync 3095 */ 3096 private static final ThreadLocal<ArrayMap<String, long[]>> sAppOpsNotedInThisBinderTransaction = 3097 new ThreadLocal<>(); 3098 3099 /** Whether noting for an appop should be collected */ 3100 private static final @ShouldCollectNoteOp byte[] sAppOpsToNote = new byte[_NUM_OP]; 3101 3102 static { 3103 if (sOpToSwitch.length != _NUM_OP) { 3104 throw new IllegalStateException("sOpToSwitch length " + sOpToSwitch.length 3105 + " should be " + _NUM_OP); 3106 } 3107 if (sOpToString.length != _NUM_OP) { 3108 throw new IllegalStateException("sOpToString length " + sOpToString.length 3109 + " should be " + _NUM_OP); 3110 } 3111 if (sOpNames.length != _NUM_OP) { 3112 throw new IllegalStateException("sOpNames length " + sOpNames.length 3113 + " should be " + _NUM_OP); 3114 } 3115 if (sOpPerms.length != _NUM_OP) { 3116 throw new IllegalStateException("sOpPerms length " + sOpPerms.length 3117 + " should be " + _NUM_OP); 3118 } 3119 if (sOpDefaultMode.length != _NUM_OP) { 3120 throw new IllegalStateException("sOpDefaultMode length " + sOpDefaultMode.length 3121 + " should be " + _NUM_OP); 3122 } 3123 if (sOpDisableReset.length != _NUM_OP) { 3124 throw new IllegalStateException("sOpDisableReset length " + sOpDisableReset.length 3125 + " should be " + _NUM_OP); 3126 } 3127 if (sOpRestrictions.length != _NUM_OP) { 3128 throw new IllegalStateException("sOpRestrictions length " + sOpRestrictions.length 3129 + " should be " + _NUM_OP); 3130 } 3131 if (sOpAllowSystemRestrictionBypass.length != _NUM_OP) { 3132 throw new IllegalStateException("sOpAllowSYstemRestrictionsBypass length " 3133 + sOpRestrictions.length + " should be " + _NUM_OP); 3134 } 3135 for (int i=0; i<_NUM_OP; i++) { 3136 if (sOpToString[i] != null) { sOpStrToOp.put(sOpToString[i], i)3137 sOpStrToOp.put(sOpToString[i], i); 3138 } 3139 } 3140 for (int op : RUNTIME_AND_APPOP_PERMISSIONS_OPS) { 3141 if (sOpPerms[op] != null) { sPermToOp.put(sOpPerms[op], op)3142 sPermToOp.put(sOpPerms[op], op); 3143 } 3144 } 3145 3146 if ((_NUM_OP + Long.SIZE - 1) / Long.SIZE != 2) { 3147 // The code currently assumes that the length of sAppOpsNotedInThisBinderTransaction is 3148 // two longs 3149 throw new IllegalStateException("notedAppOps collection code assumes < 128 appops"); 3150 } 3151 } 3152 3153 /** Config used to control app ops access messages sampling */ 3154 private static MessageSamplingConfig sConfig = 3155 new MessageSamplingConfig(OP_NONE, 0, 0); 3156 3157 /** @hide */ 3158 public static final String KEY_HISTORICAL_OPS = "historical_ops"; 3159 3160 /** System properties for debug logging of noteOp call sites */ 3161 private static final String DEBUG_LOGGING_ENABLE_PROP = "appops.logging_enabled"; 3162 private static final String DEBUG_LOGGING_PACKAGES_PROP = "appops.logging_packages"; 3163 private static final String DEBUG_LOGGING_OPS_PROP = "appops.logging_ops"; 3164 private static final String DEBUG_LOGGING_TAG = "AppOpsManager"; 3165 3166 /** 3167 * Retrieve the op switch that controls the given operation. 3168 * @hide 3169 */ 3170 @UnsupportedAppUsage opToSwitch(int op)3171 public static int opToSwitch(int op) { 3172 return sOpToSwitch[op]; 3173 } 3174 3175 /** 3176 * Retrieve a non-localized name for the operation, for debugging output. 3177 * @hide 3178 */ 3179 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) opToName(int op)3180 public static String opToName(int op) { 3181 if (op == OP_NONE) return "NONE"; 3182 return op < sOpNames.length ? sOpNames[op] : ("Unknown(" + op + ")"); 3183 } 3184 3185 /** 3186 * Retrieve a non-localized public name for the operation. 3187 * 3188 * @hide 3189 */ opToPublicName(int op)3190 public static @NonNull String opToPublicName(int op) { 3191 return sOpToString[op]; 3192 } 3193 3194 /** 3195 * @hide 3196 */ strDebugOpToOp(String op)3197 public static int strDebugOpToOp(String op) { 3198 for (int i=0; i<sOpNames.length; i++) { 3199 if (sOpNames[i].equals(op)) { 3200 return i; 3201 } 3202 } 3203 throw new IllegalArgumentException("Unknown operation string: " + op); 3204 } 3205 3206 /** 3207 * Retrieve the permission associated with an operation, or null if there is not one. 3208 * @hide 3209 */ 3210 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 3211 @TestApi opToPermission(int op)3212 public static String opToPermission(int op) { 3213 return sOpPerms[op]; 3214 } 3215 3216 /** 3217 * Retrieve the permission associated with an operation, or null if there is not one. 3218 * 3219 * @param op The operation name. 3220 * 3221 * @hide 3222 */ 3223 @Nullable 3224 @SystemApi opToPermission(@onNull String op)3225 public static String opToPermission(@NonNull String op) { 3226 return opToPermission(strOpToOp(op)); 3227 } 3228 3229 /** 3230 * Retrieve the user restriction associated with an operation, or null if there is not one. 3231 * @hide 3232 */ opToRestriction(int op)3233 public static String opToRestriction(int op) { 3234 return sOpRestrictions[op]; 3235 } 3236 3237 /** 3238 * Retrieve the app op code for a permission, or null if there is not one. 3239 * This API is intended to be used for mapping runtime or appop permissions 3240 * to the corresponding app op. 3241 * @hide 3242 */ 3243 @UnsupportedAppUsage 3244 @TestApi permissionToOpCode(String permission)3245 public static int permissionToOpCode(String permission) { 3246 Integer boxedOpCode = sPermToOp.get(permission); 3247 return boxedOpCode != null ? boxedOpCode : OP_NONE; 3248 } 3249 3250 /** 3251 * Retrieve whether the op allows to bypass the user restriction. 3252 * 3253 * @hide 3254 */ opAllowSystemBypassRestriction(int op)3255 public static RestrictionBypass opAllowSystemBypassRestriction(int op) { 3256 return sOpAllowSystemRestrictionBypass[op]; 3257 } 3258 3259 /** 3260 * Retrieve the default mode for the operation. 3261 * @hide 3262 */ opToDefaultMode(int op)3263 public static @Mode int opToDefaultMode(int op) { 3264 return sOpDefaultMode[op]; 3265 } 3266 3267 /** 3268 * Retrieve the default mode for the app op. 3269 * 3270 * @param appOp The app op name 3271 * 3272 * @return the default mode for the app op 3273 * 3274 * @hide 3275 */ 3276 @SystemApi opToDefaultMode(@onNull String appOp)3277 public static int opToDefaultMode(@NonNull String appOp) { 3278 return opToDefaultMode(strOpToOp(appOp)); 3279 } 3280 3281 /** 3282 * Retrieve the human readable mode. 3283 * @hide 3284 */ modeToName(@ode int mode)3285 public static String modeToName(@Mode int mode) { 3286 if (mode >= 0 && mode < MODE_NAMES.length) { 3287 return MODE_NAMES[mode]; 3288 } 3289 return "mode=" + mode; 3290 } 3291 3292 /** 3293 * Retrieve whether the op can be read by apps with manage appops permission. 3294 * @hide 3295 */ opRestrictsRead(int op)3296 public static boolean opRestrictsRead(int op) { 3297 return sOpRestrictRead[op]; 3298 } 3299 3300 /** 3301 * Retrieve whether the op allows itself to be reset. 3302 * @hide 3303 */ opAllowsReset(int op)3304 public static boolean opAllowsReset(int op) { 3305 return !sOpDisableReset[op]; 3306 } 3307 3308 /** 3309 * Returns a listenerId suitable for use with {@link #noteOp(int, int, String, String, String)}. 3310 * 3311 * This is intended for use client side, when the receiver id must be created before the 3312 * associated call is made to the system server. If using {@link PendingIntent} as the receiver, 3313 * avoid using this method as it will include a pointless additional x-process call. Instead 3314 * prefer passing the PendingIntent to the system server, and then invoking 3315 * {@link #toReceiverId(PendingIntent)}. 3316 * 3317 * @param obj the receiver in use 3318 * @return a string representation of the receiver suitable for app ops use 3319 * @hide 3320 */ 3321 // TODO: this should probably be @SystemApi as well toReceiverId(@ullable Object obj)3322 public static @NonNull String toReceiverId(@Nullable Object obj) { 3323 if (obj == null) { 3324 return "null"; 3325 } else if (obj instanceof PendingIntent) { 3326 return toReceiverId((PendingIntent) obj); 3327 } else { 3328 return obj.getClass().getName() + "@" + System.identityHashCode(obj); 3329 } 3330 } 3331 3332 /** 3333 * Returns a listenerId suitable for use with {@link #noteOp(int, int, String, String, String)}. 3334 * 3335 * This is intended for use server side, where ActivityManagerService can be referenced without 3336 * an additional x-process call. 3337 * 3338 * @param pendingIntent the pendingIntent in use 3339 * @return a string representation of the pending intent suitable for app ops use 3340 * @see #toReceiverId(Object) 3341 * @hide 3342 */ 3343 // TODO: this should probably be @SystemApi as well toReceiverId(@onNull PendingIntent pendingIntent)3344 public static @NonNull String toReceiverId(@NonNull PendingIntent pendingIntent) { 3345 return pendingIntent.getTag(""); 3346 } 3347 3348 /** 3349 * When to not enforce {@link #setUserRestriction restrictions}. 3350 * 3351 * @hide 3352 */ 3353 public static class RestrictionBypass { 3354 /** Does the app need to be system uid to bypass the restriction */ 3355 public boolean isSystemUid; 3356 3357 /** Does the app need to be privileged to bypass the restriction */ 3358 public boolean isPrivileged; 3359 3360 /** 3361 * Does the app need to have the EXEMPT_FROM_AUDIO_RESTRICTIONS permission to bypass the 3362 * restriction 3363 */ 3364 public boolean isRecordAudioRestrictionExcept; 3365 RestrictionBypass(boolean isSystemUid, boolean isPrivileged, boolean isRecordAudioRestrictionExcept)3366 public RestrictionBypass(boolean isSystemUid, boolean isPrivileged, 3367 boolean isRecordAudioRestrictionExcept) { 3368 this.isSystemUid = isSystemUid; 3369 this.isPrivileged = isPrivileged; 3370 this.isRecordAudioRestrictionExcept = isRecordAudioRestrictionExcept; 3371 } 3372 3373 public static RestrictionBypass UNRESTRICTED = new RestrictionBypass(false, true, true); 3374 } 3375 3376 /** 3377 * Class holding all of the operation information associated with an app. 3378 * @hide 3379 */ 3380 @SystemApi 3381 public static final class PackageOps implements Parcelable { 3382 private final String mPackageName; 3383 private final int mUid; 3384 private final List<OpEntry> mEntries; 3385 3386 /** 3387 * @hide 3388 */ 3389 @UnsupportedAppUsage PackageOps(String packageName, int uid, List<OpEntry> entries)3390 public PackageOps(String packageName, int uid, List<OpEntry> entries) { 3391 mPackageName = packageName; 3392 mUid = uid; 3393 mEntries = entries; 3394 } 3395 3396 /** 3397 * @return The name of the package. 3398 */ getPackageName()3399 public @NonNull String getPackageName() { 3400 return mPackageName; 3401 } 3402 3403 /** 3404 * @return The uid of the package. 3405 */ getUid()3406 public int getUid() { 3407 return mUid; 3408 } 3409 3410 /** 3411 * @return The ops of the package. 3412 */ getOps()3413 public @NonNull List<OpEntry> getOps() { 3414 return mEntries; 3415 } 3416 3417 @Override describeContents()3418 public int describeContents() { 3419 return 0; 3420 } 3421 3422 @Override writeToParcel(@onNull Parcel dest, int flags)3423 public void writeToParcel(@NonNull Parcel dest, int flags) { 3424 dest.writeString(mPackageName); 3425 dest.writeInt(mUid); 3426 dest.writeInt(mEntries.size()); 3427 for (int i=0; i<mEntries.size(); i++) { 3428 mEntries.get(i).writeToParcel(dest, flags); 3429 } 3430 } 3431 PackageOps(Parcel source)3432 PackageOps(Parcel source) { 3433 mPackageName = source.readString(); 3434 mUid = source.readInt(); 3435 mEntries = new ArrayList<OpEntry>(); 3436 final int N = source.readInt(); 3437 for (int i=0; i<N; i++) { 3438 mEntries.add(OpEntry.CREATOR.createFromParcel(source)); 3439 } 3440 } 3441 3442 public static final @android.annotation.NonNull Creator<PackageOps> CREATOR = new Creator<PackageOps>() { 3443 @Override public PackageOps createFromParcel(Parcel source) { 3444 return new PackageOps(source); 3445 } 3446 3447 @Override public PackageOps[] newArray(int size) { 3448 return new PackageOps[size]; 3449 } 3450 }; 3451 } 3452 3453 /** 3454 * Proxy information for a {@link #noteOp} event 3455 * 3456 * @hide 3457 */ 3458 @SystemApi 3459 // @DataClass(genHiddenConstructor = true, genHiddenCopyConstructor = true) 3460 // genHiddenCopyConstructor does not work for @hide @SystemApi classes 3461 public static final class OpEventProxyInfo implements Parcelable { 3462 /** UID of the proxy app that noted the op */ 3463 private @IntRange(from = 0) int mUid; 3464 /** Package of the proxy that noted the op */ 3465 private @Nullable String mPackageName; 3466 /** Attribution tag of the proxy that noted the op */ 3467 private @Nullable String mAttributionTag; 3468 3469 /** 3470 * Reinit existing object with new state. 3471 * 3472 * @param uid UID of the proxy app that noted the op 3473 * @param packageName Package of the proxy that noted the op 3474 * @param attributionTag attribution tag of the proxy that noted the op 3475 * 3476 * @hide 3477 */ reinit(@ntRangefrom = 0) int uid, @Nullable String packageName, @Nullable String attributionTag)3478 public void reinit(@IntRange(from = 0) int uid, @Nullable String packageName, 3479 @Nullable String attributionTag) { 3480 mUid = Preconditions.checkArgumentNonnegative(uid); 3481 mPackageName = packageName; 3482 mAttributionTag = attributionTag; 3483 } 3484 3485 3486 3487 // Code below generated by codegen v1.0.14. 3488 // 3489 // DO NOT MODIFY! 3490 // CHECKSTYLE:OFF Generated code 3491 // 3492 // To regenerate run: 3493 // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/app/AppOpsManager.java 3494 // 3495 // To exclude the generated code from IntelliJ auto-formatting enable (one-time): 3496 // Settings > Editor > Code Style > Formatter Control 3497 //@formatter:off 3498 3499 3500 /** 3501 * Creates a new OpEventProxyInfo. 3502 * 3503 * @param uid 3504 * UID of the proxy app that noted the op 3505 * @param packageName 3506 * Package of the proxy that noted the op 3507 * @param attributionTag 3508 * Attribution tag of the proxy that noted the op 3509 * @hide 3510 */ 3511 @DataClass.Generated.Member OpEventProxyInfo( @ntRangefrom = 0) int uid, @Nullable String packageName, @Nullable String attributionTag)3512 public OpEventProxyInfo( 3513 @IntRange(from = 0) int uid, 3514 @Nullable String packageName, 3515 @Nullable String attributionTag) { 3516 this.mUid = uid; 3517 com.android.internal.util.AnnotationValidations.validate( 3518 IntRange.class, null, mUid, 3519 "from", 0); 3520 this.mPackageName = packageName; 3521 this.mAttributionTag = attributionTag; 3522 3523 // onConstructed(); // You can define this method to get a callback 3524 } 3525 3526 /** 3527 * Copy constructor 3528 * 3529 * @hide 3530 */ 3531 @DataClass.Generated.Member OpEventProxyInfo(@onNull OpEventProxyInfo orig)3532 public OpEventProxyInfo(@NonNull OpEventProxyInfo orig) { 3533 mUid = orig.mUid; 3534 mPackageName = orig.mPackageName; 3535 mAttributionTag = orig.mAttributionTag; 3536 } 3537 3538 /** 3539 * UID of the proxy app that noted the op 3540 */ 3541 @DataClass.Generated.Member getUid()3542 public @IntRange(from = 0) int getUid() { 3543 return mUid; 3544 } 3545 3546 /** 3547 * Package of the proxy that noted the op 3548 */ 3549 @DataClass.Generated.Member getPackageName()3550 public @Nullable String getPackageName() { 3551 return mPackageName; 3552 } 3553 3554 /** 3555 * Attribution tag of the proxy that noted the op 3556 */ 3557 @DataClass.Generated.Member getAttributionTag()3558 public @Nullable String getAttributionTag() { 3559 return mAttributionTag; 3560 } 3561 3562 @Override 3563 @DataClass.Generated.Member writeToParcel(@onNull Parcel dest, int flags)3564 public void writeToParcel(@NonNull Parcel dest, int flags) { 3565 // You can override field parcelling by defining methods like: 3566 // void parcelFieldName(Parcel dest, int flags) { ... } 3567 3568 byte flg = 0; 3569 if (mPackageName != null) flg |= 0x2; 3570 if (mAttributionTag != null) flg |= 0x4; 3571 dest.writeByte(flg); 3572 dest.writeInt(mUid); 3573 if (mPackageName != null) dest.writeString(mPackageName); 3574 if (mAttributionTag != null) dest.writeString(mAttributionTag); 3575 } 3576 3577 @Override 3578 @DataClass.Generated.Member describeContents()3579 public int describeContents() { return 0; } 3580 3581 /** @hide */ 3582 @SuppressWarnings({"unchecked", "RedundantCast"}) 3583 @DataClass.Generated.Member OpEventProxyInfo(@onNull Parcel in)3584 /* package-private */ OpEventProxyInfo(@NonNull Parcel in) { 3585 // You can override field unparcelling by defining methods like: 3586 // static FieldType unparcelFieldName(Parcel in) { ... } 3587 3588 byte flg = in.readByte(); 3589 int uid = in.readInt(); 3590 String packageName = (flg & 0x2) == 0 ? null : in.readString(); 3591 String attributionTag = (flg & 0x4) == 0 ? null : in.readString(); 3592 3593 this.mUid = uid; 3594 com.android.internal.util.AnnotationValidations.validate( 3595 IntRange.class, null, mUid, 3596 "from", 0); 3597 this.mPackageName = packageName; 3598 this.mAttributionTag = attributionTag; 3599 3600 // onConstructed(); // You can define this method to get a callback 3601 } 3602 3603 @DataClass.Generated.Member 3604 public static final @NonNull Parcelable.Creator<OpEventProxyInfo> CREATOR 3605 = new Parcelable.Creator<OpEventProxyInfo>() { 3606 @Override 3607 public OpEventProxyInfo[] newArray(int size) { 3608 return new OpEventProxyInfo[size]; 3609 } 3610 3611 @Override 3612 public OpEventProxyInfo createFromParcel(@NonNull Parcel in) { 3613 return new OpEventProxyInfo(in); 3614 } 3615 }; 3616 3617 /* 3618 @DataClass.Generated( 3619 time = 1576814974615L, 3620 codegenVersion = "1.0.14", 3621 sourceFile = "frameworks/base/core/java/android/app/AppOpsManager.java", 3622 inputSignatures = "private @android.annotation.IntRange(from=0L) int mUid\nprivate @android.annotation.Nullable java.lang.String mPackageName\nprivate @android.annotation.Nullable java.lang.String mAttributionTag\npublic void reinit(int,java.lang.String,java.lang.String)\nclass OpEventProxyInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstructor=true, genHiddenCopyConstructor=true)") 3623 @Deprecated 3624 private void __metadata() {} 3625 */ 3626 3627 //@formatter:on 3628 // End of generated code 3629 3630 } 3631 3632 /** 3633 * Description of a {@link #noteOp} or {@link #startOp} event 3634 * 3635 * @hide 3636 */ 3637 //@DataClass codegen verifier is broken 3638 public static final class NoteOpEvent implements Parcelable { 3639 /** Time of noteOp event */ 3640 private @IntRange(from = 0) long mNoteTime; 3641 /** The duration of this event (in case this is a startOp event, -1 otherwise). */ 3642 private @IntRange(from = -1) long mDuration; 3643 /** Proxy information of the noteOp event */ 3644 private @Nullable OpEventProxyInfo mProxy; 3645 3646 /** 3647 * Reinit existing object with new state. 3648 * 3649 * @param noteTime Time of noteOp event 3650 * @param duration The duration of this event (in case this is a startOp event, 3651 * -1 otherwise). 3652 * @param proxy Proxy information of the noteOp event 3653 * @param proxyPool The pool to release previous {@link OpEventProxyInfo} to 3654 */ reinit(@ntRangefrom = 0) long noteTime, @IntRange(from = -1) long duration, @Nullable OpEventProxyInfo proxy, @NonNull Pools.Pool<OpEventProxyInfo> proxyPool)3655 public void reinit(@IntRange(from = 0) long noteTime, 3656 @IntRange(from = -1) long duration, 3657 @Nullable OpEventProxyInfo proxy, 3658 @NonNull Pools.Pool<OpEventProxyInfo> proxyPool) { 3659 mNoteTime = Preconditions.checkArgumentNonnegative(noteTime); 3660 mDuration = Preconditions.checkArgumentInRange(duration, -1L, Long.MAX_VALUE, 3661 "duration"); 3662 3663 if (mProxy != null) { 3664 proxyPool.release(mProxy); 3665 } 3666 mProxy = proxy; 3667 } 3668 3669 /** 3670 * Copy constructor 3671 * 3672 * @hide 3673 */ NoteOpEvent(@onNull NoteOpEvent original)3674 public NoteOpEvent(@NonNull NoteOpEvent original) { 3675 this(original.mNoteTime, original.mDuration, 3676 original.mProxy != null ? new OpEventProxyInfo(original.mProxy) : null); 3677 } 3678 3679 3680 3681 // Code below generated by codegen v1.0.14. 3682 // 3683 // DO NOT MODIFY! 3684 // CHECKSTYLE:OFF Generated code 3685 // 3686 // To regenerate run: 3687 // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/app/AppOpsManager.java 3688 // 3689 // To exclude the generated code from IntelliJ auto-formatting enable (one-time): 3690 // Settings > Editor > Code Style > Formatter Control 3691 //@formatter:off 3692 3693 3694 /** 3695 * Creates a new NoteOpEvent. 3696 * 3697 * @param noteTime 3698 * Time of noteOp event 3699 * @param duration 3700 * The duration of this event (in case this is a startOp event, -1 otherwise). 3701 * @param proxy 3702 * Proxy information of the noteOp event 3703 */ 3704 @DataClass.Generated.Member NoteOpEvent( @ntRangefrom = 0) long noteTime, @IntRange(from = -1) long duration, @Nullable OpEventProxyInfo proxy)3705 public NoteOpEvent( 3706 @IntRange(from = 0) long noteTime, 3707 @IntRange(from = -1) long duration, 3708 @Nullable OpEventProxyInfo proxy) { 3709 this.mNoteTime = noteTime; 3710 com.android.internal.util.AnnotationValidations.validate( 3711 IntRange.class, null, mNoteTime, 3712 "from", 0); 3713 this.mDuration = duration; 3714 com.android.internal.util.AnnotationValidations.validate( 3715 IntRange.class, null, mDuration, 3716 "from", -1); 3717 this.mProxy = proxy; 3718 3719 // onConstructed(); // You can define this method to get a callback 3720 } 3721 3722 /** 3723 * Time of noteOp event 3724 */ 3725 @DataClass.Generated.Member getNoteTime()3726 public @IntRange(from = 0) long getNoteTime() { 3727 return mNoteTime; 3728 } 3729 3730 /** 3731 * The duration of this event (in case this is a startOp event, -1 otherwise). 3732 */ 3733 @DataClass.Generated.Member getDuration()3734 public @IntRange(from = -1) long getDuration() { 3735 return mDuration; 3736 } 3737 3738 /** 3739 * Proxy information of the noteOp event 3740 */ 3741 @DataClass.Generated.Member getProxy()3742 public @Nullable OpEventProxyInfo getProxy() { 3743 return mProxy; 3744 } 3745 3746 @Override 3747 @DataClass.Generated.Member writeToParcel(@onNull Parcel dest, int flags)3748 public void writeToParcel(@NonNull Parcel dest, int flags) { 3749 // You can override field parcelling by defining methods like: 3750 // void parcelFieldName(Parcel dest, int flags) { ... } 3751 3752 byte flg = 0; 3753 if (mProxy != null) flg |= 0x4; 3754 dest.writeByte(flg); 3755 dest.writeLong(mNoteTime); 3756 dest.writeLong(mDuration); 3757 if (mProxy != null) dest.writeTypedObject(mProxy, flags); 3758 } 3759 3760 @Override 3761 @DataClass.Generated.Member describeContents()3762 public int describeContents() { return 0; } 3763 3764 /** @hide */ 3765 @SuppressWarnings({"unchecked", "RedundantCast"}) 3766 @DataClass.Generated.Member NoteOpEvent(@onNull Parcel in)3767 /* package-private */ NoteOpEvent(@NonNull Parcel in) { 3768 // You can override field unparcelling by defining methods like: 3769 // static FieldType unparcelFieldName(Parcel in) { ... } 3770 3771 byte flg = in.readByte(); 3772 long noteTime = in.readLong(); 3773 long duration = in.readLong(); 3774 OpEventProxyInfo proxy = (flg & 0x4) == 0 ? null : (OpEventProxyInfo) in.readTypedObject(OpEventProxyInfo.CREATOR); 3775 3776 this.mNoteTime = noteTime; 3777 com.android.internal.util.AnnotationValidations.validate( 3778 IntRange.class, null, mNoteTime, 3779 "from", 0); 3780 this.mDuration = duration; 3781 com.android.internal.util.AnnotationValidations.validate( 3782 IntRange.class, null, mDuration, 3783 "from", -1); 3784 this.mProxy = proxy; 3785 3786 // onConstructed(); // You can define this method to get a callback 3787 } 3788 3789 @DataClass.Generated.Member 3790 public static final @NonNull Parcelable.Creator<NoteOpEvent> CREATOR 3791 = new Parcelable.Creator<NoteOpEvent>() { 3792 @Override 3793 public NoteOpEvent[] newArray(int size) { 3794 return new NoteOpEvent[size]; 3795 } 3796 3797 @Override 3798 public NoteOpEvent createFromParcel(@NonNull Parcel in) { 3799 return new NoteOpEvent(in); 3800 } 3801 }; 3802 3803 /* 3804 @DataClass.Generated( 3805 time = 1576811792274L, 3806 codegenVersion = "1.0.14", 3807 sourceFile = "frameworks/base/core/java/android/app/AppOpsManager.java", 3808 inputSignatures = "private @android.annotation.IntRange(from=0L) long mNoteTime\nprivate @android.annotation.IntRange(from=-1) long mDuration\nprivate @android.annotation.Nullable android.app.OpEventProxyInfo mProxy\npublic void reinit(long,long,android.app.OpEventProxyInfo,android.util.Pools.Pool<android.app.OpEventProxyInfo>)\npublic @java.lang.Override java.lang.Object clone()\nclass NoteOpEvent extends java.lang.Object implements [android.os.Parcelable, java.lang.Cloneable]\n@com.android.internal.util.DataClass") 3809 @Deprecated 3810 private void __metadata() {} 3811 */ 3812 3813 3814 //@formatter:on 3815 // End of generated code 3816 3817 } 3818 3819 /** 3820 * Last {@link #noteOp} and {@link #startOp} events performed for a single op and a specific 3821 * {@link Context#createAttributionContext(String) attribution} for all uidModes and opFlags. 3822 * 3823 * @hide 3824 */ 3825 @SystemApi 3826 @Immutable 3827 // @DataClass(genHiddenConstructor = true) codegen verifier is broken 3828 @DataClass.Suppress({"getAccessEvents", "getRejectEvents", "getOp"}) 3829 public static final class AttributedOpEntry implements Parcelable { 3830 /** The code of the op */ 3831 private final @IntRange(from = 0, to = _NUM_OP - 1) int mOp; 3832 /** Whether the op is running */ 3833 private final boolean mRunning; 3834 /** The access events */ 3835 @DataClass.ParcelWith(LongSparseArrayParceling.class) 3836 private final @Nullable LongSparseArray<NoteOpEvent> mAccessEvents; 3837 /** The rejection events */ 3838 @DataClass.ParcelWith(LongSparseArrayParceling.class) 3839 private final @Nullable LongSparseArray<NoteOpEvent> mRejectEvents; 3840 AttributedOpEntry(@onNull AttributedOpEntry other)3841 private AttributedOpEntry(@NonNull AttributedOpEntry other) { 3842 mOp = other.mOp; 3843 mRunning = other.mRunning; 3844 mAccessEvents = other.mAccessEvents == null ? null : other.mAccessEvents.clone(); 3845 mRejectEvents = other.mRejectEvents == null ? null : other.mRejectEvents.clone(); 3846 } 3847 3848 /** 3849 * Returns all keys for which we have events. 3850 * 3851 * @hide 3852 */ collectKeys()3853 public @NonNull ArraySet<Long> collectKeys() { 3854 ArraySet<Long> keys = new ArraySet<>(); 3855 3856 if (mAccessEvents != null) { 3857 int numEvents = mAccessEvents.size(); 3858 for (int i = 0; i < numEvents; i++) { 3859 keys.add(mAccessEvents.keyAt(i)); 3860 } 3861 } 3862 3863 if (mRejectEvents != null) { 3864 int numEvents = mRejectEvents.size(); 3865 for (int i = 0; i < numEvents; i++) { 3866 keys.add(mRejectEvents.keyAt(i)); 3867 } 3868 } 3869 3870 return keys; 3871 } 3872 3873 /** 3874 * Return the last access time. 3875 * 3876 * @param flags The op flags 3877 * 3878 * @return the last access time (in milliseconds since epoch start (January 1, 1970 3879 * 00:00:00.000 GMT - Gregorian)) or {@code -1} if there was no access 3880 * 3881 * @see #getLastAccessForegroundTime(int) 3882 * @see #getLastAccessBackgroundTime(int) 3883 * @see #getLastAccessTime(int, int, int) 3884 * @see OpEntry#getLastAccessTime(int) 3885 */ getLastAccessTime(@pFlags int flags)3886 public long getLastAccessTime(@OpFlags int flags) { 3887 return getLastAccessTime(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, flags); 3888 } 3889 3890 /** 3891 * Return the last foreground access time. 3892 * 3893 * @param flags The op flags 3894 * 3895 * @return the last access time (in milliseconds since epoch start (January 1, 1970 3896 * 00:00:00.000 GMT - Gregorian)) or {@code -1} if there was no foreground access 3897 * 3898 * @see #getLastAccessTime(int) 3899 * @see #getLastAccessBackgroundTime(int) 3900 * @see #getLastAccessTime(int, int, int) 3901 * @see OpEntry#getLastAccessForegroundTime(int) 3902 */ getLastAccessForegroundTime(@pFlags int flags)3903 public long getLastAccessForegroundTime(@OpFlags int flags) { 3904 return getLastAccessTime(MAX_PRIORITY_UID_STATE, resolveFirstUnrestrictedUidState(mOp), 3905 flags); 3906 } 3907 3908 /** 3909 * Return the last background access time. 3910 * 3911 * @param flags The op flags 3912 * 3913 * @return the last access time (in milliseconds since epoch start (January 1, 1970 3914 * 00:00:00.000 GMT - Gregorian)) or {@code -1} if there was no background access 3915 * 3916 * @see #getLastAccessTime(int) 3917 * @see #getLastAccessForegroundTime(int) 3918 * @see #getLastAccessTime(int, int, int) 3919 * @see OpEntry#getLastAccessBackgroundTime(int) 3920 */ getLastAccessBackgroundTime(@pFlags int flags)3921 public long getLastAccessBackgroundTime(@OpFlags int flags) { 3922 return getLastAccessTime(resolveLastRestrictedUidState(mOp), MIN_PRIORITY_UID_STATE, 3923 flags); 3924 } 3925 3926 /** 3927 * Return the last access event. 3928 * 3929 * @param flags The op flags 3930 * 3931 * @return the last access event of {@code null} if there was no access 3932 */ getLastAccessEvent(@idState int fromUidState, @UidState int toUidState, @OpFlags int flags)3933 private @Nullable NoteOpEvent getLastAccessEvent(@UidState int fromUidState, 3934 @UidState int toUidState, @OpFlags int flags) { 3935 return getLastEvent(mAccessEvents, fromUidState, toUidState, flags); 3936 } 3937 3938 /** 3939 * Return the last access time. 3940 * 3941 * @param fromUidState The lowest UID state for which to query 3942 * @param toUidState The highest UID state for which to query (inclusive) 3943 * @param flags The op flags 3944 * 3945 * @return the last access time (in milliseconds since epoch start (January 1, 1970 3946 * 00:00:00.000 GMT - Gregorian)) or {@code -1} if there was no access 3947 * 3948 * @see #getLastAccessTime(int) 3949 * @see #getLastAccessForegroundTime(int) 3950 * @see #getLastAccessBackgroundTime(int) 3951 * @see OpEntry#getLastAccessTime(int, int, int) 3952 */ getLastAccessTime(@idState int fromUidState, @UidState int toUidState, @OpFlags int flags)3953 public long getLastAccessTime(@UidState int fromUidState, @UidState int toUidState, 3954 @OpFlags int flags) { 3955 NoteOpEvent lastEvent = getLastAccessEvent(fromUidState, toUidState, flags); 3956 if (lastEvent == null) { 3957 return -1; 3958 } 3959 3960 return lastEvent.getNoteTime(); 3961 } 3962 3963 /** 3964 * Return the last rejection time. 3965 * 3966 * @param flags The op flags 3967 * 3968 * @return the last rejection time (in milliseconds since epoch start (January 1, 1970 3969 * 00:00:00.000 GMT - Gregorian)) or {@code -1} if there was no rejection 3970 * 3971 * @see #getLastRejectForegroundTime(int) 3972 * @see #getLastRejectBackgroundTime(int) 3973 * @see #getLastRejectTime(int, int, int) 3974 * @see OpEntry#getLastRejectTime(int) 3975 */ getLastRejectTime(@pFlags int flags)3976 public long getLastRejectTime(@OpFlags int flags) { 3977 return getLastRejectTime(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, flags); 3978 } 3979 3980 /** 3981 * Return the last foreground rejection time. 3982 * 3983 * @param flags The op flags 3984 * 3985 * @return the last rejection time (in milliseconds since epoch start (January 1, 1970 3986 * 00:00:00.000 GMT - Gregorian)) or {@code -1} if there was no foreground rejection 3987 * 3988 * @see #getLastRejectTime(int) 3989 * @see #getLastRejectBackgroundTime(int) 3990 * @see #getLastRejectTime(int, int, int) 3991 * @see OpEntry#getLastRejectForegroundTime(int) 3992 */ getLastRejectForegroundTime(@pFlags int flags)3993 public long getLastRejectForegroundTime(@OpFlags int flags) { 3994 return getLastRejectTime(MAX_PRIORITY_UID_STATE, resolveFirstUnrestrictedUidState(mOp), 3995 flags); 3996 } 3997 3998 /** 3999 * Return the last background rejection time. 4000 * 4001 * @param flags The op flags 4002 * 4003 * @return the last rejection time (in milliseconds since epoch start (January 1, 1970 4004 * 00:00:00.000 GMT - Gregorian)) or {@code -1} if there was no background rejection 4005 * 4006 * @see #getLastRejectTime(int) 4007 * @see #getLastRejectForegroundTime(int) 4008 * @see #getLastRejectTime(int, int, int) 4009 * @see OpEntry#getLastRejectBackgroundTime(int) 4010 */ getLastRejectBackgroundTime(@pFlags int flags)4011 public long getLastRejectBackgroundTime(@OpFlags int flags) { 4012 return getLastRejectTime(resolveLastRestrictedUidState(mOp), MIN_PRIORITY_UID_STATE, 4013 flags); 4014 } 4015 4016 /** 4017 * Return the last background rejection event. 4018 * 4019 * @param flags The op flags 4020 * 4021 * @return the last rejection event of {@code null} if there was no rejection 4022 * 4023 * @see #getLastRejectTime(int) 4024 * @see #getLastRejectForegroundTime(int) 4025 * @see #getLastRejectBackgroundTime(int) 4026 * @see OpEntry#getLastRejectTime(int, int, int) 4027 */ getLastRejectEvent(@idState int fromUidState, @UidState int toUidState, @OpFlags int flags)4028 private @Nullable NoteOpEvent getLastRejectEvent(@UidState int fromUidState, 4029 @UidState int toUidState, @OpFlags int flags) { 4030 return getLastEvent(mRejectEvents, fromUidState, toUidState, flags); 4031 } 4032 4033 /** 4034 * Return the last rejection time. 4035 * 4036 * @param fromUidState The lowest UID state for which to query 4037 * @param toUidState The highest UID state for which to query (inclusive) 4038 * @param flags The op flags 4039 * 4040 * @return the last access time (in milliseconds since epoch) or {@code -1} if there was no 4041 * rejection 4042 * 4043 * @see #getLastRejectTime(int) 4044 * @see #getLastRejectForegroundTime(int) 4045 * @see #getLastRejectForegroundTime(int) 4046 * @see #getLastRejectTime(int, int, int) 4047 * @see OpEntry#getLastRejectTime(int, int, int) 4048 */ getLastRejectTime(@idState int fromUidState, @UidState int toUidState, @OpFlags int flags)4049 public long getLastRejectTime(@UidState int fromUidState, @UidState int toUidState, 4050 @OpFlags int flags) { 4051 NoteOpEvent lastEvent = getLastRejectEvent(fromUidState, toUidState, flags); 4052 if (lastEvent == null) { 4053 return -1; 4054 } 4055 4056 return lastEvent.getNoteTime(); 4057 } 4058 4059 /** 4060 * Return the duration in milliseconds of the last the access. 4061 * 4062 * @param flags The op flags 4063 * 4064 * @return the duration in milliseconds or {@code -1} if there was no rejection 4065 * 4066 * @see #getLastForegroundDuration(int) 4067 * @see #getLastBackgroundDuration(int) 4068 * @see #getLastDuration(int, int, int) 4069 * @see OpEntry#getLastDuration(int) 4070 */ getLastDuration(@pFlags int flags)4071 public long getLastDuration(@OpFlags int flags) { 4072 return getLastDuration(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, flags); 4073 } 4074 4075 /** 4076 * Return the duration in milliseconds of the last foreground access. 4077 * 4078 * @param flags The op flags 4079 * 4080 * @return the duration in milliseconds or {@code -1} if there was no foreground rejection 4081 * 4082 * @see #getLastDuration(int) 4083 * @see #getLastBackgroundDuration(int) 4084 * @see #getLastDuration(int, int, int) 4085 * @see OpEntry#getLastForegroundDuration(int) 4086 */ getLastForegroundDuration(@pFlags int flags)4087 public long getLastForegroundDuration(@OpFlags int flags) { 4088 return getLastDuration(MAX_PRIORITY_UID_STATE, resolveFirstUnrestrictedUidState(mOp), 4089 flags); 4090 } 4091 4092 /** 4093 * Return the duration in milliseconds of the last background access. 4094 * 4095 * @param flags The op flags 4096 * 4097 * @return the duration in milliseconds or {@code -1} if there was no background rejection 4098 * 4099 * @see #getLastDuration(int) 4100 * @see #getLastForegroundDuration(int) 4101 * @see #getLastDuration(int, int, int) 4102 * @see OpEntry#getLastBackgroundDuration(int) 4103 */ getLastBackgroundDuration(@pFlags int flags)4104 public long getLastBackgroundDuration(@OpFlags int flags) { 4105 return getLastDuration(resolveLastRestrictedUidState(mOp), MIN_PRIORITY_UID_STATE, 4106 flags); 4107 } 4108 4109 /** 4110 * Return the duration in milliseconds of the last access. 4111 * 4112 * @param fromUidState The lowest UID state for which to query 4113 * @param toUidState The highest UID state for which to query (inclusive) 4114 * @param flags The op flags 4115 * 4116 * @return the duration in milliseconds or {@code -1} if there was no rejection 4117 * 4118 * @see #getLastDuration(int) 4119 * @see #getLastForegroundDuration(int) 4120 * @see #getLastBackgroundDuration(int) 4121 * @see #getLastDuration(int, int, int) 4122 * @see OpEntry#getLastDuration(int, int, int) 4123 */ getLastDuration(@idState int fromUidState, @UidState int toUidState, @OpFlags int flags)4124 public long getLastDuration(@UidState int fromUidState, @UidState int toUidState, 4125 @OpFlags int flags) { 4126 NoteOpEvent lastEvent = getLastAccessEvent(fromUidState, toUidState, flags);; 4127 if (lastEvent == null) { 4128 return -1; 4129 } 4130 4131 return lastEvent.getDuration(); 4132 } 4133 4134 /** 4135 * Gets the proxy info of the app that performed the last access on behalf of this 4136 * attribution and as a result blamed the op on this attribution. 4137 * 4138 * @param flags The op flags 4139 * 4140 * @return The proxy info or {@code null} if there was no proxy access 4141 * 4142 * @see #getLastForegroundProxyInfo(int) 4143 * @see #getLastBackgroundProxyInfo(int) 4144 * @see #getLastProxyInfo(int, int, int) 4145 * @see OpEntry#getLastProxyInfo(int) 4146 */ getLastProxyInfo(@pFlags int flags)4147 public @Nullable OpEventProxyInfo getLastProxyInfo(@OpFlags int flags) { 4148 return getLastProxyInfo(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, flags); 4149 } 4150 4151 /** 4152 * Gets the proxy info of the app that performed the last foreground access on behalf of 4153 * this attribution and as a result blamed the op on this attribution. 4154 * 4155 * @param flags The op flags 4156 * 4157 * @return The proxy info or {@code null} if there was no proxy access 4158 * 4159 * @see #getLastProxyInfo(int) 4160 * @see #getLastBackgroundProxyInfo(int) 4161 * @see #getLastProxyInfo(int, int, int) 4162 * @see OpEntry#getLastForegroundProxyInfo(int) 4163 */ getLastForegroundProxyInfo(@pFlags int flags)4164 public @Nullable OpEventProxyInfo getLastForegroundProxyInfo(@OpFlags int flags) { 4165 return getLastProxyInfo(MAX_PRIORITY_UID_STATE, resolveFirstUnrestrictedUidState(mOp), 4166 flags); 4167 } 4168 4169 /** 4170 * Gets the proxy info of the app that performed the last background access on behalf of 4171 * this attribution and as a result blamed the op on this attribution. 4172 * 4173 * @param flags The op flags 4174 * 4175 * @return The proxy info or {@code null} if there was no proxy background access 4176 * 4177 * @see #getLastProxyInfo(int) 4178 * @see #getLastForegroundProxyInfo(int) 4179 * @see #getLastProxyInfo(int, int, int) 4180 * @see OpEntry#getLastBackgroundProxyInfo(int) 4181 */ getLastBackgroundProxyInfo(@pFlags int flags)4182 public @Nullable OpEventProxyInfo getLastBackgroundProxyInfo(@OpFlags int flags) { 4183 return getLastProxyInfo(resolveLastRestrictedUidState(mOp), MIN_PRIORITY_UID_STATE, 4184 flags); 4185 } 4186 4187 /** 4188 * Gets the proxy info of the app that performed the last access on behalf of this 4189 * attribution and as a result blamed the op on this attribution. 4190 * 4191 * @param fromUidState The lowest UID state for which to query 4192 * @param toUidState The highest UID state for which to query (inclusive) 4193 * @param flags The op flags 4194 * 4195 * @return The proxy info or {@code null} if there was no proxy foreground access 4196 * 4197 * @see #getLastProxyInfo(int) 4198 * @see #getLastForegroundProxyInfo(int) 4199 * @see #getLastBackgroundProxyInfo(int) 4200 * @see OpEntry#getLastProxyInfo(int, int, int) 4201 */ getLastProxyInfo(@idState int fromUidState, @UidState int toUidState, @OpFlags int flags)4202 public @Nullable OpEventProxyInfo getLastProxyInfo(@UidState int fromUidState, 4203 @UidState int toUidState, @OpFlags int flags) { 4204 NoteOpEvent lastEvent = getLastAccessEvent(fromUidState, toUidState, flags); 4205 if (lastEvent == null) { 4206 return null; 4207 } 4208 4209 return lastEvent.getProxy(); 4210 } 4211 4212 @NonNull getOpName()4213 String getOpName() { 4214 return AppOpsManager.opToPublicName(mOp); 4215 } 4216 getOp()4217 int getOp() { 4218 return mOp; 4219 } 4220 4221 private static class LongSparseArrayParceling implements 4222 Parcelling<LongSparseArray<NoteOpEvent>> { 4223 @Override parcel(@ullable LongSparseArray<NoteOpEvent> array, @NonNull Parcel dest, int parcelFlags)4224 public void parcel(@Nullable LongSparseArray<NoteOpEvent> array, @NonNull Parcel dest, 4225 int parcelFlags) { 4226 if (array == null) { 4227 dest.writeInt(-1); 4228 return; 4229 } 4230 4231 int numEntries = array.size(); 4232 dest.writeInt(numEntries); 4233 4234 for (int i = 0; i < numEntries; i++) { 4235 dest.writeLong(array.keyAt(i)); 4236 dest.writeParcelable(array.valueAt(i), parcelFlags); 4237 } 4238 } 4239 4240 @Override unparcel(@onNull Parcel source)4241 public @Nullable LongSparseArray<NoteOpEvent> unparcel(@NonNull Parcel source) { 4242 int numEntries = source.readInt(); 4243 if (numEntries == -1) { 4244 return null; 4245 } 4246 4247 LongSparseArray<NoteOpEvent> array = new LongSparseArray<>(numEntries); 4248 4249 for (int i = 0; i < numEntries; i++) { 4250 array.put(source.readLong(), source.readParcelable(null, android.app.AppOpsManager.NoteOpEvent.class)); 4251 } 4252 4253 return array; 4254 } 4255 } 4256 4257 4258 4259 // Code below generated by codegen v1.0.14. 4260 // 4261 // DO NOT MODIFY! 4262 // CHECKSTYLE:OFF Generated code 4263 // 4264 // To regenerate run: 4265 // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/app/AppOpsManager.java 4266 // 4267 // To exclude the generated code from IntelliJ auto-formatting enable (one-time): 4268 // Settings > Editor > Code Style > Formatter Control 4269 //@formatter:off 4270 4271 4272 /** 4273 * Creates a new OpAttributionEntry. 4274 * 4275 * @param op 4276 * The code of the op 4277 * @param running 4278 * Whether the op is running 4279 * @param accessEvents 4280 * The access events 4281 * @param rejectEvents 4282 * The rejection events 4283 * @hide 4284 */ 4285 @DataClass.Generated.Member AttributedOpEntry( @ntRangefrom = 0, to = _NUM_OP - 1) int op, boolean running, @Nullable LongSparseArray<NoteOpEvent> accessEvents, @Nullable LongSparseArray<NoteOpEvent> rejectEvents)4286 public AttributedOpEntry( 4287 @IntRange(from = 0, to = _NUM_OP - 1) int op, 4288 boolean running, 4289 @Nullable LongSparseArray<NoteOpEvent> accessEvents, 4290 @Nullable LongSparseArray<NoteOpEvent> rejectEvents) { 4291 this.mOp = op; 4292 com.android.internal.util.AnnotationValidations.validate( 4293 IntRange.class, null, mOp, 4294 "from", 0, 4295 "to", _NUM_OP - 1); 4296 this.mRunning = running; 4297 this.mAccessEvents = accessEvents; 4298 this.mRejectEvents = rejectEvents; 4299 4300 // onConstructed(); // You can define this method to get a callback 4301 } 4302 4303 /** 4304 * Whether the op is running 4305 */ 4306 @DataClass.Generated.Member isRunning()4307 public boolean isRunning() { 4308 return mRunning; 4309 } 4310 4311 @DataClass.Generated.Member 4312 static Parcelling<LongSparseArray<NoteOpEvent>> sParcellingForAccessEvents = 4313 Parcelling.Cache.get( 4314 LongSparseArrayParceling.class); 4315 static { 4316 if (sParcellingForAccessEvents == null) { 4317 sParcellingForAccessEvents = Parcelling.Cache.put( 4318 new LongSparseArrayParceling()); 4319 } 4320 } 4321 4322 @DataClass.Generated.Member 4323 static Parcelling<LongSparseArray<NoteOpEvent>> sParcellingForRejectEvents = 4324 Parcelling.Cache.get( 4325 LongSparseArrayParceling.class); 4326 static { 4327 if (sParcellingForRejectEvents == null) { 4328 sParcellingForRejectEvents = Parcelling.Cache.put( 4329 new LongSparseArrayParceling()); 4330 } 4331 } 4332 4333 @Override 4334 @DataClass.Generated.Member writeToParcel(@onNull Parcel dest, int flags)4335 public void writeToParcel(@NonNull Parcel dest, int flags) { 4336 // You can override field parcelling by defining methods like: 4337 // void parcelFieldName(Parcel dest, int flags) { ... } 4338 4339 byte flg = 0; 4340 if (mRunning) flg |= 0x2; 4341 if (mAccessEvents != null) flg |= 0x4; 4342 if (mRejectEvents != null) flg |= 0x8; 4343 dest.writeByte(flg); 4344 dest.writeInt(mOp); 4345 sParcellingForAccessEvents.parcel(mAccessEvents, dest, flags); 4346 sParcellingForRejectEvents.parcel(mRejectEvents, dest, flags); 4347 } 4348 4349 @Override 4350 @DataClass.Generated.Member describeContents()4351 public int describeContents() { return 0; } 4352 4353 /** @hide */ 4354 @SuppressWarnings({"unchecked", "RedundantCast"}) 4355 @DataClass.Generated.Member AttributedOpEntry(@onNull Parcel in)4356 /* package-private */ AttributedOpEntry(@NonNull Parcel in) { 4357 // You can override field unparcelling by defining methods like: 4358 // static FieldType unparcelFieldName(Parcel in) { ... } 4359 4360 byte flg = in.readByte(); 4361 boolean running = (flg & 0x2) != 0; 4362 int op = in.readInt(); 4363 LongSparseArray<NoteOpEvent> accessEvents = sParcellingForAccessEvents.unparcel(in); 4364 LongSparseArray<NoteOpEvent> rejectEvents = sParcellingForRejectEvents.unparcel(in); 4365 4366 this.mOp = op; 4367 com.android.internal.util.AnnotationValidations.validate( 4368 IntRange.class, null, mOp, 4369 "from", 0, 4370 "to", _NUM_OP - 1); 4371 this.mRunning = running; 4372 this.mAccessEvents = accessEvents; 4373 this.mRejectEvents = rejectEvents; 4374 4375 // onConstructed(); // You can define this method to get a callback 4376 } 4377 4378 @DataClass.Generated.Member 4379 public static final @NonNull Parcelable.Creator<AttributedOpEntry> CREATOR 4380 = new Parcelable.Creator<AttributedOpEntry>() { 4381 @Override 4382 public AttributedOpEntry[] newArray(int size) { 4383 return new AttributedOpEntry[size]; 4384 } 4385 4386 @Override 4387 public AttributedOpEntry createFromParcel(@NonNull Parcel in) { 4388 return new AttributedOpEntry(in); 4389 } 4390 }; 4391 4392 /* 4393 @DataClass.Generated( 4394 time = 1574809856239L, 4395 codegenVersion = "1.0.14", 4396 sourceFile = "frameworks/base/core/java/android/app/AppOpsManager.java", 4397 inputSignatures = "private final @android.annotation.IntRange(from=0L, to=_NUM_OP - 1) int mOp\nprivate final boolean mRunning\nprivate final @com.android.internal.util.DataClass.ParcelWith(android.app.OpAttributionEntry.LongSparseArrayParceling.class) @android.annotation.Nullable android.util.LongSparseArray<android.app.NoteOpEvent> mAccessEvents\nprivate final @com.android.internal.util.DataClass.ParcelWith(android.app.OpAttributionEntry.LongSparseArrayParceling.class) @android.annotation.Nullable android.util.LongSparseArray<android.app.NoteOpEvent> mRejectEvents\npublic @android.annotation.NonNull android.util.ArraySet<java.lang.Long> collectKeys()\npublic @android.app.UidState int getLastAccessUidState(int)\npublic @android.app.UidState int getLastForegroundAccessUidState(int)\npublic @android.app.UidState int getLastBackgroundAccessUidState(int)\npublic @android.app.UidState int getLastRejectUidState(int)\npublic @android.app.UidState int getLastForegroundRejectUidState(int)\npublic @android.app.UidState int getLastBackgroundRejectUidState(int)\npublic long getAccessTime(int,int)\npublic long getRejectTime(int,int)\npublic long getDuration(int,int)\npublic int getProxyUid(int,int)\npublic @android.annotation.Nullable java.lang.String getProxyPackageName(int,int)\npublic @android.annotation.Nullable java.lang.String getProxyAttributionTag(int,int)\nclass OpAttributionEntry extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstructor=true)") 4398 @Deprecated 4399 private void __metadata() {} 4400 */ 4401 4402 4403 //@formatter:on 4404 // End of generated code 4405 4406 } 4407 4408 /** 4409 * Last {@link #noteOp} and {@link #startOp} events performed for a single op for all uidModes 4410 * and opFlags. 4411 * 4412 * @hide 4413 */ 4414 @Immutable 4415 @SystemApi 4416 // @DataClass(genHiddenConstructor = true) codegen verifier is broken 4417 public static final class OpEntry implements Parcelable { 4418 /** The code of the op */ 4419 private final @IntRange(from = 0, to = _NUM_OP - 1) int mOp; 4420 /** The mode of the op */ 4421 private final @Mode int mMode; 4422 /** The attributed entries by attribution tag */ 4423 private final @NonNull Map<String, AttributedOpEntry> mAttributedOpEntries; 4424 4425 /** 4426 * @hide 4427 */ 4428 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, publicAlternatives = "{@code " 4429 + "#getOpStr()}") getOp()4430 public int getOp() { 4431 return mOp; 4432 } 4433 4434 /** 4435 * @return This entry's op string name, such as {@link #OPSTR_COARSE_LOCATION}. 4436 */ getOpStr()4437 public @NonNull String getOpStr() { 4438 return sOpToString[mOp]; 4439 } 4440 4441 /** 4442 * @hide 4443 * 4444 * @deprecated Use {@link #getLastAccessTime(int)} instead 4445 */ 4446 @Deprecated 4447 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, publicAlternatives = "{@code " 4448 + "#getLastAccessTime(int)}") getTime()4449 public long getTime() { 4450 return getLastAccessTime(OP_FLAGS_ALL); 4451 } 4452 4453 /** 4454 * Return the last access time. 4455 * 4456 * @param flags The op flags 4457 * 4458 * @return the last access time (in milliseconds since epoch start (January 1, 1970 4459 * 00:00:00.000 GMT - Gregorian)) or {@code -1} if there was no access 4460 * 4461 * @see #getLastAccessForegroundTime(int) 4462 * @see #getLastAccessBackgroundTime(int) 4463 * @see #getLastAccessTime(int, int, int) 4464 * @see AttributedOpEntry#getLastAccessTime(int) 4465 */ getLastAccessTime(@pFlags int flags)4466 public long getLastAccessTime(@OpFlags int flags) { 4467 return getLastAccessTime(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, flags); 4468 } 4469 4470 /** 4471 * Return the last foreground access time. 4472 * 4473 * @param flags The op flags 4474 * 4475 * @return the last access time (in milliseconds since epoch start (January 1, 1970 4476 * 00:00:00.000 GMT - Gregorian)) or {@code -1} if there was no foreground access 4477 * 4478 * @see #getLastAccessTime(int) 4479 * @see #getLastAccessBackgroundTime(int) 4480 * @see #getLastAccessTime(int, int, int) 4481 * @see AttributedOpEntry#getLastAccessForegroundTime(int) 4482 */ getLastAccessForegroundTime(@pFlags int flags)4483 public long getLastAccessForegroundTime(@OpFlags int flags) { 4484 return getLastAccessTime(MAX_PRIORITY_UID_STATE, resolveFirstUnrestrictedUidState(mOp), 4485 flags); 4486 } 4487 4488 /** 4489 * Return the last background access time. 4490 * 4491 * @param flags The op flags 4492 * 4493 * @return the last access time (in milliseconds since epoch start (January 1, 1970 4494 * 00:00:00.000 GMT - Gregorian)) or {@code -1} if there was no background access 4495 * 4496 * @see #getLastAccessTime(int) 4497 * @see #getLastAccessForegroundTime(int) 4498 * @see #getLastAccessTime(int, int, int) 4499 * @see AttributedOpEntry#getLastAccessBackgroundTime(int) 4500 */ getLastAccessBackgroundTime(@pFlags int flags)4501 public long getLastAccessBackgroundTime(@OpFlags int flags) { 4502 return getLastAccessTime(resolveLastRestrictedUidState(mOp), MIN_PRIORITY_UID_STATE, 4503 flags); 4504 } 4505 4506 /** 4507 * Return the last access event. 4508 * 4509 * @param flags The op flags 4510 * 4511 * @return the last access event of {@code null} if there was no access 4512 */ getLastAccessEvent(@idState int fromUidState, @UidState int toUidState, @OpFlags int flags)4513 private @Nullable NoteOpEvent getLastAccessEvent(@UidState int fromUidState, 4514 @UidState int toUidState, @OpFlags int flags) { 4515 NoteOpEvent lastAccessEvent = null; 4516 for (AttributedOpEntry attributionEntry : mAttributedOpEntries.values()) { 4517 NoteOpEvent lastAttributionAccessEvent = attributionEntry.getLastAccessEvent( 4518 fromUidState, toUidState, flags); 4519 4520 if (lastAccessEvent == null || (lastAttributionAccessEvent != null 4521 && lastAttributionAccessEvent.getNoteTime() 4522 > lastAccessEvent.getNoteTime())) { 4523 lastAccessEvent = lastAttributionAccessEvent; 4524 } 4525 } 4526 4527 return lastAccessEvent; 4528 } 4529 4530 /** 4531 * Return the last access time. 4532 * 4533 * @param fromUidState the lowest uid state to query 4534 * @param toUidState the highest uid state to query (inclusive) 4535 * @param flags The op flags 4536 * 4537 * @return the last access time (in milliseconds since epoch start (January 1, 1970 4538 * 00:00:00.000 GMT - Gregorian)) or {@code -1} if there was no access 4539 * 4540 * @see #getLastAccessTime(int) 4541 * @see #getLastAccessForegroundTime(int) 4542 * @see #getLastAccessBackgroundTime(int) 4543 * @see AttributedOpEntry#getLastAccessTime(int, int, int) 4544 */ getLastAccessTime(@idState int fromUidState, @UidState int toUidState, @OpFlags int flags)4545 public long getLastAccessTime(@UidState int fromUidState, @UidState int toUidState, 4546 @OpFlags int flags) { 4547 NoteOpEvent lastEvent = getLastAccessEvent(fromUidState, toUidState, flags);; 4548 4549 if (lastEvent == null) { 4550 return -1; 4551 } 4552 4553 return lastEvent.getNoteTime(); 4554 } 4555 4556 /** 4557 * @hide 4558 * 4559 * @deprecated Use {@link #getLastRejectTime(int)} instead 4560 */ 4561 @Deprecated 4562 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, publicAlternatives = "{@code " 4563 + "#getLastRejectTime(int)}") getRejectTime()4564 public long getRejectTime() { 4565 return getLastRejectTime(OP_FLAGS_ALL); 4566 } 4567 4568 /** 4569 * Return the last rejection time. 4570 * 4571 * @param flags The op flags 4572 * 4573 * @return the last rejection time (in milliseconds since epoch start (January 1, 1970 4574 * 00:00:00.000 GMT - Gregorian)) or {@code -1} if there was no rejection 4575 * 4576 * @see #getLastRejectForegroundTime(int) 4577 * @see #getLastRejectBackgroundTime(int) 4578 * @see #getLastRejectTime(int, int, int) 4579 * @see AttributedOpEntry#getLastRejectTime(int) 4580 */ getLastRejectTime(@pFlags int flags)4581 public long getLastRejectTime(@OpFlags int flags) { 4582 return getLastRejectTime(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, flags); 4583 } 4584 4585 /** 4586 * Return the last foreground rejection time. 4587 * 4588 * @param flags The op flags 4589 * 4590 * @return the last rejection time (in milliseconds since epoch start (January 1, 1970 4591 * 00:00:00.000 GMT - Gregorian)) or {@code -1} if there was no foreground rejection 4592 * 4593 * @see #getLastRejectTime(int) 4594 * @see #getLastRejectBackgroundTime(int) 4595 * @see #getLastRejectTime(int, int, int) 4596 * @see AttributedOpEntry#getLastRejectForegroundTime(int) 4597 */ getLastRejectForegroundTime(@pFlags int flags)4598 public long getLastRejectForegroundTime(@OpFlags int flags) { 4599 return getLastRejectTime(MAX_PRIORITY_UID_STATE, resolveFirstUnrestrictedUidState(mOp), 4600 flags); 4601 } 4602 4603 /** 4604 * Return the last background rejection time. 4605 * 4606 * @param flags The op flags 4607 * 4608 * @return the last rejection time (in milliseconds since epoch start (January 1, 1970 4609 * 00:00:00.000 GMT - Gregorian)) or {@code -1} if there was no background rejection 4610 * 4611 * @see #getLastRejectTime(int) 4612 * @see #getLastRejectForegroundTime(int) 4613 * @see #getLastRejectTime(int, int, int) 4614 * @see AttributedOpEntry#getLastRejectBackgroundTime(int) 4615 */ getLastRejectBackgroundTime(@pFlags int flags)4616 public long getLastRejectBackgroundTime(@OpFlags int flags) { 4617 return getLastRejectTime(resolveLastRestrictedUidState(mOp), MIN_PRIORITY_UID_STATE, 4618 flags); 4619 } 4620 4621 /** 4622 * Return the last rejection event. 4623 * 4624 * @param flags The op flags 4625 * 4626 * @return the last reject event of {@code null} if there was no rejection 4627 */ getLastRejectEvent(@idState int fromUidState, @UidState int toUidState, @OpFlags int flags)4628 private @Nullable NoteOpEvent getLastRejectEvent(@UidState int fromUidState, 4629 @UidState int toUidState, @OpFlags int flags) { 4630 NoteOpEvent lastAccessEvent = null; 4631 for (AttributedOpEntry attributionEntry : mAttributedOpEntries.values()) { 4632 NoteOpEvent lastAttributionAccessEvent = attributionEntry.getLastRejectEvent( 4633 fromUidState, toUidState, flags); 4634 4635 if (lastAccessEvent == null || (lastAttributionAccessEvent != null 4636 && lastAttributionAccessEvent.getNoteTime() 4637 > lastAccessEvent.getNoteTime())) { 4638 lastAccessEvent = lastAttributionAccessEvent; 4639 } 4640 } 4641 4642 return lastAccessEvent; 4643 } 4644 4645 /** 4646 * Return the last rejection time. 4647 * 4648 * @param fromUidState the lowest uid state to query 4649 * @param toUidState the highest uid state to query (inclusive) 4650 * @param flags The op flags 4651 * 4652 * @return the last rejection time (in milliseconds since epoch start (January 1, 1970 4653 * 00:00:00.000 GMT - Gregorian)) or {@code -1} if there was no rejection 4654 * 4655 * @see #getLastRejectTime(int) 4656 * @see #getLastRejectForegroundTime(int) 4657 * @see #getLastRejectBackgroundTime(int) 4658 * @see #getLastRejectTime(int, int, int) 4659 * @see AttributedOpEntry#getLastRejectTime(int, int, int) 4660 */ getLastRejectTime(@idState int fromUidState, @UidState int toUidState, @OpFlags int flags)4661 public long getLastRejectTime(@UidState int fromUidState, @UidState int toUidState, 4662 @OpFlags int flags) { 4663 NoteOpEvent lastEvent = getLastRejectEvent(fromUidState, toUidState, flags); 4664 if (lastEvent == null) { 4665 return -1; 4666 } 4667 4668 return lastEvent.getNoteTime(); 4669 } 4670 4671 /** 4672 * @return Whether the operation is running. 4673 */ isRunning()4674 public boolean isRunning() { 4675 for (AttributedOpEntry opAttributionEntry : mAttributedOpEntries.values()) { 4676 if (opAttributionEntry.isRunning()) { 4677 return true; 4678 } 4679 } 4680 4681 return false; 4682 } 4683 4684 /** 4685 * @deprecated Use {@link #getLastDuration(int)} instead 4686 */ 4687 @Deprecated getDuration()4688 public long getDuration() { 4689 return getLastDuration(OP_FLAGS_ALL); 4690 } 4691 4692 /** 4693 * Return the duration in milliseconds of the last the access. 4694 * 4695 * @param flags The op flags 4696 * 4697 * @return the duration in milliseconds or {@code -1} if there was no access 4698 * 4699 * @see #getLastForegroundDuration(int) 4700 * @see #getLastBackgroundDuration(int) 4701 * @see #getLastDuration(int, int, int) 4702 * @see AttributedOpEntry#getLastDuration(int) 4703 */ getLastDuration(@pFlags int flags)4704 public long getLastDuration(@OpFlags int flags) { 4705 return getLastDuration(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, flags); 4706 } 4707 4708 /** 4709 * Return the duration in milliseconds of the last foreground access. 4710 * 4711 * @param flags The op flags 4712 * 4713 * @return the duration in milliseconds or {@code -1} if there was no foreground access 4714 * 4715 * @see #getLastDuration(int) 4716 * @see #getLastBackgroundDuration(int) 4717 * @see #getLastDuration(int, int, int) 4718 * @see AttributedOpEntry#getLastForegroundDuration(int) 4719 */ getLastForegroundDuration(@pFlags int flags)4720 public long getLastForegroundDuration(@OpFlags int flags) { 4721 return getLastDuration(MAX_PRIORITY_UID_STATE, resolveFirstUnrestrictedUidState(mOp), 4722 flags); 4723 } 4724 4725 /** 4726 * Return the duration in milliseconds of the last background access. 4727 * 4728 * @param flags The op flags 4729 * 4730 * @return the duration in milliseconds or {@code -1} if there was no background access 4731 * 4732 * @see #getLastDuration(int) 4733 * @see #getLastForegroundDuration(int) 4734 * @see #getLastDuration(int, int, int) 4735 * @see AttributedOpEntry#getLastBackgroundDuration(int) 4736 */ getLastBackgroundDuration(@pFlags int flags)4737 public long getLastBackgroundDuration(@OpFlags int flags) { 4738 return getLastDuration(resolveLastRestrictedUidState(mOp), MIN_PRIORITY_UID_STATE, 4739 flags); 4740 } 4741 4742 /** 4743 * Return the duration in milliseconds of the last access. 4744 * 4745 * @param fromUidState The lowest UID state for which to query 4746 * @param toUidState The highest UID state for which to query (inclusive) 4747 * @param flags The op flags 4748 * 4749 * @return the duration in milliseconds or {@code -1} if there was no access 4750 * 4751 * @see #getLastDuration(int) 4752 * @see #getLastForegroundDuration(int) 4753 * @see #getLastBackgroundDuration(int) 4754 * @see AttributedOpEntry#getLastDuration(int, int, int) 4755 */ getLastDuration(@idState int fromUidState, @UidState int toUidState, @OpFlags int flags)4756 public long getLastDuration(@UidState int fromUidState, @UidState int toUidState, 4757 @OpFlags int flags) { 4758 NoteOpEvent lastEvent = getLastAccessEvent(fromUidState, toUidState, flags); 4759 if (lastEvent == null) { 4760 return -1; 4761 } 4762 4763 return lastEvent.getDuration(); 4764 } 4765 4766 /** 4767 * @deprecated Use {@link #getLastProxyInfo(int)} instead 4768 */ 4769 @Deprecated getProxyUid()4770 public int getProxyUid() { 4771 OpEventProxyInfo proxy = getLastProxyInfo(OP_FLAGS_ALL); 4772 if (proxy == null) { 4773 return Process.INVALID_UID; 4774 } 4775 4776 return proxy.getUid(); 4777 } 4778 4779 /** 4780 * @deprecated Use {@link #getLastProxyInfo(int)} instead 4781 */ 4782 @Deprecated getProxyUid(@idState int uidState, @OpFlags int flags)4783 public int getProxyUid(@UidState int uidState, @OpFlags int flags) { 4784 OpEventProxyInfo proxy = getLastProxyInfo(uidState, uidState, flags); 4785 if (proxy == null) { 4786 return Process.INVALID_UID; 4787 } 4788 4789 return proxy.getUid(); 4790 } 4791 4792 /** 4793 * @deprecated Use {@link #getLastProxyInfo(int)} instead 4794 */ 4795 @Deprecated getProxyPackageName()4796 public @Nullable String getProxyPackageName() { 4797 OpEventProxyInfo proxy = getLastProxyInfo(OP_FLAGS_ALL); 4798 if (proxy == null) { 4799 return null; 4800 } 4801 4802 return proxy.getPackageName(); 4803 } 4804 4805 /** 4806 * @deprecated Use {@link #getLastProxyInfo(int)} instead 4807 */ 4808 @Deprecated getProxyPackageName(@idState int uidState, @OpFlags int flags)4809 public @Nullable String getProxyPackageName(@UidState int uidState, @OpFlags int flags) { 4810 OpEventProxyInfo proxy = getLastProxyInfo(uidState, uidState, flags); 4811 if (proxy == null) { 4812 return null; 4813 } 4814 4815 return proxy.getPackageName(); 4816 } 4817 4818 /** 4819 * Gets the proxy info of the app that performed the last access on behalf of this app and 4820 * as a result blamed the op on this app. 4821 * 4822 * @param flags The op flags 4823 * 4824 * @return The proxy info or {@code null} if there was no proxy access 4825 * 4826 * @see #getLastForegroundProxyInfo(int) 4827 * @see #getLastBackgroundProxyInfo(int) 4828 * @see #getLastProxyInfo(int, int, int) 4829 * @see AttributedOpEntry#getLastProxyInfo(int) 4830 */ getLastProxyInfo(@pFlags int flags)4831 public @Nullable OpEventProxyInfo getLastProxyInfo(@OpFlags int flags) { 4832 return getLastProxyInfo(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, flags); 4833 } 4834 4835 /** 4836 * Gets the proxy info of the app that performed the last foreground access on behalf of 4837 * this app and as a result blamed the op on this app. 4838 * 4839 * @param flags The op flags 4840 * 4841 * @return The proxy info or {@code null} if there was no foreground proxy access 4842 * 4843 * @see #getLastProxyInfo(int) 4844 * @see #getLastBackgroundProxyInfo(int) 4845 * @see #getLastProxyInfo(int, int, int) 4846 * @see AttributedOpEntry#getLastForegroundProxyInfo(int) 4847 */ getLastForegroundProxyInfo(@pFlags int flags)4848 public @Nullable OpEventProxyInfo getLastForegroundProxyInfo(@OpFlags int flags) { 4849 return getLastProxyInfo(MAX_PRIORITY_UID_STATE, resolveFirstUnrestrictedUidState(mOp), 4850 flags); 4851 } 4852 4853 /** 4854 * Gets the proxy info of the app that performed the last background access on behalf of 4855 * this app and as a result blamed the op on this app. 4856 * 4857 * @param flags The op flags 4858 * 4859 * @return The proxy info or {@code null} if there was no background proxy access 4860 * 4861 * @see #getLastProxyInfo(int) 4862 * @see #getLastForegroundProxyInfo(int) 4863 * @see #getLastProxyInfo(int, int, int) 4864 * @see AttributedOpEntry#getLastBackgroundProxyInfo(int) 4865 */ getLastBackgroundProxyInfo(@pFlags int flags)4866 public @Nullable OpEventProxyInfo getLastBackgroundProxyInfo(@OpFlags int flags) { 4867 return getLastProxyInfo(resolveLastRestrictedUidState(mOp), MIN_PRIORITY_UID_STATE, 4868 flags); 4869 } 4870 4871 /** 4872 * Gets the proxy info of the app that performed the last access on behalf of this app and 4873 * as a result blamed the op on this app. 4874 * 4875 * @param fromUidState The lowest UID state for which to query 4876 * @param toUidState The highest UID state for which to query (inclusive) 4877 * @param flags The op flags 4878 * 4879 * @return The proxy info or {@code null} if there was no proxy access 4880 * 4881 * @see #getLastProxyInfo(int) 4882 * @see #getLastForegroundProxyInfo(int) 4883 * @see #getLastBackgroundProxyInfo(int) 4884 * @see AttributedOpEntry#getLastProxyInfo(int, int, int) 4885 */ getLastProxyInfo(@idState int fromUidState, @UidState int toUidState, @OpFlags int flags)4886 public @Nullable OpEventProxyInfo getLastProxyInfo(@UidState int fromUidState, 4887 @UidState int toUidState, @OpFlags int flags) { 4888 NoteOpEvent lastEvent = getLastAccessEvent(fromUidState, toUidState, flags); 4889 if (lastEvent == null) { 4890 return null; 4891 } 4892 4893 return lastEvent.getProxy(); 4894 } 4895 4896 4897 4898 // Code below generated by codegen v1.0.14. 4899 // 4900 // DO NOT MODIFY! 4901 // CHECKSTYLE:OFF Generated code 4902 // 4903 // To regenerate run: 4904 // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/app/AppOpsManager.java 4905 // 4906 // To exclude the generated code from IntelliJ auto-formatting enable (one-time): 4907 // Settings > Editor > Code Style > Formatter Control 4908 //@formatter:off 4909 4910 4911 /** 4912 * Creates a new OpEntry. 4913 * 4914 * @param op 4915 * The code of the op 4916 * @param mode 4917 * The mode of the op 4918 * @param attributedOpEntries 4919 * The attributions that have been used when noting the op 4920 * @hide 4921 */ 4922 @DataClass.Generated.Member OpEntry( @ntRangefrom = 0, to = _NUM_OP - 1) int op, @Mode int mode, @NonNull Map<String, AttributedOpEntry> attributedOpEntries)4923 public OpEntry( 4924 @IntRange(from = 0, to = _NUM_OP - 1) int op, 4925 @Mode int mode, 4926 @NonNull Map<String, AttributedOpEntry> attributedOpEntries) { 4927 this.mOp = op; 4928 com.android.internal.util.AnnotationValidations.validate( 4929 IntRange.class, null, mOp, 4930 "from", 0, 4931 "to", _NUM_OP - 1); 4932 this.mMode = mode; 4933 com.android.internal.util.AnnotationValidations.validate( 4934 Mode.class, null, mMode); 4935 this.mAttributedOpEntries = attributedOpEntries; 4936 com.android.internal.util.AnnotationValidations.validate( 4937 NonNull.class, null, mAttributedOpEntries); 4938 4939 // onConstructed(); // You can define this method to get a callback 4940 } 4941 4942 /** 4943 * The mode of the op 4944 */ 4945 @DataClass.Generated.Member getMode()4946 public @Mode int getMode() { 4947 return mMode; 4948 } 4949 4950 /** 4951 * The attributed entries keyed by attribution tag. 4952 * 4953 * @see Context#createAttributionContext(String) 4954 * @see #noteOp(String, int, String, String, String) 4955 */ 4956 @DataClass.Generated.Member getAttributedOpEntries()4957 public @NonNull Map<String, AttributedOpEntry> getAttributedOpEntries() { 4958 return mAttributedOpEntries; 4959 } 4960 4961 @Override 4962 @DataClass.Generated.Member writeToParcel(Parcel dest, int flags)4963 public void writeToParcel(Parcel dest, int flags) { 4964 // You can override field parcelling by defining methods like: 4965 // void parcelFieldName(Parcel dest, int flags) { ... } 4966 4967 dest.writeInt(mOp); 4968 dest.writeInt(mMode); 4969 dest.writeMap(mAttributedOpEntries); 4970 } 4971 4972 @Override 4973 @DataClass.Generated.Member describeContents()4974 public int describeContents() { return 0; } 4975 4976 /** @hide */ 4977 @SuppressWarnings({"unchecked", "RedundantCast"}) 4978 @DataClass.Generated.Member OpEntry(@onNull Parcel in)4979 /* package-private */ OpEntry(@NonNull Parcel in) { 4980 // You can override field unparcelling by defining methods like: 4981 // static FieldType unparcelFieldName(Parcel in) { ... } 4982 4983 int op = in.readInt(); 4984 int mode = in.readInt(); 4985 Map<String, AttributedOpEntry> attributions = new java.util.LinkedHashMap<>(); 4986 in.readMap(attributions, AttributedOpEntry.class.getClassLoader()); 4987 4988 this.mOp = op; 4989 com.android.internal.util.AnnotationValidations.validate( 4990 IntRange.class, null, mOp, 4991 "from", 0, 4992 "to", _NUM_OP - 1); 4993 this.mMode = mode; 4994 com.android.internal.util.AnnotationValidations.validate( 4995 Mode.class, null, mMode); 4996 this.mAttributedOpEntries = attributions; 4997 com.android.internal.util.AnnotationValidations.validate( 4998 NonNull.class, null, mAttributedOpEntries); 4999 5000 // onConstructed(); // You can define this method to get a callback 5001 } 5002 5003 @DataClass.Generated.Member 5004 public static final @NonNull Parcelable.Creator<OpEntry> CREATOR 5005 = new Parcelable.Creator<OpEntry>() { 5006 @Override 5007 public OpEntry[] newArray(int size) { 5008 return new OpEntry[size]; 5009 } 5010 5011 @Override 5012 public OpEntry createFromParcel(@NonNull Parcel in) { 5013 return new OpEntry(in); 5014 } 5015 }; 5016 5017 /* 5018 @DataClass.Generated( 5019 time = 1574809856259L, 5020 codegenVersion = "1.0.14", 5021 sourceFile = "frameworks/base/core/java/android/app/AppOpsManager.java", 5022 inputSignatures = "private final @android.annotation.IntRange(from=0L, to=_NUM_OP - 1) int mOp\nprivate final @android.app.Mode int mMode\nprivate final @android.annotation.NonNull java.util.Map<java.lang.String,android.app.OpAttributionEntry> mAttributions\npublic @android.annotation.UnsupportedAppUsage(maxTargetSdk=Build.VERSION_CODES.Q, publicAlternatives=\"{@code \" + \"#getOpStr()}\") int getOp()\npublic @android.annotation.NonNull java.lang.String getOpStr()\npublic @java.lang.Deprecated @android.annotation.UnsupportedAppUsage(maxTargetSdk=Build.VERSION_CODES.Q, publicAlternatives=\"{@code \" + \"#getAccessTime(int, int)}\") long getTime()\npublic @java.lang.Deprecated long getLastAccessTime(int)\npublic @java.lang.Deprecated long getLastAccessForegroundTime(int)\npublic @java.lang.Deprecated long getLastAccessBackgroundTime(int)\npublic @java.lang.Deprecated long getLastAccessTime(int,int,int)\npublic @java.lang.Deprecated @android.annotation.UnsupportedAppUsage(maxTargetSdk=Build.VERSION_CODES.Q, publicAlternatives=\"{@code \" + \"#getLastRejectTime(int, int, int)}\") long getRejectTime()\npublic @java.lang.Deprecated long getLastRejectTime(int)\npublic @java.lang.Deprecated long getLastRejectForegroundTime(int)\npublic @java.lang.Deprecated long getLastRejectBackgroundTime(int)\npublic @java.lang.Deprecated long getLastRejectTime(int,int,int)\npublic long getAccessTime(int,int)\npublic long getRejectTime(int,int)\npublic boolean isRunning()\nprivate android.app.NoteOpEvent getLastAccessEvent(int,int,int)\npublic @java.lang.Deprecated long getDuration()\npublic @java.lang.Deprecated long getLastForegroundDuration(int)\npublic @java.lang.Deprecated long getLastBackgroundDuration(int)\npublic @java.lang.Deprecated long getLastDuration(int,int,int)\npublic @java.lang.Deprecated int getProxyUid()\npublic @java.lang.Deprecated @android.annotation.Nullable java.lang.String getProxyPackageName()\nprivate @android.app.UidState int getLastAccessUidStateForFlagsInStatesOfAllAttributions(int,int,int)\npublic @android.app.UidState int getLastAccessUidState(int)\npublic @android.app.UidState int getLastForegroundAccessUidState(int)\npublic @android.app.UidState int getLastBackgroundAccessUidState(int)\nprivate @android.app.UidState int getLastRejectUidStateForFlagsInStatesOfAllAttributions(int,int,int)\npublic @android.app.UidState int getLastRejectUidState(int)\npublic @android.app.UidState int getLastForegroundRejectUidState(int)\npublic @android.app.UidState int getLastBackgroundRejectUidState(int)\npublic long getDuration(int,int)\npublic int getProxyUid(int,int)\nprivate int getProxyUid(int,int,int)\npublic @android.annotation.Nullable java.lang.String getProxyPackageName(int,int)\nprivate @android.annotation.Nullable java.lang.String getProxyPackageName(int,int,int)\nclass OpEntry extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstructor=true)") 5023 @Deprecated 5024 private void __metadata() {} 5025 */ 5026 5027 5028 //@formatter:on 5029 // End of generated code 5030 5031 } 5032 5033 /** @hide */ 5034 public interface HistoricalOpsVisitor { visitHistoricalOps(@onNull HistoricalOps ops)5035 void visitHistoricalOps(@NonNull HistoricalOps ops); visitHistoricalUidOps(@onNull HistoricalUidOps ops)5036 void visitHistoricalUidOps(@NonNull HistoricalUidOps ops); visitHistoricalPackageOps(@onNull HistoricalPackageOps ops)5037 void visitHistoricalPackageOps(@NonNull HistoricalPackageOps ops); visitHistoricalAttributionOps(@onNull AttributedHistoricalOps ops)5038 void visitHistoricalAttributionOps(@NonNull AttributedHistoricalOps ops); visitHistoricalOp(@onNull HistoricalOp ops)5039 void visitHistoricalOp(@NonNull HistoricalOp ops); 5040 } 5041 5042 /** 5043 * Flag for querying app op history: get only aggregate information (counts of events) and no 5044 * discret accesses information - specific accesses with timestamp. 5045 * 5046 * @see #getHistoricalOps(HistoricalOpsRequest, Executor, Consumer) 5047 * 5048 * @hide 5049 */ 5050 @TestApi 5051 @SystemApi 5052 public static final int HISTORY_FLAG_AGGREGATE = 1 << 0; 5053 5054 /** 5055 * Flag for querying app op history: get only discrete access information (only specific 5056 * accesses with timestamps) and no aggregate information (counts over time). 5057 * 5058 * @see #getHistoricalOps(HistoricalOpsRequest, Executor, Consumer) 5059 * 5060 * @hide 5061 */ 5062 @TestApi 5063 @SystemApi 5064 public static final int HISTORY_FLAG_DISCRETE = 1 << 1; 5065 5066 /** 5067 * Flag for querying app op history: assemble attribution chains, and attach the last visible 5068 * node in the chain to the start as a proxy info. This only applies to discrete accesses. 5069 * 5070 * TODO 191512294: Add to @SystemApi 5071 * 5072 * @hide 5073 */ 5074 public static final int HISTORY_FLAG_GET_ATTRIBUTION_CHAINS = 1 << 2; 5075 5076 /** 5077 * Flag for querying app op history: get all types of historical access information. 5078 * 5079 * @see #getHistoricalOps(HistoricalOpsRequest, Executor, Consumer) 5080 * 5081 * @hide 5082 */ 5083 @TestApi 5084 @SystemApi 5085 public static final int HISTORY_FLAGS_ALL = HISTORY_FLAG_AGGREGATE 5086 | HISTORY_FLAG_DISCRETE; 5087 5088 /** @hide */ 5089 @Retention(RetentionPolicy.SOURCE) 5090 @IntDef(flag = true, prefix = { "HISTORY_FLAG_" }, value = { 5091 HISTORY_FLAG_AGGREGATE, 5092 HISTORY_FLAG_DISCRETE, 5093 HISTORY_FLAG_GET_ATTRIBUTION_CHAINS 5094 }) 5095 public @interface OpHistoryFlags {} 5096 5097 /** 5098 * Specifies what parameters to filter historical appop requests for 5099 * 5100 * @hide 5101 */ 5102 @Retention(RetentionPolicy.SOURCE) 5103 @IntDef(flag = true, prefix = { "FILTER_BY_" }, value = { 5104 FILTER_BY_UID, 5105 FILTER_BY_PACKAGE_NAME, 5106 FILTER_BY_ATTRIBUTION_TAG, 5107 FILTER_BY_OP_NAMES 5108 }) 5109 public @interface HistoricalOpsRequestFilter {} 5110 5111 /** 5112 * Filter historical appop request by uid. 5113 * 5114 * @hide 5115 */ 5116 public static final int FILTER_BY_UID = 1<<0; 5117 5118 /** 5119 * Filter historical appop request by package name. 5120 * 5121 * @hide 5122 */ 5123 public static final int FILTER_BY_PACKAGE_NAME = 1<<1; 5124 5125 /** 5126 * Filter historical appop request by attribution tag. 5127 * 5128 * @hide 5129 */ 5130 public static final int FILTER_BY_ATTRIBUTION_TAG = 1<<2; 5131 5132 /** 5133 * Filter historical appop request by op names. 5134 * 5135 * @hide 5136 */ 5137 public static final int FILTER_BY_OP_NAMES = 1<<3; 5138 5139 /** 5140 * Request for getting historical app op usage. The request acts 5141 * as a filtering criteria when querying historical op usage. 5142 * 5143 * @hide 5144 */ 5145 @Immutable 5146 @SystemApi 5147 public static final class HistoricalOpsRequest { 5148 private final int mUid; 5149 private final @Nullable String mPackageName; 5150 private final @Nullable String mAttributionTag; 5151 private final @Nullable List<String> mOpNames; 5152 private final @OpHistoryFlags int mHistoryFlags; 5153 private final @HistoricalOpsRequestFilter int mFilter; 5154 private final long mBeginTimeMillis; 5155 private final long mEndTimeMillis; 5156 private final @OpFlags int mFlags; 5157 HistoricalOpsRequest(int uid, @Nullable String packageName, @Nullable String attributionTag, @Nullable List<String> opNames, @OpHistoryFlags int historyFlags, @HistoricalOpsRequestFilter int filter, long beginTimeMillis, long endTimeMillis, @OpFlags int flags)5158 private HistoricalOpsRequest(int uid, @Nullable String packageName, 5159 @Nullable String attributionTag, @Nullable List<String> opNames, 5160 @OpHistoryFlags int historyFlags, @HistoricalOpsRequestFilter int filter, 5161 long beginTimeMillis, long endTimeMillis, @OpFlags int flags) { 5162 mUid = uid; 5163 mPackageName = packageName; 5164 mAttributionTag = attributionTag; 5165 mOpNames = opNames; 5166 mHistoryFlags = historyFlags; 5167 mFilter = filter; 5168 mBeginTimeMillis = beginTimeMillis; 5169 mEndTimeMillis = endTimeMillis; 5170 mFlags = flags; 5171 } 5172 5173 /** 5174 * Builder for creating a {@link HistoricalOpsRequest}. 5175 * 5176 * @hide 5177 */ 5178 @SystemApi 5179 public static final class Builder { 5180 private int mUid = Process.INVALID_UID; 5181 private @Nullable String mPackageName; 5182 private @Nullable String mAttributionTag; 5183 private @Nullable List<String> mOpNames; 5184 private @OpHistoryFlags int mHistoryFlags; 5185 private @HistoricalOpsRequestFilter int mFilter; 5186 private final long mBeginTimeMillis; 5187 private final long mEndTimeMillis; 5188 private @OpFlags int mFlags = OP_FLAGS_ALL; 5189 5190 /** 5191 * Creates a new builder. 5192 * 5193 * @param beginTimeMillis The beginning of the interval in milliseconds since 5194 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). Must be non 5195 * negative. 5196 * @param endTimeMillis The end of the interval in milliseconds since 5197 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). Must be after 5198 * {@code beginTimeMillis}. Pass {@link Long#MAX_VALUE} to get the most recent 5199 * history including ops that happen while this call is in flight. 5200 */ Builder(long beginTimeMillis, long endTimeMillis)5201 public Builder(long beginTimeMillis, long endTimeMillis) { 5202 Preconditions.checkArgument(beginTimeMillis >= 0 && beginTimeMillis < endTimeMillis, 5203 "beginTimeMillis must be non negative and lesser than endTimeMillis"); 5204 mBeginTimeMillis = beginTimeMillis; 5205 mEndTimeMillis = endTimeMillis; 5206 mHistoryFlags = HISTORY_FLAG_AGGREGATE; 5207 } 5208 5209 /** 5210 * Sets the UID to query for. 5211 * 5212 * @param uid The uid. Pass {@link android.os.Process#INVALID_UID} for any uid. 5213 * @return This builder. 5214 */ setUid(int uid)5215 public @NonNull Builder setUid(int uid) { 5216 Preconditions.checkArgument(uid == Process.INVALID_UID || uid >= 0, 5217 "uid must be " + Process.INVALID_UID + " or non negative"); 5218 mUid = uid; 5219 5220 if (uid == Process.INVALID_UID) { 5221 mFilter &= ~FILTER_BY_UID; 5222 } else { 5223 mFilter |= FILTER_BY_UID; 5224 } 5225 5226 return this; 5227 } 5228 5229 /** 5230 * Sets the package to query for. 5231 * 5232 * @param packageName The package name. <code>Null</code> for any package. 5233 * @return This builder. 5234 */ setPackageName(@ullable String packageName)5235 public @NonNull Builder setPackageName(@Nullable String packageName) { 5236 mPackageName = packageName; 5237 5238 if (packageName == null) { 5239 mFilter &= ~FILTER_BY_PACKAGE_NAME; 5240 } else { 5241 mFilter |= FILTER_BY_PACKAGE_NAME; 5242 } 5243 5244 return this; 5245 } 5246 5247 /** 5248 * Sets the attribution tag to query for. 5249 * 5250 * @param attributionTag attribution tag 5251 * @return This builder. 5252 */ setAttributionTag(@ullable String attributionTag)5253 public @NonNull Builder setAttributionTag(@Nullable String attributionTag) { 5254 mAttributionTag = attributionTag; 5255 mFilter |= FILTER_BY_ATTRIBUTION_TAG; 5256 5257 return this; 5258 } 5259 5260 /** 5261 * Sets the op names to query for. 5262 * 5263 * @param opNames The op names. <code>Null</code> for any op. 5264 * @return This builder. 5265 */ setOpNames(@ullable List<String> opNames)5266 public @NonNull Builder setOpNames(@Nullable List<String> opNames) { 5267 if (opNames != null) { 5268 final int opCount = opNames.size(); 5269 for (int i = 0; i < opCount; i++) { 5270 Preconditions.checkArgument(AppOpsManager.strOpToOp( 5271 opNames.get(i)) != AppOpsManager.OP_NONE); 5272 } 5273 } 5274 mOpNames = opNames; 5275 5276 if (mOpNames == null) { 5277 mFilter &= ~FILTER_BY_OP_NAMES; 5278 } else { 5279 mFilter |= FILTER_BY_OP_NAMES; 5280 } 5281 5282 return this; 5283 } 5284 5285 /** 5286 * Sets the op flags to query for. The flags specify the type of 5287 * op data being queried. 5288 * 5289 * @param flags The flags which are any combination of 5290 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 5291 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 5292 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 5293 * for any flag. 5294 * @return This builder. 5295 */ setFlags(@pFlags int flags)5296 public @NonNull Builder setFlags(@OpFlags int flags) { 5297 Preconditions.checkFlagsArgument(flags, OP_FLAGS_ALL); 5298 mFlags = flags; 5299 return this; 5300 } 5301 5302 /** 5303 * Specifies what type of historical information to query. 5304 * 5305 * @param flags Flags for the historical types to fetch which are any 5306 * combination of {@link #HISTORY_FLAG_AGGREGATE}, {@link #HISTORY_FLAG_DISCRETE}, 5307 * {@link #HISTORY_FLAGS_ALL}. The default is {@link #HISTORY_FLAG_AGGREGATE}. 5308 * @return This builder. 5309 */ setHistoryFlags(@pHistoryFlags int flags)5310 public @NonNull Builder setHistoryFlags(@OpHistoryFlags int flags) { 5311 Preconditions.checkFlagsArgument(flags, 5312 HISTORY_FLAGS_ALL | HISTORY_FLAG_GET_ATTRIBUTION_CHAINS); 5313 mHistoryFlags = flags; 5314 return this; 5315 } 5316 5317 /** 5318 * @return a new {@link HistoricalOpsRequest}. 5319 */ build()5320 public @NonNull HistoricalOpsRequest build() { 5321 return new HistoricalOpsRequest(mUid, mPackageName, mAttributionTag, mOpNames, 5322 mHistoryFlags, mFilter, mBeginTimeMillis, mEndTimeMillis, mFlags); 5323 } 5324 } 5325 } 5326 5327 /** 5328 * This class represents historical app op state of all UIDs for a given time interval. 5329 * 5330 * @hide 5331 */ 5332 @SystemApi 5333 public static final class HistoricalOps implements Parcelable { 5334 private long mBeginTimeMillis; 5335 private long mEndTimeMillis; 5336 private @Nullable SparseArray<HistoricalUidOps> mHistoricalUidOps; 5337 5338 /** @hide */ 5339 @TestApi HistoricalOps(long beginTimeMillis, long endTimeMillis)5340 public HistoricalOps(long beginTimeMillis, long endTimeMillis) { 5341 Preconditions.checkState(beginTimeMillis <= endTimeMillis); 5342 mBeginTimeMillis = beginTimeMillis; 5343 mEndTimeMillis = endTimeMillis; 5344 } 5345 5346 /** @hide */ HistoricalOps(@onNull HistoricalOps other)5347 public HistoricalOps(@NonNull HistoricalOps other) { 5348 mBeginTimeMillis = other.mBeginTimeMillis; 5349 mEndTimeMillis = other.mEndTimeMillis; 5350 Preconditions.checkState(mBeginTimeMillis <= mEndTimeMillis); 5351 if (other.mHistoricalUidOps != null) { 5352 final int opCount = other.getUidCount(); 5353 for (int i = 0; i < opCount; i++) { 5354 final HistoricalUidOps origOps = other.getUidOpsAt(i); 5355 final HistoricalUidOps clonedOps = new HistoricalUidOps(origOps); 5356 if (mHistoricalUidOps == null) { 5357 mHistoricalUidOps = new SparseArray<>(opCount); 5358 } 5359 mHistoricalUidOps.put(clonedOps.getUid(), clonedOps); 5360 } 5361 } 5362 } 5363 HistoricalOps(Parcel parcel)5364 private HistoricalOps(Parcel parcel) { 5365 mBeginTimeMillis = parcel.readLong(); 5366 mEndTimeMillis = parcel.readLong(); 5367 final int[] uids = parcel.createIntArray(); 5368 if (!ArrayUtils.isEmpty(uids)) { 5369 final ParceledListSlice<HistoricalUidOps> listSlice = parcel.readParcelable( 5370 HistoricalOps.class.getClassLoader(), android.content.pm.ParceledListSlice.class); 5371 final List<HistoricalUidOps> uidOps = (listSlice != null) 5372 ? listSlice.getList() : null; 5373 if (uidOps == null) { 5374 return; 5375 } 5376 for (int i = 0; i < uids.length; i++) { 5377 if (mHistoricalUidOps == null) { 5378 mHistoricalUidOps = new SparseArray<>(); 5379 } 5380 mHistoricalUidOps.put(uids[i], uidOps.get(i)); 5381 } 5382 } 5383 } 5384 5385 /** 5386 * Splice a piece from the beginning of these ops. 5387 * 5388 * @param splicePoint The fraction of the data to be spliced off. 5389 * 5390 * @hide 5391 */ spliceFromBeginning(double splicePoint)5392 public @NonNull HistoricalOps spliceFromBeginning(double splicePoint) { 5393 return splice(splicePoint, true); 5394 } 5395 5396 /** 5397 * Splice a piece from the end of these ops. 5398 * 5399 * @param fractionToRemove The fraction of the data to be spliced off. 5400 * 5401 * @hide 5402 */ spliceFromEnd(double fractionToRemove)5403 public @NonNull HistoricalOps spliceFromEnd(double fractionToRemove) { 5404 return splice(fractionToRemove, false); 5405 } 5406 5407 /** 5408 * Splice a piece from the beginning or end of these ops. 5409 * 5410 * @param fractionToRemove The fraction of the data to be spliced off. 5411 * @param beginning Whether to splice off the beginning or the end. 5412 * 5413 * @return The spliced off part. 5414 * 5415 * @hide 5416 */ splice(double fractionToRemove, boolean beginning)5417 private @Nullable HistoricalOps splice(double fractionToRemove, boolean beginning) { 5418 final long spliceBeginTimeMills; 5419 final long spliceEndTimeMills; 5420 if (beginning) { 5421 spliceBeginTimeMills = mBeginTimeMillis; 5422 spliceEndTimeMills = (long) (mBeginTimeMillis 5423 + getDurationMillis() * fractionToRemove); 5424 mBeginTimeMillis = spliceEndTimeMills; 5425 } else { 5426 spliceBeginTimeMills = (long) (mEndTimeMillis 5427 - getDurationMillis() * fractionToRemove); 5428 spliceEndTimeMills = mEndTimeMillis; 5429 mEndTimeMillis = spliceBeginTimeMills; 5430 } 5431 5432 HistoricalOps splice = null; 5433 final int uidCount = getUidCount(); 5434 for (int i = 0; i < uidCount; i++) { 5435 final HistoricalUidOps origOps = getUidOpsAt(i); 5436 final HistoricalUidOps spliceOps = origOps.splice(fractionToRemove); 5437 if (spliceOps != null) { 5438 if (splice == null) { 5439 splice = new HistoricalOps(spliceBeginTimeMills, spliceEndTimeMills); 5440 } 5441 if (splice.mHistoricalUidOps == null) { 5442 splice.mHistoricalUidOps = new SparseArray<>(); 5443 } 5444 splice.mHistoricalUidOps.put(spliceOps.getUid(), spliceOps); 5445 } 5446 } 5447 return splice; 5448 } 5449 5450 /** 5451 * Merge the passed ops into the current ones. The time interval is a 5452 * union of the current and passed in one and the passed in data is 5453 * folded into the data of this instance. 5454 * 5455 * @hide 5456 */ merge(@onNull HistoricalOps other)5457 public void merge(@NonNull HistoricalOps other) { 5458 mBeginTimeMillis = Math.min(mBeginTimeMillis, other.mBeginTimeMillis); 5459 mEndTimeMillis = Math.max(mEndTimeMillis, other.mEndTimeMillis); 5460 final int uidCount = other.getUidCount(); 5461 for (int i = 0; i < uidCount; i++) { 5462 final HistoricalUidOps otherUidOps = other.getUidOpsAt(i); 5463 final HistoricalUidOps thisUidOps = getUidOps(otherUidOps.getUid()); 5464 if (thisUidOps != null) { 5465 thisUidOps.merge(otherUidOps); 5466 } else { 5467 if (mHistoricalUidOps == null) { 5468 mHistoricalUidOps = new SparseArray<>(); 5469 } 5470 mHistoricalUidOps.put(otherUidOps.getUid(), otherUidOps); 5471 } 5472 } 5473 } 5474 5475 /** 5476 * AppPermissionUsage the ops to leave only the data we filter for. 5477 * 5478 * @param uid Uid to filter for. 5479 * @param packageName Package to filter for. 5480 * @param attributionTag attribution tag to filter for 5481 * @param opNames Ops to filter for. 5482 * @param filter Which parameters to filter on. 5483 * @param beginTimeMillis The begin time to filter for or {@link Long#MIN_VALUE} for all. 5484 * @param endTimeMillis The end time to filter for or {@link Long#MAX_VALUE} for all. 5485 * 5486 * @hide 5487 */ filter(int uid, @Nullable String packageName, @Nullable String attributionTag, @Nullable String[] opNames, @OpHistoryFlags int historyFilter, @HistoricalOpsRequestFilter int filter, long beginTimeMillis, long endTimeMillis)5488 public void filter(int uid, @Nullable String packageName, @Nullable String attributionTag, 5489 @Nullable String[] opNames, @OpHistoryFlags int historyFilter, 5490 @HistoricalOpsRequestFilter int filter, 5491 long beginTimeMillis, long endTimeMillis) { 5492 final long durationMillis = getDurationMillis(); 5493 mBeginTimeMillis = Math.max(mBeginTimeMillis, beginTimeMillis); 5494 mEndTimeMillis = Math.min(mEndTimeMillis, endTimeMillis); 5495 final double scaleFactor = Math.min((double) (endTimeMillis - beginTimeMillis) 5496 / (double) durationMillis, 1); 5497 final int uidCount = getUidCount(); 5498 for (int i = uidCount - 1; i >= 0; i--) { 5499 final HistoricalUidOps uidOp = mHistoricalUidOps.valueAt(i); 5500 if ((filter & FILTER_BY_UID) != 0 && uid != uidOp.getUid()) { 5501 mHistoricalUidOps.removeAt(i); 5502 } else { 5503 uidOp.filter(packageName, attributionTag, opNames, filter, historyFilter, 5504 scaleFactor, mBeginTimeMillis, mEndTimeMillis); 5505 if (uidOp.getPackageCount() == 0) { 5506 mHistoricalUidOps.removeAt(i); 5507 } 5508 } 5509 } 5510 } 5511 5512 /** @hide */ isEmpty()5513 public boolean isEmpty() { 5514 if (getBeginTimeMillis() >= getEndTimeMillis()) { 5515 return true; 5516 } 5517 final int uidCount = getUidCount(); 5518 for (int i = uidCount - 1; i >= 0; i--) { 5519 final HistoricalUidOps uidOp = mHistoricalUidOps.valueAt(i); 5520 if (!uidOp.isEmpty()) { 5521 return false; 5522 } 5523 } 5524 return true; 5525 } 5526 5527 /** @hide */ getDurationMillis()5528 public long getDurationMillis() { 5529 return mEndTimeMillis - mBeginTimeMillis; 5530 } 5531 5532 /** @hide */ 5533 @TestApi increaseAccessCount(int opCode, int uid, @NonNull String packageName, @Nullable String attributionTag, @UidState int uidState, @OpFlags int flags, long increment)5534 public void increaseAccessCount(int opCode, int uid, @NonNull String packageName, 5535 @Nullable String attributionTag, @UidState int uidState, @OpFlags int flags, 5536 long increment) { 5537 getOrCreateHistoricalUidOps(uid).increaseAccessCount(opCode, 5538 packageName, attributionTag, uidState, flags, increment); 5539 } 5540 5541 /** @hide */ 5542 @TestApi increaseRejectCount(int opCode, int uid, @NonNull String packageName, @Nullable String attributionTag, @UidState int uidState, @OpFlags int flags, long increment)5543 public void increaseRejectCount(int opCode, int uid, @NonNull String packageName, 5544 @Nullable String attributionTag, @UidState int uidState, @OpFlags int flags, 5545 long increment) { 5546 getOrCreateHistoricalUidOps(uid).increaseRejectCount(opCode, 5547 packageName, attributionTag, uidState, flags, increment); 5548 } 5549 5550 /** @hide */ 5551 @TestApi increaseAccessDuration(int opCode, int uid, @NonNull String packageName, @Nullable String attributionTag, @UidState int uidState, @OpFlags int flags, long increment)5552 public void increaseAccessDuration(int opCode, int uid, @NonNull String packageName, 5553 @Nullable String attributionTag, @UidState int uidState, @OpFlags int flags, 5554 long increment) { 5555 getOrCreateHistoricalUidOps(uid).increaseAccessDuration(opCode, 5556 packageName, attributionTag, uidState, flags, increment); 5557 } 5558 5559 /** @hide */ 5560 @TestApi addDiscreteAccess(int opCode, int uid, @NonNull String packageName, @Nullable String attributionTag, @UidState int uidState, @OpFlags int opFlag, long discreteAccessTime, long discreteAccessDuration)5561 public void addDiscreteAccess(int opCode, int uid, @NonNull String packageName, 5562 @Nullable String attributionTag, @UidState int uidState, @OpFlags int opFlag, 5563 long discreteAccessTime, long discreteAccessDuration) { 5564 getOrCreateHistoricalUidOps(uid).addDiscreteAccess(opCode, packageName, attributionTag, 5565 uidState, opFlag, discreteAccessTime, discreteAccessDuration, null); 5566 } 5567 5568 /** @hide */ addDiscreteAccess(int opCode, int uid, @NonNull String packageName, @Nullable String attributionTag, @UidState int uidState, @OpFlags int opFlag, long discreteAccessTime, long discreteAccessDuration, @Nullable OpEventProxyInfo proxy)5569 public void addDiscreteAccess(int opCode, int uid, @NonNull String packageName, 5570 @Nullable String attributionTag, @UidState int uidState, @OpFlags int opFlag, 5571 long discreteAccessTime, long discreteAccessDuration, 5572 @Nullable OpEventProxyInfo proxy) { 5573 getOrCreateHistoricalUidOps(uid).addDiscreteAccess(opCode, packageName, attributionTag, 5574 uidState, opFlag, discreteAccessTime, discreteAccessDuration, proxy); 5575 } 5576 5577 5578 /** @hide */ 5579 @TestApi offsetBeginAndEndTime(long offsetMillis)5580 public void offsetBeginAndEndTime(long offsetMillis) { 5581 mBeginTimeMillis += offsetMillis; 5582 mEndTimeMillis += offsetMillis; 5583 } 5584 5585 /** @hide */ setBeginAndEndTime(long beginTimeMillis, long endTimeMillis)5586 public void setBeginAndEndTime(long beginTimeMillis, long endTimeMillis) { 5587 mBeginTimeMillis = beginTimeMillis; 5588 mEndTimeMillis = endTimeMillis; 5589 } 5590 5591 /** @hide */ setBeginTime(long beginTimeMillis)5592 public void setBeginTime(long beginTimeMillis) { 5593 mBeginTimeMillis = beginTimeMillis; 5594 } 5595 5596 /** @hide */ setEndTime(long endTimeMillis)5597 public void setEndTime(long endTimeMillis) { 5598 mEndTimeMillis = endTimeMillis; 5599 } 5600 5601 /** 5602 * @return The beginning of the interval in milliseconds since 5603 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). 5604 */ getBeginTimeMillis()5605 public long getBeginTimeMillis() { 5606 return mBeginTimeMillis; 5607 } 5608 5609 /** 5610 * @return The end of the interval in milliseconds since 5611 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). 5612 */ getEndTimeMillis()5613 public long getEndTimeMillis() { 5614 return mEndTimeMillis; 5615 } 5616 5617 /** 5618 * Gets number of UIDs with historical ops. 5619 * 5620 * @return The number of UIDs with historical ops. 5621 * 5622 * @see #getUidOpsAt(int) 5623 */ getUidCount()5624 public @IntRange(from = 0) int getUidCount() { 5625 if (mHistoricalUidOps == null) { 5626 return 0; 5627 } 5628 return mHistoricalUidOps.size(); 5629 } 5630 5631 /** 5632 * Gets the historical UID ops at a given index. 5633 * 5634 * @param index The index. 5635 * 5636 * @return The historical UID ops at the given index. 5637 * 5638 * @see #getUidCount() 5639 */ getUidOpsAt(@ntRangefrom = 0) int index)5640 public @NonNull HistoricalUidOps getUidOpsAt(@IntRange(from = 0) int index) { 5641 if (mHistoricalUidOps == null) { 5642 throw new IndexOutOfBoundsException(); 5643 } 5644 return mHistoricalUidOps.valueAt(index); 5645 } 5646 5647 /** 5648 * Gets the historical UID ops for a given UID. 5649 * 5650 * @param uid The UID. 5651 * 5652 * @return The historical ops for the UID. 5653 */ getUidOps(int uid)5654 public @Nullable HistoricalUidOps getUidOps(int uid) { 5655 if (mHistoricalUidOps == null) { 5656 return null; 5657 } 5658 return mHistoricalUidOps.get(uid); 5659 } 5660 5661 /** @hide */ clearHistory(int uid, @NonNull String packageName)5662 public void clearHistory(int uid, @NonNull String packageName) { 5663 HistoricalUidOps historicalUidOps = getOrCreateHistoricalUidOps(uid); 5664 historicalUidOps.clearHistory(packageName); 5665 if (historicalUidOps.isEmpty()) { 5666 mHistoricalUidOps.remove(uid); 5667 } 5668 } 5669 5670 @Override describeContents()5671 public int describeContents() { 5672 return 0; 5673 } 5674 5675 @Override writeToParcel(Parcel parcel, int flags)5676 public void writeToParcel(Parcel parcel, int flags) { 5677 parcel.writeLong(mBeginTimeMillis); 5678 parcel.writeLong(mEndTimeMillis); 5679 if (mHistoricalUidOps != null) { 5680 final int uidCount = mHistoricalUidOps.size(); 5681 parcel.writeInt(uidCount); 5682 for (int i = 0; i < uidCount; i++) { 5683 parcel.writeInt(mHistoricalUidOps.keyAt(i)); 5684 } 5685 final List<HistoricalUidOps> opsList = new ArrayList<>(uidCount); 5686 for (int i = 0; i < uidCount; i++) { 5687 opsList.add(mHistoricalUidOps.valueAt(i)); 5688 } 5689 parcel.writeParcelable(new ParceledListSlice<>(opsList), flags); 5690 } else { 5691 parcel.writeInt(-1); 5692 } 5693 } 5694 5695 /** 5696 * Accepts a visitor to traverse the ops tree. 5697 * 5698 * @param visitor The visitor. 5699 * 5700 * @hide 5701 */ accept(@onNull HistoricalOpsVisitor visitor)5702 public void accept(@NonNull HistoricalOpsVisitor visitor) { 5703 visitor.visitHistoricalOps(this); 5704 final int uidCount = getUidCount(); 5705 for (int i = 0; i < uidCount; i++) { 5706 getUidOpsAt(i).accept(visitor); 5707 } 5708 } 5709 getOrCreateHistoricalUidOps(int uid)5710 private @NonNull HistoricalUidOps getOrCreateHistoricalUidOps(int uid) { 5711 if (mHistoricalUidOps == null) { 5712 mHistoricalUidOps = new SparseArray<>(); 5713 } 5714 HistoricalUidOps historicalUidOp = mHistoricalUidOps.get(uid); 5715 if (historicalUidOp == null) { 5716 historicalUidOp = new HistoricalUidOps(uid); 5717 mHistoricalUidOps.put(uid, historicalUidOp); 5718 } 5719 return historicalUidOp; 5720 } 5721 5722 /** 5723 * @return Rounded value up at the 0.5 boundary. 5724 * 5725 * @hide 5726 */ round(double value)5727 public static double round(double value) { 5728 return Math.floor(value + 0.5); 5729 } 5730 5731 @Override equals(@ullable Object obj)5732 public boolean equals(@Nullable Object obj) { 5733 if (this == obj) { 5734 return true; 5735 } 5736 if (obj == null || getClass() != obj.getClass()) { 5737 return false; 5738 } 5739 final HistoricalOps other = (HistoricalOps) obj; 5740 if (mBeginTimeMillis != other.mBeginTimeMillis) { 5741 return false; 5742 } 5743 if (mEndTimeMillis != other.mEndTimeMillis) { 5744 return false; 5745 } 5746 if (mHistoricalUidOps == null) { 5747 if (other.mHistoricalUidOps != null) { 5748 return false; 5749 } 5750 } else if (!mHistoricalUidOps.equals(other.mHistoricalUidOps)) { 5751 return false; 5752 } 5753 return true; 5754 } 5755 5756 @Override hashCode()5757 public int hashCode() { 5758 int result = (int) (mBeginTimeMillis ^ (mBeginTimeMillis >>> 32)); 5759 result = 31 * result + mHistoricalUidOps.hashCode(); 5760 return result; 5761 } 5762 5763 @NonNull 5764 @Override toString()5765 public String toString() { 5766 return getClass().getSimpleName() + "[from:" 5767 + mBeginTimeMillis + " to:" + mEndTimeMillis + "]"; 5768 } 5769 5770 public static final @android.annotation.NonNull Creator<HistoricalOps> CREATOR = new Creator<HistoricalOps>() { 5771 @Override 5772 public @NonNull HistoricalOps createFromParcel(@NonNull Parcel parcel) { 5773 return new HistoricalOps(parcel); 5774 } 5775 5776 @Override 5777 public @NonNull HistoricalOps[] newArray(int size) { 5778 return new HistoricalOps[size]; 5779 } 5780 }; 5781 } 5782 5783 /** 5784 * This class represents historical app op state for a UID. 5785 * 5786 * @hide 5787 */ 5788 @SystemApi 5789 public static final class HistoricalUidOps implements Parcelable { 5790 private final int mUid; 5791 private @Nullable ArrayMap<String, HistoricalPackageOps> mHistoricalPackageOps; 5792 5793 /** @hide */ HistoricalUidOps(int uid)5794 public HistoricalUidOps(int uid) { 5795 mUid = uid; 5796 } 5797 HistoricalUidOps(@onNull HistoricalUidOps other)5798 private HistoricalUidOps(@NonNull HistoricalUidOps other) { 5799 mUid = other.mUid; 5800 final int opCount = other.getPackageCount(); 5801 for (int i = 0; i < opCount; i++) { 5802 final HistoricalPackageOps origOps = other.getPackageOpsAt(i); 5803 final HistoricalPackageOps cloneOps = new HistoricalPackageOps(origOps); 5804 if (mHistoricalPackageOps == null) { 5805 mHistoricalPackageOps = new ArrayMap<>(opCount); 5806 } 5807 mHistoricalPackageOps.put(cloneOps.getPackageName(), cloneOps); 5808 } 5809 } 5810 HistoricalUidOps(@onNull Parcel parcel)5811 private HistoricalUidOps(@NonNull Parcel parcel) { 5812 // No arg check since we always read from a trusted source. 5813 mUid = parcel.readInt(); 5814 mHistoricalPackageOps = parcel.createTypedArrayMap(HistoricalPackageOps.CREATOR); 5815 } 5816 splice(double fractionToRemove)5817 private @Nullable HistoricalUidOps splice(double fractionToRemove) { 5818 HistoricalUidOps splice = null; 5819 final int packageCount = getPackageCount(); 5820 for (int i = 0; i < packageCount; i++) { 5821 final HistoricalPackageOps origOps = getPackageOpsAt(i); 5822 final HistoricalPackageOps spliceOps = origOps.splice(fractionToRemove); 5823 if (spliceOps != null) { 5824 if (splice == null) { 5825 splice = new HistoricalUidOps(mUid); 5826 } 5827 if (splice.mHistoricalPackageOps == null) { 5828 splice.mHistoricalPackageOps = new ArrayMap<>(); 5829 } 5830 splice.mHistoricalPackageOps.put(spliceOps.getPackageName(), spliceOps); 5831 } 5832 } 5833 return splice; 5834 } 5835 merge(@onNull HistoricalUidOps other)5836 private void merge(@NonNull HistoricalUidOps other) { 5837 final int packageCount = other.getPackageCount(); 5838 for (int i = 0; i < packageCount; i++) { 5839 final HistoricalPackageOps otherPackageOps = other.getPackageOpsAt(i); 5840 final HistoricalPackageOps thisPackageOps = getPackageOps( 5841 otherPackageOps.getPackageName()); 5842 if (thisPackageOps != null) { 5843 thisPackageOps.merge(otherPackageOps); 5844 } else { 5845 if (mHistoricalPackageOps == null) { 5846 mHistoricalPackageOps = new ArrayMap<>(); 5847 } 5848 mHistoricalPackageOps.put(otherPackageOps.getPackageName(), otherPackageOps); 5849 } 5850 } 5851 } 5852 filter(@ullable String packageName, @Nullable String attributionTag, @Nullable String[] opNames, @HistoricalOpsRequestFilter int filter, @OpHistoryFlags int historyFilter, double fractionToRemove, long beginTimeMillis, long endTimeMillis)5853 private void filter(@Nullable String packageName, @Nullable String attributionTag, 5854 @Nullable String[] opNames, @HistoricalOpsRequestFilter int filter, 5855 @OpHistoryFlags int historyFilter, double fractionToRemove, long beginTimeMillis, 5856 long endTimeMillis) { 5857 final int packageCount = getPackageCount(); 5858 for (int i = packageCount - 1; i >= 0; i--) { 5859 final HistoricalPackageOps packageOps = getPackageOpsAt(i); 5860 if ((filter & FILTER_BY_PACKAGE_NAME) != 0 && !packageName.equals( 5861 packageOps.getPackageName())) { 5862 mHistoricalPackageOps.removeAt(i); 5863 } else { 5864 packageOps.filter(attributionTag, opNames, filter, historyFilter, 5865 fractionToRemove, beginTimeMillis, endTimeMillis); 5866 if (packageOps.getAttributedOpsCount() == 0) { 5867 mHistoricalPackageOps.removeAt(i); 5868 } 5869 } 5870 } 5871 } 5872 isEmpty()5873 private boolean isEmpty() { 5874 final int packageCount = getPackageCount(); 5875 for (int i = packageCount - 1; i >= 0; i--) { 5876 final HistoricalPackageOps packageOps = mHistoricalPackageOps.valueAt(i); 5877 if (!packageOps.isEmpty()) { 5878 return false; 5879 } 5880 } 5881 return true; 5882 } 5883 increaseAccessCount(int opCode, @NonNull String packageName, @Nullable String attributionTag, @UidState int uidState, @OpFlags int flags, long increment)5884 private void increaseAccessCount(int opCode, @NonNull String packageName, 5885 @Nullable String attributionTag, @UidState int uidState, @OpFlags int flags, 5886 long increment) { 5887 getOrCreateHistoricalPackageOps(packageName).increaseAccessCount( 5888 opCode, attributionTag, uidState, flags, increment); 5889 } 5890 increaseRejectCount(int opCode, @NonNull String packageName, @Nullable String attributionTag, @UidState int uidState, @OpFlags int flags, long increment)5891 private void increaseRejectCount(int opCode, @NonNull String packageName, 5892 @Nullable String attributionTag, @UidState int uidState, @OpFlags int flags, 5893 long increment) { 5894 getOrCreateHistoricalPackageOps(packageName).increaseRejectCount( 5895 opCode, attributionTag, uidState, flags, increment); 5896 } 5897 increaseAccessDuration(int opCode, @NonNull String packageName, @Nullable String attributionTag, @UidState int uidState, @OpFlags int flags, long increment)5898 private void increaseAccessDuration(int opCode, @NonNull String packageName, 5899 @Nullable String attributionTag, @UidState int uidState, @OpFlags int flags, 5900 long increment) { 5901 getOrCreateHistoricalPackageOps(packageName).increaseAccessDuration( 5902 opCode, attributionTag, uidState, flags, increment); 5903 } 5904 addDiscreteAccess(int opCode, @NonNull String packageName, @Nullable String attributionTag, @UidState int uidState, @OpFlags int flag, long discreteAccessTime, long discreteAccessDuration, @Nullable OpEventProxyInfo proxy)5905 private void addDiscreteAccess(int opCode, @NonNull String packageName, 5906 @Nullable String attributionTag, @UidState int uidState, 5907 @OpFlags int flag, long discreteAccessTime, long discreteAccessDuration, 5908 @Nullable OpEventProxyInfo proxy) { 5909 getOrCreateHistoricalPackageOps(packageName).addDiscreteAccess(opCode, attributionTag, 5910 uidState, flag, discreteAccessTime, discreteAccessDuration, proxy); 5911 }; 5912 5913 /** 5914 * @return The UID for which the data is related. 5915 */ getUid()5916 public int getUid() { 5917 return mUid; 5918 } 5919 5920 /** 5921 * Gets number of packages with historical ops. 5922 * 5923 * @return The number of packages with historical ops. 5924 * 5925 * @see #getPackageOpsAt(int) 5926 */ getPackageCount()5927 public @IntRange(from = 0) int getPackageCount() { 5928 if (mHistoricalPackageOps == null) { 5929 return 0; 5930 } 5931 return mHistoricalPackageOps.size(); 5932 } 5933 5934 /** 5935 * Gets the historical package ops at a given index. 5936 * 5937 * @param index The index. 5938 * 5939 * @return The historical package ops at the given index. 5940 * 5941 * @see #getPackageCount() 5942 */ getPackageOpsAt(@ntRangefrom = 0) int index)5943 public @NonNull HistoricalPackageOps getPackageOpsAt(@IntRange(from = 0) int index) { 5944 if (mHistoricalPackageOps == null) { 5945 throw new IndexOutOfBoundsException(); 5946 } 5947 return mHistoricalPackageOps.valueAt(index); 5948 } 5949 5950 /** 5951 * Gets the historical package ops for a given package. 5952 * 5953 * @param packageName The package. 5954 * 5955 * @return The historical ops for the package. 5956 */ getPackageOps(@onNull String packageName)5957 public @Nullable HistoricalPackageOps getPackageOps(@NonNull String packageName) { 5958 if (mHistoricalPackageOps == null) { 5959 return null; 5960 } 5961 return mHistoricalPackageOps.get(packageName); 5962 } 5963 clearHistory(@onNull String packageName)5964 private void clearHistory(@NonNull String packageName) { 5965 if (mHistoricalPackageOps != null) { 5966 mHistoricalPackageOps.remove(packageName); 5967 } 5968 } 5969 5970 @Override describeContents()5971 public int describeContents() { 5972 return 0; 5973 } 5974 5975 @Override writeToParcel(Parcel parcel, int flags)5976 public void writeToParcel(Parcel parcel, int flags) { 5977 parcel.writeInt(mUid); 5978 parcel.writeTypedArrayMap(mHistoricalPackageOps, flags); 5979 } 5980 accept(@onNull HistoricalOpsVisitor visitor)5981 private void accept(@NonNull HistoricalOpsVisitor visitor) { 5982 visitor.visitHistoricalUidOps(this); 5983 final int packageCount = getPackageCount(); 5984 for (int i = 0; i < packageCount; i++) { 5985 getPackageOpsAt(i).accept(visitor); 5986 } 5987 } 5988 getOrCreateHistoricalPackageOps( @onNull String packageName)5989 private @NonNull HistoricalPackageOps getOrCreateHistoricalPackageOps( 5990 @NonNull String packageName) { 5991 if (mHistoricalPackageOps == null) { 5992 mHistoricalPackageOps = new ArrayMap<>(); 5993 } 5994 HistoricalPackageOps historicalPackageOp = mHistoricalPackageOps.get(packageName); 5995 if (historicalPackageOp == null) { 5996 historicalPackageOp = new HistoricalPackageOps(packageName); 5997 mHistoricalPackageOps.put(packageName, historicalPackageOp); 5998 } 5999 return historicalPackageOp; 6000 } 6001 6002 6003 public static final @android.annotation.NonNull Creator<HistoricalUidOps> CREATOR = new Creator<HistoricalUidOps>() { 6004 @Override 6005 public @NonNull HistoricalUidOps createFromParcel(@NonNull Parcel parcel) { 6006 return new HistoricalUidOps(parcel); 6007 } 6008 6009 @Override 6010 public @NonNull HistoricalUidOps[] newArray(int size) { 6011 return new HistoricalUidOps[size]; 6012 } 6013 }; 6014 6015 @Override equals(@ullable Object obj)6016 public boolean equals(@Nullable Object obj) { 6017 if (this == obj) { 6018 return true; 6019 } 6020 if (obj == null || getClass() != obj.getClass()) { 6021 return false; 6022 } 6023 final HistoricalUidOps other = (HistoricalUidOps) obj; 6024 if (mUid != other.mUid) { 6025 return false; 6026 } 6027 if (mHistoricalPackageOps == null) { 6028 if (other.mHistoricalPackageOps != null) { 6029 return false; 6030 } 6031 } else if (!mHistoricalPackageOps.equals(other.mHistoricalPackageOps)) { 6032 return false; 6033 } 6034 return true; 6035 } 6036 6037 @Override hashCode()6038 public int hashCode() { 6039 int result = mUid; 6040 result = 31 * result + (mHistoricalPackageOps != null 6041 ? mHistoricalPackageOps.hashCode() : 0); 6042 return result; 6043 } 6044 } 6045 6046 /** 6047 * This class represents historical app op information about a package. 6048 * 6049 * @hide 6050 */ 6051 @SystemApi 6052 public static final class HistoricalPackageOps implements Parcelable { 6053 private final @NonNull String mPackageName; 6054 private @Nullable ArrayMap<String, AttributedHistoricalOps> mAttributedHistoricalOps; 6055 6056 /** @hide */ HistoricalPackageOps(@onNull String packageName)6057 public HistoricalPackageOps(@NonNull String packageName) { 6058 mPackageName = packageName; 6059 } 6060 HistoricalPackageOps(@onNull HistoricalPackageOps other)6061 private HistoricalPackageOps(@NonNull HistoricalPackageOps other) { 6062 mPackageName = other.mPackageName; 6063 final int opCount = other.getAttributedOpsCount(); 6064 for (int i = 0; i < opCount; i++) { 6065 final AttributedHistoricalOps origOps = other.getAttributedOpsAt(i); 6066 final AttributedHistoricalOps cloneOps = new AttributedHistoricalOps(origOps); 6067 if (mAttributedHistoricalOps == null) { 6068 mAttributedHistoricalOps = new ArrayMap<>(opCount); 6069 } 6070 mAttributedHistoricalOps.put(cloneOps.getTag(), cloneOps); 6071 } 6072 } 6073 HistoricalPackageOps(@onNull Parcel parcel)6074 private HistoricalPackageOps(@NonNull Parcel parcel) { 6075 mPackageName = parcel.readString(); 6076 mAttributedHistoricalOps = parcel.createTypedArrayMap(AttributedHistoricalOps.CREATOR); 6077 } 6078 splice(double fractionToRemove)6079 private @Nullable HistoricalPackageOps splice(double fractionToRemove) { 6080 HistoricalPackageOps splice = null; 6081 final int attributionCount = getAttributedOpsCount(); 6082 for (int i = 0; i < attributionCount; i++) { 6083 final AttributedHistoricalOps origOps = getAttributedOpsAt(i); 6084 final AttributedHistoricalOps spliceOps = origOps.splice(fractionToRemove); 6085 if (spliceOps != null) { 6086 if (splice == null) { 6087 splice = new HistoricalPackageOps(mPackageName); 6088 } 6089 if (splice.mAttributedHistoricalOps == null) { 6090 splice.mAttributedHistoricalOps = new ArrayMap<>(); 6091 } 6092 splice.mAttributedHistoricalOps.put(spliceOps.getTag(), spliceOps); 6093 } 6094 } 6095 return splice; 6096 } 6097 merge(@onNull HistoricalPackageOps other)6098 private void merge(@NonNull HistoricalPackageOps other) { 6099 final int attributionCount = other.getAttributedOpsCount(); 6100 for (int i = 0; i < attributionCount; i++) { 6101 final AttributedHistoricalOps otherAttributionOps = other.getAttributedOpsAt(i); 6102 final AttributedHistoricalOps thisAttributionOps = getAttributedOps( 6103 otherAttributionOps.getTag()); 6104 if (thisAttributionOps != null) { 6105 thisAttributionOps.merge(otherAttributionOps); 6106 } else { 6107 if (mAttributedHistoricalOps == null) { 6108 mAttributedHistoricalOps = new ArrayMap<>(); 6109 } 6110 mAttributedHistoricalOps.put(otherAttributionOps.getTag(), 6111 otherAttributionOps); 6112 } 6113 } 6114 } 6115 filter(@ullable String attributionTag, @Nullable String[] opNames, @HistoricalOpsRequestFilter int filter, @OpHistoryFlags int historyFilter, double fractionToRemove, long beginTimeMillis, long endTimeMillis)6116 private void filter(@Nullable String attributionTag, @Nullable String[] opNames, 6117 @HistoricalOpsRequestFilter int filter, @OpHistoryFlags int historyFilter, 6118 double fractionToRemove, long beginTimeMillis, long endTimeMillis) { 6119 final int attributionCount = getAttributedOpsCount(); 6120 for (int i = attributionCount - 1; i >= 0; i--) { 6121 final AttributedHistoricalOps attributionOps = getAttributedOpsAt(i); 6122 if ((filter & FILTER_BY_ATTRIBUTION_TAG) != 0 && !Objects.equals(attributionTag, 6123 attributionOps.getTag())) { 6124 mAttributedHistoricalOps.removeAt(i); 6125 } else { 6126 attributionOps.filter(opNames, filter, historyFilter, fractionToRemove, 6127 beginTimeMillis, endTimeMillis); 6128 if (attributionOps.getOpCount() == 0) { 6129 mAttributedHistoricalOps.removeAt(i); 6130 } 6131 } 6132 } 6133 } 6134 accept(@onNull HistoricalOpsVisitor visitor)6135 private void accept(@NonNull HistoricalOpsVisitor visitor) { 6136 visitor.visitHistoricalPackageOps(this); 6137 final int attributionCount = getAttributedOpsCount(); 6138 for (int i = 0; i < attributionCount; i++) { 6139 getAttributedOpsAt(i).accept(visitor); 6140 } 6141 } 6142 isEmpty()6143 private boolean isEmpty() { 6144 final int attributionCount = getAttributedOpsCount(); 6145 for (int i = attributionCount - 1; i >= 0; i--) { 6146 final AttributedHistoricalOps attributionOps = mAttributedHistoricalOps.valueAt(i); 6147 if (!attributionOps.isEmpty()) { 6148 return false; 6149 } 6150 } 6151 return true; 6152 } 6153 increaseAccessCount(int opCode, @Nullable String attributionTag, @UidState int uidState, @OpFlags int flags, long increment)6154 private void increaseAccessCount(int opCode, @Nullable String attributionTag, 6155 @UidState int uidState, @OpFlags int flags, long increment) { 6156 getOrCreateAttributedHistoricalOps(attributionTag).increaseAccessCount( 6157 opCode, uidState, flags, increment); 6158 } 6159 increaseRejectCount(int opCode, @Nullable String attributionTag, @UidState int uidState, @OpFlags int flags, long increment)6160 private void increaseRejectCount(int opCode, @Nullable String attributionTag, 6161 @UidState int uidState, @OpFlags int flags, long increment) { 6162 getOrCreateAttributedHistoricalOps(attributionTag).increaseRejectCount( 6163 opCode, uidState, flags, increment); 6164 } 6165 increaseAccessDuration(int opCode, @Nullable String attributionTag, @UidState int uidState, @OpFlags int flags, long increment)6166 private void increaseAccessDuration(int opCode, @Nullable String attributionTag, 6167 @UidState int uidState, @OpFlags int flags, long increment) { 6168 getOrCreateAttributedHistoricalOps(attributionTag).increaseAccessDuration( 6169 opCode, uidState, flags, increment); 6170 } 6171 addDiscreteAccess(int opCode, @Nullable String attributionTag, @UidState int uidState, @OpFlags int flag, long discreteAccessTime, long discreteAccessDuration, @Nullable OpEventProxyInfo proxy)6172 private void addDiscreteAccess(int opCode, @Nullable String attributionTag, 6173 @UidState int uidState, @OpFlags int flag, long discreteAccessTime, 6174 long discreteAccessDuration, @Nullable OpEventProxyInfo proxy) { 6175 getOrCreateAttributedHistoricalOps(attributionTag).addDiscreteAccess(opCode, uidState, 6176 flag, discreteAccessTime, discreteAccessDuration, proxy); 6177 } 6178 6179 /** 6180 * Gets the package name which the data represents. 6181 * 6182 * @return The package name which the data represents. 6183 */ getPackageName()6184 public @NonNull String getPackageName() { 6185 return mPackageName; 6186 } 6187 getOrCreateAttributedHistoricalOps( @ullable String attributionTag)6188 private @NonNull AttributedHistoricalOps getOrCreateAttributedHistoricalOps( 6189 @Nullable String attributionTag) { 6190 if (mAttributedHistoricalOps == null) { 6191 mAttributedHistoricalOps = new ArrayMap<>(); 6192 } 6193 AttributedHistoricalOps historicalAttributionOp = mAttributedHistoricalOps.get( 6194 attributionTag); 6195 if (historicalAttributionOp == null) { 6196 historicalAttributionOp = new AttributedHistoricalOps(attributionTag); 6197 mAttributedHistoricalOps.put(attributionTag, historicalAttributionOp); 6198 } 6199 return historicalAttributionOp; 6200 } 6201 6202 /** 6203 * Gets number historical app ops. 6204 * 6205 * @return The number historical app ops. 6206 * @see #getOpAt(int) 6207 */ getOpCount()6208 public @IntRange(from = 0) int getOpCount() { 6209 int numOps = 0; 6210 int numAttributions = getAttributedOpsCount(); 6211 6212 for (int code = 0; code < _NUM_OP; code++) { 6213 String opName = opToPublicName(code); 6214 6215 for (int attributionNum = 0; attributionNum < numAttributions; attributionNum++) { 6216 if (getAttributedOpsAt(attributionNum).getOp(opName) != null) { 6217 numOps++; 6218 break; 6219 } 6220 } 6221 } 6222 6223 return numOps; 6224 } 6225 6226 /** 6227 * Gets the historical op at a given index. 6228 * 6229 * <p>This combines the counts from all attributions. 6230 * 6231 * @param index The index to lookup. 6232 * @return The op at the given index. 6233 * @see #getOpCount() 6234 */ getOpAt(@ntRangefrom = 0) int index)6235 public @NonNull HistoricalOp getOpAt(@IntRange(from = 0) int index) { 6236 int numOpsFound = 0; 6237 int numAttributions = getAttributedOpsCount(); 6238 6239 for (int code = 0; code < _NUM_OP; code++) { 6240 String opName = opToPublicName(code); 6241 6242 for (int attributionNum = 0; attributionNum < numAttributions; attributionNum++) { 6243 if (getAttributedOpsAt(attributionNum).getOp(opName) != null) { 6244 if (numOpsFound == index) { 6245 return getOp(opName); 6246 } else { 6247 numOpsFound++; 6248 break; 6249 } 6250 } 6251 } 6252 } 6253 6254 throw new IndexOutOfBoundsException(); 6255 } 6256 6257 /** 6258 * Gets the historical entry for a given op name. 6259 * 6260 * <p>This combines the counts from all attributions. 6261 * 6262 * @param opName The op name. 6263 * @return The historical entry for that op name. 6264 */ getOp(@onNull String opName)6265 public @Nullable HistoricalOp getOp(@NonNull String opName) { 6266 if (mAttributedHistoricalOps == null) { 6267 return null; 6268 } 6269 6270 HistoricalOp combinedOp = null; 6271 int numAttributions = getAttributedOpsCount(); 6272 for (int i = 0; i < numAttributions; i++) { 6273 HistoricalOp attributionOp = getAttributedOpsAt(i).getOp(opName); 6274 if (attributionOp != null) { 6275 if (combinedOp == null) { 6276 combinedOp = new HistoricalOp(attributionOp); 6277 } else { 6278 combinedOp.merge(attributionOp); 6279 } 6280 } 6281 } 6282 6283 return combinedOp; 6284 } 6285 6286 @Override describeContents()6287 public int describeContents() { 6288 return 0; 6289 } 6290 6291 @Override writeToParcel(@onNull Parcel parcel, int flags)6292 public void writeToParcel(@NonNull Parcel parcel, int flags) { 6293 parcel.writeString(mPackageName); 6294 parcel.writeTypedArrayMap(mAttributedHistoricalOps, flags); 6295 } 6296 6297 public static final @android.annotation.NonNull Creator<HistoricalPackageOps> CREATOR = 6298 new Creator<HistoricalPackageOps>() { 6299 @Override 6300 public @NonNull HistoricalPackageOps createFromParcel(@NonNull Parcel parcel) { 6301 return new HistoricalPackageOps(parcel); 6302 } 6303 6304 @Override 6305 public @NonNull HistoricalPackageOps[] newArray(int size) { 6306 return new HistoricalPackageOps[size]; 6307 } 6308 }; 6309 6310 @Override equals(@ullable Object obj)6311 public boolean equals(@Nullable Object obj) { 6312 if (this == obj) { 6313 return true; 6314 } 6315 if (obj == null || getClass() != obj.getClass()) { 6316 return false; 6317 } 6318 final HistoricalPackageOps other = (HistoricalPackageOps) obj; 6319 if (!mPackageName.equals(other.mPackageName)) { 6320 return false; 6321 } 6322 if (mAttributedHistoricalOps == null) { 6323 if (other.mAttributedHistoricalOps != null) { 6324 return false; 6325 } 6326 } else if (!mAttributedHistoricalOps.equals(other.mAttributedHistoricalOps)) { 6327 return false; 6328 } 6329 return true; 6330 } 6331 6332 @Override hashCode()6333 public int hashCode() { 6334 int result = mPackageName != null ? mPackageName.hashCode() : 0; 6335 result = 31 * result + (mAttributedHistoricalOps != null 6336 ? mAttributedHistoricalOps.hashCode() : 0); 6337 return result; 6338 } 6339 6340 /** 6341 * Gets number of attributed historical ops. 6342 * 6343 * @return The number of attribution with historical ops. 6344 * 6345 * @see #getAttributedOpsAt(int) 6346 */ getAttributedOpsCount()6347 public @IntRange(from = 0) int getAttributedOpsCount() { 6348 if (mAttributedHistoricalOps == null) { 6349 return 0; 6350 } 6351 return mAttributedHistoricalOps.size(); 6352 } 6353 6354 /** 6355 * Gets the attributed historical ops at a given index. 6356 * 6357 * @param index The index. 6358 * 6359 * @return The historical attribution ops at the given index. 6360 * 6361 * @see #getAttributedOpsCount() 6362 */ getAttributedOpsAt(@ntRangefrom = 0) int index)6363 public @NonNull AttributedHistoricalOps getAttributedOpsAt(@IntRange(from = 0) int index) { 6364 if (mAttributedHistoricalOps == null) { 6365 throw new IndexOutOfBoundsException(); 6366 } 6367 return mAttributedHistoricalOps.valueAt(index); 6368 } 6369 6370 /** 6371 * Gets the attributed historical ops for a given attribution tag. 6372 * 6373 * @param attributionTag The attribution tag. 6374 * 6375 * @return The historical ops for the attribution. 6376 */ getAttributedOps(@ullable String attributionTag)6377 public @Nullable AttributedHistoricalOps getAttributedOps(@Nullable String attributionTag) { 6378 if (mAttributedHistoricalOps == null) { 6379 return null; 6380 } 6381 return mAttributedHistoricalOps.get(attributionTag); 6382 } 6383 } 6384 6385 /** 6386 * This class represents historical app op information about a attribution in a package. 6387 * 6388 * @hide 6389 */ 6390 @SystemApi 6391 /* codegen verifier cannot deal with nested class parameters 6392 @DataClass(genHiddenConstructor = true, 6393 genEqualsHashCode = true, genHiddenCopyConstructor = true) */ 6394 @DataClass.Suppress("getHistoricalOps") 6395 public static final class AttributedHistoricalOps implements Parcelable { 6396 /** {@link Context#createAttributionContext attribution} tag */ 6397 private final @Nullable String mTag; 6398 6399 /** Ops for this attribution */ 6400 private @Nullable ArrayMap<String, HistoricalOp> mHistoricalOps; 6401 6402 /** @hide */ AttributedHistoricalOps(@onNull String tag)6403 public AttributedHistoricalOps(@NonNull String tag) { 6404 mTag = tag; 6405 } 6406 AttributedHistoricalOps(@onNull AttributedHistoricalOps other)6407 private AttributedHistoricalOps(@NonNull AttributedHistoricalOps other) { 6408 mTag = other.mTag; 6409 final int opCount = other.getOpCount(); 6410 for (int i = 0; i < opCount; i++) { 6411 final HistoricalOp origOp = other.getOpAt(i); 6412 final HistoricalOp cloneOp = new HistoricalOp(origOp); 6413 if (mHistoricalOps == null) { 6414 mHistoricalOps = new ArrayMap<>(opCount); 6415 } 6416 mHistoricalOps.put(cloneOp.getOpName(), cloneOp); 6417 } 6418 } 6419 splice(double fractionToRemove)6420 private @Nullable AttributedHistoricalOps splice(double fractionToRemove) { 6421 AttributedHistoricalOps splice = null; 6422 final int opCount = getOpCount(); 6423 for (int i = 0; i < opCount; i++) { 6424 final HistoricalOp origOps = getOpAt(i); 6425 final HistoricalOp spliceOps = origOps.splice(fractionToRemove); 6426 if (spliceOps != null) { 6427 if (splice == null) { 6428 splice = new AttributedHistoricalOps(mTag, null); 6429 } 6430 if (splice.mHistoricalOps == null) { 6431 splice.mHistoricalOps = new ArrayMap<>(); 6432 } 6433 splice.mHistoricalOps.put(spliceOps.getOpName(), spliceOps); 6434 } 6435 } 6436 return splice; 6437 } 6438 merge(@onNull AttributedHistoricalOps other)6439 private void merge(@NonNull AttributedHistoricalOps other) { 6440 final int opCount = other.getOpCount(); 6441 for (int i = 0; i < opCount; i++) { 6442 final HistoricalOp otherOp = other.getOpAt(i); 6443 final HistoricalOp thisOp = getOp(otherOp.getOpName()); 6444 if (thisOp != null) { 6445 thisOp.merge(otherOp); 6446 } else { 6447 if (mHistoricalOps == null) { 6448 mHistoricalOps = new ArrayMap<>(); 6449 } 6450 mHistoricalOps.put(otherOp.getOpName(), otherOp); 6451 } 6452 } 6453 } 6454 filter(@ullable String[] opNames, @HistoricalOpsRequestFilter int filter, @OpHistoryFlags int historyFilter, double scaleFactor, long beginTimeMillis, long endTimeMillis)6455 private void filter(@Nullable String[] opNames, @HistoricalOpsRequestFilter int filter, 6456 @OpHistoryFlags int historyFilter, double scaleFactor, long beginTimeMillis, 6457 long endTimeMillis) { 6458 final int opCount = getOpCount(); 6459 for (int i = opCount - 1; i >= 0; i--) { 6460 final HistoricalOp op = mHistoricalOps.valueAt(i); 6461 if ((filter & FILTER_BY_OP_NAMES) != 0 && !ArrayUtils.contains(opNames, 6462 op.getOpName())) { 6463 mHistoricalOps.removeAt(i); 6464 } else { 6465 op.filter(historyFilter, scaleFactor, beginTimeMillis, endTimeMillis); 6466 } 6467 } 6468 } 6469 isEmpty()6470 private boolean isEmpty() { 6471 final int opCount = getOpCount(); 6472 for (int i = opCount - 1; i >= 0; i--) { 6473 final HistoricalOp op = mHistoricalOps.valueAt(i); 6474 if (!op.isEmpty()) { 6475 return false; 6476 } 6477 } 6478 return true; 6479 } 6480 increaseAccessCount(int opCode, @UidState int uidState, @OpFlags int flags, long increment)6481 private void increaseAccessCount(int opCode, @UidState int uidState, 6482 @OpFlags int flags, long increment) { 6483 getOrCreateHistoricalOp(opCode).increaseAccessCount(uidState, flags, increment); 6484 } 6485 increaseRejectCount(int opCode, @UidState int uidState, @OpFlags int flags, long increment)6486 private void increaseRejectCount(int opCode, @UidState int uidState, 6487 @OpFlags int flags, long increment) { 6488 getOrCreateHistoricalOp(opCode).increaseRejectCount(uidState, flags, increment); 6489 } 6490 increaseAccessDuration(int opCode, @UidState int uidState, @OpFlags int flags, long increment)6491 private void increaseAccessDuration(int opCode, @UidState int uidState, 6492 @OpFlags int flags, long increment) { 6493 getOrCreateHistoricalOp(opCode).increaseAccessDuration(uidState, flags, increment); 6494 } 6495 addDiscreteAccess(int opCode, @UidState int uidState, @OpFlags int flag, long discreteAccessTime, long discreteAccessDuration, @Nullable OpEventProxyInfo proxy)6496 private void addDiscreteAccess(int opCode, @UidState int uidState, @OpFlags int flag, 6497 long discreteAccessTime, long discreteAccessDuration, 6498 @Nullable OpEventProxyInfo proxy) { 6499 getOrCreateHistoricalOp(opCode).addDiscreteAccess(uidState,flag, discreteAccessTime, 6500 discreteAccessDuration, proxy); 6501 } 6502 6503 /** 6504 * Gets number historical app ops. 6505 * 6506 * @return The number historical app ops. 6507 * @see #getOpAt(int) 6508 */ getOpCount()6509 public @IntRange(from = 0) int getOpCount() { 6510 if (mHistoricalOps == null) { 6511 return 0; 6512 } 6513 return mHistoricalOps.size(); 6514 } 6515 6516 /** 6517 * Gets the historical op at a given index. 6518 * 6519 * @param index The index to lookup. 6520 * @return The op at the given index. 6521 * @see #getOpCount() 6522 */ getOpAt(@ntRangefrom = 0) int index)6523 public @NonNull HistoricalOp getOpAt(@IntRange(from = 0) int index) { 6524 if (mHistoricalOps == null) { 6525 throw new IndexOutOfBoundsException(); 6526 } 6527 return mHistoricalOps.valueAt(index); 6528 } 6529 6530 /** 6531 * Gets the historical entry for a given op name. 6532 * 6533 * @param opName The op name. 6534 * @return The historical entry for that op name. 6535 */ getOp(@onNull String opName)6536 public @Nullable HistoricalOp getOp(@NonNull String opName) { 6537 if (mHistoricalOps == null) { 6538 return null; 6539 } 6540 return mHistoricalOps.get(opName); 6541 } 6542 accept(@onNull HistoricalOpsVisitor visitor)6543 private void accept(@NonNull HistoricalOpsVisitor visitor) { 6544 visitor.visitHistoricalAttributionOps(this); 6545 final int opCount = getOpCount(); 6546 for (int i = 0; i < opCount; i++) { 6547 getOpAt(i).accept(visitor); 6548 } 6549 } 6550 getOrCreateHistoricalOp(int opCode)6551 private @NonNull HistoricalOp getOrCreateHistoricalOp(int opCode) { 6552 if (mHistoricalOps == null) { 6553 mHistoricalOps = new ArrayMap<>(); 6554 } 6555 final String opStr = sOpToString[opCode]; 6556 HistoricalOp op = mHistoricalOps.get(opStr); 6557 if (op == null) { 6558 op = new HistoricalOp(opCode); 6559 mHistoricalOps.put(opStr, op); 6560 } 6561 return op; 6562 } 6563 6564 // Code below generated by codegen v1.0.14. 6565 // 6566 // DO NOT MODIFY! 6567 // CHECKSTYLE:OFF Generated code 6568 // 6569 // To regenerate run: 6570 // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/app/AppOpsManager.java 6571 // 6572 // To exclude the generated code from IntelliJ auto-formatting enable (one-time): 6573 // Settings > Editor > Code Style > Formatter Control 6574 //@formatter:off 6575 6576 6577 /** 6578 * Creates a new HistoricalAttributionOps. 6579 * 6580 * @param tag 6581 * {@link Context#createAttributionContext attribution} tag 6582 * @param historicalOps 6583 * Ops for this attribution 6584 * @hide 6585 */ 6586 @DataClass.Generated.Member AttributedHistoricalOps( @ullable String tag, @Nullable ArrayMap<String,HistoricalOp> historicalOps)6587 public AttributedHistoricalOps( 6588 @Nullable String tag, 6589 @Nullable ArrayMap<String,HistoricalOp> historicalOps) { 6590 this.mTag = tag; 6591 this.mHistoricalOps = historicalOps; 6592 6593 // onConstructed(); // You can define this method to get a callback 6594 } 6595 6596 /** 6597 * {@link Context#createAttributionContext attribution} tag 6598 */ 6599 @DataClass.Generated.Member getTag()6600 public @Nullable String getTag() { 6601 return mTag; 6602 } 6603 6604 @Override 6605 @DataClass.Generated.Member equals(@ullable Object o)6606 public boolean equals(@Nullable Object o) { 6607 // You can override field equality logic by defining either of the methods like: 6608 // boolean fieldNameEquals(HistoricalAttributionOps other) { ... } 6609 // boolean fieldNameEquals(FieldType otherValue) { ... } 6610 6611 if (this == o) return true; 6612 if (o == null || getClass() != o.getClass()) return false; 6613 @SuppressWarnings("unchecked") 6614 AttributedHistoricalOps that = (AttributedHistoricalOps) o; 6615 //noinspection PointlessBooleanExpression 6616 return true 6617 && Objects.equals(mTag, that.mTag) 6618 && Objects.equals(mHistoricalOps, that.mHistoricalOps); 6619 } 6620 6621 @Override 6622 @DataClass.Generated.Member hashCode()6623 public int hashCode() { 6624 // You can override field hashCode logic by defining methods like: 6625 // int fieldNameHashCode() { ... } 6626 6627 int _hash = 1; 6628 _hash = 31 * _hash + Objects.hashCode(mTag); 6629 _hash = 31 * _hash + Objects.hashCode(mHistoricalOps); 6630 return _hash; 6631 } 6632 6633 @Override 6634 @DataClass.Generated.Member writeToParcel(@onNull Parcel dest, int flags)6635 public void writeToParcel(@NonNull Parcel dest, int flags) { 6636 // You can override field parcelling by defining methods like: 6637 // void parcelFieldName(Parcel dest, int flags) { ... } 6638 6639 byte flg = 0; 6640 if (mTag != null) flg |= 0x1; 6641 if (mHistoricalOps != null) flg |= 0x2; 6642 dest.writeByte(flg); 6643 if (mTag != null) dest.writeString(mTag); 6644 if (mHistoricalOps != null) dest.writeMap(mHistoricalOps); 6645 } 6646 6647 @Override 6648 @DataClass.Generated.Member describeContents()6649 public int describeContents() { return 0; } 6650 6651 /** @hide */ 6652 @SuppressWarnings({"unchecked", "RedundantCast"}) 6653 @DataClass.Generated.Member AttributedHistoricalOps(@onNull Parcel in)6654 /* package-private */ AttributedHistoricalOps(@NonNull Parcel in) { 6655 // You can override field unparcelling by defining methods like: 6656 // static FieldType unparcelFieldName(Parcel in) { ... } 6657 6658 byte flg = in.readByte(); 6659 String attributionTag = (flg & 0x1) == 0 ? null : in.readString(); 6660 ArrayMap<String,HistoricalOp> historicalOps = null; 6661 if ((flg & 0x2) != 0) { 6662 historicalOps = new ArrayMap(); 6663 in.readMap(historicalOps, HistoricalOp.class.getClassLoader()); 6664 } 6665 6666 this.mTag = attributionTag; 6667 this.mHistoricalOps = historicalOps; 6668 6669 // onConstructed(); // You can define this method to get a callback 6670 } 6671 6672 @DataClass.Generated.Member 6673 public static final @NonNull Parcelable.Creator<AttributedHistoricalOps> CREATOR 6674 = new Parcelable.Creator<AttributedHistoricalOps>() { 6675 @Override 6676 public AttributedHistoricalOps[] newArray(int size) { 6677 return new AttributedHistoricalOps[size]; 6678 } 6679 6680 @Override 6681 public AttributedHistoricalOps createFromParcel(@NonNull Parcel in) { 6682 return new AttributedHistoricalOps(in); 6683 } 6684 }; 6685 6686 /* 6687 @DataClass.Generated( 6688 time = 1578113234821L, 6689 codegenVersion = "1.0.14", 6690 sourceFile = "frameworks/base/core/java/android/app/AppOpsManager.java", 6691 inputSignatures = "private final @android.annotation.Nullable java.lang.String mAttributionTag\nprivate @android.annotation.Nullable android.util.ArrayMap<java.lang.String,android.app.HistoricalOp> mHistoricalOps\nprivate @android.annotation.Nullable android.app.HistoricalAttributionOps splice(double)\nprivate void merge(android.app.HistoricalAttributionOps)\nprivate void filter(java.lang.String[],int,double)\nprivate boolean isEmpty()\nprivate void increaseAccessCount(int,int,int,long)\nprivate void increaseRejectCount(int,int,int,long)\nprivate void increaseAccessDuration(int,int,int,long)\npublic @android.annotation.IntRange(from=0L) int getOpCount()\npublic @android.annotation.NonNull android.app.HistoricalOp getOpAt(int)\npublic @android.annotation.Nullable android.app.HistoricalOp getOp(java.lang.String)\nprivate void accept(android.app.HistoricalOpsVisitor)\nprivate @android.annotation.NonNull android.app.HistoricalOp getOrCreateHistoricalOp(int)\nclass HistoricalAttributionOps extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstructor=true, genEqualsHashCode=true, genHiddenCopyConstructor=true)") 6692 @Deprecated 6693 private void __metadata() {} 6694 */ 6695 6696 //@formatter:on 6697 // End of generated code 6698 6699 } 6700 6701 /** 6702 * This class represents historical information about an app op. 6703 * 6704 * @hide 6705 */ 6706 @SystemApi 6707 public static final class HistoricalOp implements Parcelable { 6708 private final int mOp; 6709 private @Nullable LongSparseLongArray mAccessCount; 6710 private @Nullable LongSparseLongArray mRejectCount; 6711 private @Nullable LongSparseLongArray mAccessDuration; 6712 6713 /** Discrete Ops for this Op */ 6714 private @Nullable List<AttributedOpEntry> mDiscreteAccesses; 6715 6716 /** @hide */ HistoricalOp(int op)6717 public HistoricalOp(int op) { 6718 mOp = op; 6719 } 6720 HistoricalOp(@onNull HistoricalOp other)6721 private HistoricalOp(@NonNull HistoricalOp other) { 6722 mOp = other.mOp; 6723 if (other.mAccessCount != null) { 6724 mAccessCount = other.mAccessCount.clone(); 6725 } 6726 if (other.mRejectCount != null) { 6727 mRejectCount = other.mRejectCount.clone(); 6728 } 6729 if (other.mAccessDuration != null) { 6730 mAccessDuration = other.mAccessDuration.clone(); 6731 } 6732 final int historicalOpCount = other.getDiscreteAccessCount(); 6733 for (int i = 0; i < historicalOpCount; i++) { 6734 final AttributedOpEntry origOp = other.getDiscreteAccessAt(i); 6735 final AttributedOpEntry cloneOp = new AttributedOpEntry(origOp); 6736 getOrCreateDiscreteAccesses().add(cloneOp); 6737 } 6738 } 6739 HistoricalOp(@onNull Parcel parcel)6740 private HistoricalOp(@NonNull Parcel parcel) { 6741 mOp = parcel.readInt(); 6742 mAccessCount = readLongSparseLongArrayFromParcel(parcel); 6743 mRejectCount = readLongSparseLongArrayFromParcel(parcel); 6744 mAccessDuration = readLongSparseLongArrayFromParcel(parcel); 6745 mDiscreteAccesses = readDiscreteAccessArrayFromParcel(parcel); 6746 } 6747 filter(@pHistoryFlags int historyFlag, double scaleFactor, long beginTimeMillis, long endTimeMillis)6748 private void filter(@OpHistoryFlags int historyFlag, double scaleFactor, 6749 long beginTimeMillis, long endTimeMillis) { 6750 if ((historyFlag & HISTORY_FLAG_AGGREGATE) == 0) { 6751 mAccessCount = null; 6752 mRejectCount = null; 6753 mAccessDuration = null; 6754 } else { 6755 scale(mAccessCount, scaleFactor); 6756 scale(mRejectCount, scaleFactor); 6757 scale(mAccessDuration, scaleFactor); 6758 } 6759 if ((historyFlag & HISTORY_FLAG_DISCRETE) == 0) { 6760 mDiscreteAccesses = null; 6761 return; 6762 } 6763 final int discreteOpCount = getDiscreteAccessCount(); 6764 for (int i = discreteOpCount - 1; i >= 0; i--) { 6765 final AttributedOpEntry op = mDiscreteAccesses.get(i); 6766 long opBeginTime = op.getLastAccessTime(OP_FLAGS_ALL); 6767 long opEndTime = opBeginTime + op.getLastDuration(OP_FLAGS_ALL); 6768 opEndTime = max(opBeginTime, opEndTime); 6769 if (opEndTime < beginTimeMillis || opBeginTime > endTimeMillis) { 6770 mDiscreteAccesses.remove(i); 6771 } 6772 } 6773 } 6774 isEmpty()6775 private boolean isEmpty() { 6776 return !hasData(mAccessCount) 6777 && !hasData(mRejectCount) 6778 && !hasData(mAccessDuration) 6779 && (mDiscreteAccesses == null); 6780 } 6781 hasData(@onNull LongSparseLongArray array)6782 private boolean hasData(@NonNull LongSparseLongArray array) { 6783 return array != null && array.size() > 0; 6784 } 6785 splice(double fractionToRemove)6786 private @Nullable HistoricalOp splice(double fractionToRemove) { 6787 final HistoricalOp splice = new HistoricalOp(mOp); 6788 splice(mAccessCount, splice::getOrCreateAccessCount, fractionToRemove); 6789 splice(mRejectCount, splice::getOrCreateRejectCount, fractionToRemove); 6790 splice(mAccessDuration, splice::getOrCreateAccessDuration, fractionToRemove); 6791 return splice; 6792 } 6793 splice(@ullable LongSparseLongArray sourceContainer, @NonNull Supplier<LongSparseLongArray> destContainerProvider, double fractionToRemove)6794 private static void splice(@Nullable LongSparseLongArray sourceContainer, 6795 @NonNull Supplier<LongSparseLongArray> destContainerProvider, 6796 double fractionToRemove) { 6797 if (sourceContainer != null) { 6798 final int size = sourceContainer.size(); 6799 for (int i = 0; i < size; i++) { 6800 final long key = sourceContainer.keyAt(i); 6801 final long value = sourceContainer.valueAt(i); 6802 final long removedFraction = Math.round(value * fractionToRemove); 6803 if (removedFraction > 0) { 6804 destContainerProvider.get().put(key, removedFraction); 6805 sourceContainer.put(key, value - removedFraction); 6806 } 6807 } 6808 } 6809 } 6810 merge(@onNull HistoricalOp other)6811 private void merge(@NonNull HistoricalOp other) { 6812 merge(this::getOrCreateAccessCount, other.mAccessCount); 6813 merge(this::getOrCreateRejectCount, other.mRejectCount); 6814 merge(this::getOrCreateAccessDuration, other.mAccessDuration); 6815 6816 if (other.mDiscreteAccesses == null) { 6817 return; 6818 } 6819 if (mDiscreteAccesses == null) { 6820 mDiscreteAccesses = new ArrayList(other.mDiscreteAccesses); 6821 return; 6822 } 6823 List<AttributedOpEntry> historicalDiscreteAccesses = new ArrayList<>(); 6824 final int otherHistoricalOpCount = other.getDiscreteAccessCount(); 6825 final int historicalOpCount = getDiscreteAccessCount(); 6826 int i = 0; 6827 int j = 0; 6828 while (i < otherHistoricalOpCount || j < historicalOpCount) { 6829 if (i == otherHistoricalOpCount) { 6830 historicalDiscreteAccesses.add(mDiscreteAccesses.get(j++)); 6831 } else if (j == historicalOpCount) { 6832 historicalDiscreteAccesses.add(other.mDiscreteAccesses.get(i++)); 6833 } else if (mDiscreteAccesses.get(j).getLastAccessTime(OP_FLAGS_ALL) 6834 < other.mDiscreteAccesses.get(i).getLastAccessTime(OP_FLAGS_ALL)) { 6835 historicalDiscreteAccesses.add(mDiscreteAccesses.get(j++)); 6836 } else { 6837 historicalDiscreteAccesses.add(other.mDiscreteAccesses.get(i++)); 6838 } 6839 } 6840 mDiscreteAccesses = deduplicateDiscreteEvents(historicalDiscreteAccesses); 6841 } 6842 increaseAccessCount(@idState int uidState, @OpFlags int flags, long increment)6843 private void increaseAccessCount(@UidState int uidState, @OpFlags int flags, 6844 long increment) { 6845 increaseCount(getOrCreateAccessCount(), uidState, flags, increment); 6846 } 6847 increaseRejectCount(@idState int uidState, @OpFlags int flags, long increment)6848 private void increaseRejectCount(@UidState int uidState, @OpFlags int flags, 6849 long increment) { 6850 increaseCount(getOrCreateRejectCount(), uidState, flags, increment); 6851 } 6852 increaseAccessDuration(@idState int uidState, @OpFlags int flags, long increment)6853 private void increaseAccessDuration(@UidState int uidState, @OpFlags int flags, 6854 long increment) { 6855 increaseCount(getOrCreateAccessDuration(), uidState, flags, increment); 6856 } 6857 increaseCount(@onNull LongSparseLongArray counts, @UidState int uidState, @OpFlags int flags, long increment)6858 private void increaseCount(@NonNull LongSparseLongArray counts, 6859 @UidState int uidState, @OpFlags int flags, long increment) { 6860 while (flags != 0) { 6861 final int flag = 1 << Integer.numberOfTrailingZeros(flags); 6862 flags &= ~flag; 6863 final long key = makeKey(uidState, flag); 6864 counts.put(key, counts.get(key) + increment); 6865 } 6866 } 6867 addDiscreteAccess(@idState int uidState, @OpFlags int flag, long discreteAccessTime, long discreteAccessDuration, @Nullable OpEventProxyInfo proxy)6868 private void addDiscreteAccess(@UidState int uidState, @OpFlags int flag, 6869 long discreteAccessTime, long discreteAccessDuration, 6870 @Nullable OpEventProxyInfo proxy) { 6871 List<AttributedOpEntry> discreteAccesses = getOrCreateDiscreteAccesses(); 6872 LongSparseArray<NoteOpEvent> accessEvents = new LongSparseArray<>(); 6873 long key = makeKey(uidState, flag); 6874 NoteOpEvent note = new NoteOpEvent(discreteAccessTime, discreteAccessDuration, proxy); 6875 accessEvents.append(key, note); 6876 AttributedOpEntry access = new AttributedOpEntry(mOp, false, accessEvents, null); 6877 int insertionPoint = discreteAccesses.size() - 1; 6878 for (; insertionPoint >= 0; insertionPoint--) { 6879 if (discreteAccesses.get(insertionPoint).getLastAccessTime(OP_FLAGS_ALL) 6880 < discreteAccessTime) { 6881 break; 6882 } 6883 } 6884 insertionPoint++; 6885 if (insertionPoint < discreteAccesses.size() && discreteAccesses.get( 6886 insertionPoint).getLastAccessTime(OP_FLAGS_ALL) == discreteAccessTime) { 6887 discreteAccesses.set(insertionPoint, mergeAttributedOpEntries( 6888 Arrays.asList(discreteAccesses.get(insertionPoint), access))); 6889 } else { 6890 discreteAccesses.add(insertionPoint, access); 6891 } 6892 } 6893 6894 /** 6895 * Gets the op name. 6896 * 6897 * @return The op name. 6898 */ getOpName()6899 public @NonNull String getOpName() { 6900 return sOpToString[mOp]; 6901 } 6902 6903 /** @hide */ getOpCode()6904 public int getOpCode() { 6905 return mOp; 6906 } 6907 6908 /** 6909 * Gets number of discrete historical app ops. 6910 * 6911 * @return The number historical app ops. 6912 * @see #getDiscreteAccessAt(int) 6913 */ getDiscreteAccessCount()6914 public @IntRange(from = 0) int getDiscreteAccessCount() { 6915 if (mDiscreteAccesses == null) { 6916 return 0; 6917 } 6918 return mDiscreteAccesses.size(); 6919 } 6920 6921 /** 6922 * Gets the historical op at a given index. 6923 * 6924 * @param index The index to lookup. 6925 * @return The op at the given index. 6926 * @see #getDiscreteAccessCount() 6927 */ getDiscreteAccessAt(@ntRangefrom = 0) int index)6928 public @NonNull AttributedOpEntry getDiscreteAccessAt(@IntRange(from = 0) int index) { 6929 if (mDiscreteAccesses == null) { 6930 throw new IndexOutOfBoundsException(); 6931 } 6932 return mDiscreteAccesses.get(index); 6933 } 6934 6935 /** 6936 * Gets the number times the op was accessed (performed) in the foreground. 6937 * 6938 * @param flags The flags which are any combination of 6939 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 6940 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 6941 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 6942 * for any flag. 6943 * @return The times the op was accessed in the foreground. 6944 * 6945 * @see #getBackgroundAccessCount(int) 6946 * @see #getAccessCount(int, int, int) 6947 */ getForegroundAccessCount(@pFlags int flags)6948 public long getForegroundAccessCount(@OpFlags int flags) { 6949 return sumForFlagsInStates(mAccessCount, MAX_PRIORITY_UID_STATE, 6950 resolveFirstUnrestrictedUidState(mOp), flags); 6951 } 6952 6953 /** 6954 * Gets the discrete events the op was accessed (performed) in the foreground. 6955 * 6956 * @param flags The flags which are any combination of 6957 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 6958 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 6959 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 6960 * for any flag. 6961 * @return The list of discrete ops accessed in the foreground. 6962 * 6963 * @see #getBackgroundDiscreteAccesses(int) 6964 * @see #getDiscreteAccesses(int, int, int) 6965 */ 6966 @NonNull getForegroundDiscreteAccesses(@pFlags int flags)6967 public List<AttributedOpEntry> getForegroundDiscreteAccesses(@OpFlags int flags) { 6968 return listForFlagsInStates(mDiscreteAccesses, MAX_PRIORITY_UID_STATE, 6969 resolveFirstUnrestrictedUidState(mOp), flags); 6970 } 6971 6972 /** 6973 * Gets the number times the op was accessed (performed) in the background. 6974 * 6975 * @param flags The flags which are any combination of 6976 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 6977 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 6978 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 6979 * for any flag. 6980 * @return The times the op was accessed in the background. 6981 * 6982 * @see #getForegroundAccessCount(int) 6983 * @see #getAccessCount(int, int, int) 6984 */ getBackgroundAccessCount(@pFlags int flags)6985 public long getBackgroundAccessCount(@OpFlags int flags) { 6986 return sumForFlagsInStates(mAccessCount, resolveLastRestrictedUidState(mOp), 6987 MIN_PRIORITY_UID_STATE, flags); 6988 } 6989 6990 /** 6991 * Gets the discrete events the op was accessed (performed) in the background. 6992 * 6993 * @param flags The flags which are any combination of 6994 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 6995 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 6996 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 6997 * for any flag. 6998 * @return The list of discrete ops accessed in the background. 6999 * 7000 * @see #getForegroundDiscreteAccesses(int) 7001 * @see #getDiscreteAccesses(int, int, int) 7002 */ 7003 @NonNull getBackgroundDiscreteAccesses(@pFlags int flags)7004 public List<AttributedOpEntry> getBackgroundDiscreteAccesses(@OpFlags int flags) { 7005 return listForFlagsInStates(mDiscreteAccesses, resolveLastRestrictedUidState(mOp), 7006 MIN_PRIORITY_UID_STATE, flags); 7007 } 7008 7009 /** 7010 * Gets the number times the op was accessed (performed) for a 7011 * range of uid states. 7012 * 7013 * @param fromUidState The UID state from which to query. Could be one of 7014 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP}, 7015 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND}, 7016 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}. 7017 * @param toUidState The UID state to which to query. 7018 * @param flags The flags which are any combination of 7019 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 7020 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 7021 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 7022 * for any flag. 7023 * 7024 * @return The times the op was accessed for the given UID state. 7025 * 7026 * @see #getForegroundAccessCount(int) 7027 * @see #getBackgroundAccessCount(int) 7028 */ getAccessCount(@idState int fromUidState, @UidState int toUidState, @OpFlags int flags)7029 public long getAccessCount(@UidState int fromUidState, @UidState int toUidState, 7030 @OpFlags int flags) { 7031 return sumForFlagsInStates(mAccessCount, fromUidState, toUidState, flags); 7032 } 7033 7034 /** 7035 * Gets the discrete events the op was accessed (performed) for a 7036 * range of uid states. 7037 * 7038 * @param flags The flags which are any combination of 7039 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 7040 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 7041 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 7042 * for any flag. 7043 * @return The discrete the op was accessed in the background. 7044 * 7045 * @see #getBackgroundDiscreteAccesses(int) 7046 * @see #getForegroundDiscreteAccesses(int) 7047 */ 7048 @NonNull getDiscreteAccesses(@idState int fromUidState, @UidState int toUidState, @OpFlags int flags)7049 public List<AttributedOpEntry> getDiscreteAccesses(@UidState int fromUidState, 7050 @UidState int toUidState, @OpFlags int flags) { 7051 return listForFlagsInStates(mDiscreteAccesses, fromUidState, toUidState, flags); 7052 } 7053 7054 /** 7055 * Gets the number times the op was rejected in the foreground. 7056 * 7057 * @param flags The flags which are any combination of 7058 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 7059 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 7060 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 7061 * for any flag. 7062 * @return The times the op was rejected in the foreground. 7063 * 7064 * @see #getBackgroundRejectCount(int) 7065 * @see #getRejectCount(int, int, int) 7066 */ getForegroundRejectCount(@pFlags int flags)7067 public long getForegroundRejectCount(@OpFlags int flags) { 7068 return sumForFlagsInStates(mRejectCount, MAX_PRIORITY_UID_STATE, 7069 resolveFirstUnrestrictedUidState(mOp), flags); 7070 } 7071 7072 /** 7073 * Gets the number times the op was rejected in the background. 7074 * 7075 * @param flags The flags which are any combination of 7076 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 7077 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 7078 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 7079 * for any flag. 7080 * @return The times the op was rejected in the background. 7081 * 7082 * @see #getForegroundRejectCount(int) 7083 * @see #getRejectCount(int, int, int) 7084 */ getBackgroundRejectCount(@pFlags int flags)7085 public long getBackgroundRejectCount(@OpFlags int flags) { 7086 return sumForFlagsInStates(mRejectCount, resolveLastRestrictedUidState(mOp), 7087 MIN_PRIORITY_UID_STATE, flags); 7088 } 7089 7090 /** 7091 * Gets the number times the op was rejected for a given range of UID states. 7092 * 7093 * @param fromUidState The UID state from which to query. Could be one of 7094 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP}, 7095 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND}, 7096 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}. 7097 * @param toUidState The UID state to which to query. 7098 * @param flags The flags which are any combination of 7099 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 7100 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 7101 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 7102 * for any flag. 7103 * 7104 * @return The times the op was rejected for the given UID state. 7105 * 7106 * @see #getForegroundRejectCount(int) 7107 * @see #getBackgroundRejectCount(int) 7108 */ getRejectCount(@idState int fromUidState, @UidState int toUidState, @OpFlags int flags)7109 public long getRejectCount(@UidState int fromUidState, @UidState int toUidState, 7110 @OpFlags int flags) { 7111 return sumForFlagsInStates(mRejectCount, fromUidState, toUidState, flags); 7112 } 7113 7114 /** 7115 * Gets the total duration the app op was accessed (performed) in the foreground. 7116 * The duration is in wall time. 7117 * 7118 * @param flags The flags which are any combination of 7119 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 7120 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 7121 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 7122 * for any flag. 7123 * @return The total duration the app op was accessed in the foreground. 7124 * 7125 * @see #getBackgroundAccessDuration(int) 7126 * @see #getAccessDuration(int, int, int) 7127 */ getForegroundAccessDuration(@pFlags int flags)7128 public long getForegroundAccessDuration(@OpFlags int flags) { 7129 return sumForFlagsInStates(mAccessDuration, MAX_PRIORITY_UID_STATE, 7130 resolveFirstUnrestrictedUidState(mOp), flags); 7131 } 7132 7133 /** 7134 * Gets the total duration the app op was accessed (performed) in the background. 7135 * The duration is in wall time. 7136 * 7137 * @param flags The flags which are any combination of 7138 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 7139 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 7140 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 7141 * for any flag. 7142 * @return The total duration the app op was accessed in the background. 7143 * 7144 * @see #getForegroundAccessDuration(int) 7145 * @see #getAccessDuration(int, int, int) 7146 */ getBackgroundAccessDuration(@pFlags int flags)7147 public long getBackgroundAccessDuration(@OpFlags int flags) { 7148 return sumForFlagsInStates(mAccessDuration, resolveLastRestrictedUidState(mOp), 7149 MIN_PRIORITY_UID_STATE, flags); 7150 } 7151 7152 /** 7153 * Gets the total duration the app op was accessed (performed) for a given 7154 * range of UID states. The duration is in wall time. 7155 * 7156 * @param fromUidState The UID state from which to query. Could be one of 7157 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP}, 7158 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND}, 7159 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}. 7160 * @param toUidState The UID state from which to query. 7161 * @param flags The flags which are any combination of 7162 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY}, 7163 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED}, 7164 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL} 7165 * for any flag. 7166 * 7167 * @return The total duration the app op was accessed for the given UID state. 7168 * 7169 * @see #getForegroundAccessDuration(int) 7170 * @see #getBackgroundAccessDuration(int) 7171 */ getAccessDuration(@idState int fromUidState, @UidState int toUidState, @OpFlags int flags)7172 public long getAccessDuration(@UidState int fromUidState, @UidState int toUidState, 7173 @OpFlags int flags) { 7174 return sumForFlagsInStates(mAccessDuration, fromUidState, toUidState, flags); 7175 } 7176 7177 @Override describeContents()7178 public int describeContents() { 7179 return 0; 7180 } 7181 7182 @Override writeToParcel(Parcel parcel, int flags)7183 public void writeToParcel(Parcel parcel, int flags) { 7184 parcel.writeInt(mOp); 7185 writeLongSparseLongArrayToParcel(mAccessCount, parcel); 7186 writeLongSparseLongArrayToParcel(mRejectCount, parcel); 7187 writeLongSparseLongArrayToParcel(mAccessDuration, parcel); 7188 writeDiscreteAccessArrayToParcel(mDiscreteAccesses, parcel, flags); 7189 } 7190 7191 @Override equals(@ullable Object obj)7192 public boolean equals(@Nullable Object obj) { 7193 if (this == obj) { 7194 return true; 7195 } 7196 if (obj == null || getClass() != obj.getClass()) { 7197 return false; 7198 } 7199 final HistoricalOp other = (HistoricalOp) obj; 7200 if (mOp != other.mOp) { 7201 return false; 7202 } 7203 if (!equalsLongSparseLongArray(mAccessCount, other.mAccessCount)) { 7204 return false; 7205 } 7206 if (!equalsLongSparseLongArray(mRejectCount, other.mRejectCount)) { 7207 return false; 7208 } 7209 if (!equalsLongSparseLongArray(mAccessDuration, other.mAccessDuration)) { 7210 return false; 7211 } 7212 return mDiscreteAccesses == null ? (other.mDiscreteAccesses == null ? true 7213 : false) : mDiscreteAccesses.equals(other.mDiscreteAccesses); 7214 } 7215 7216 @Override hashCode()7217 public int hashCode() { 7218 int result = mOp; 7219 result = 31 * result + Objects.hashCode(mAccessCount); 7220 result = 31 * result + Objects.hashCode(mRejectCount); 7221 result = 31 * result + Objects.hashCode(mAccessDuration); 7222 result = 31 * result + Objects.hashCode(mDiscreteAccesses); 7223 return result; 7224 } 7225 accept(@onNull HistoricalOpsVisitor visitor)7226 private void accept(@NonNull HistoricalOpsVisitor visitor) { 7227 visitor.visitHistoricalOp(this); 7228 } 7229 getOrCreateAccessCount()7230 private @NonNull LongSparseLongArray getOrCreateAccessCount() { 7231 if (mAccessCount == null) { 7232 mAccessCount = new LongSparseLongArray(); 7233 } 7234 return mAccessCount; 7235 } 7236 getOrCreateRejectCount()7237 private @NonNull LongSparseLongArray getOrCreateRejectCount() { 7238 if (mRejectCount == null) { 7239 mRejectCount = new LongSparseLongArray(); 7240 } 7241 return mRejectCount; 7242 } 7243 getOrCreateAccessDuration()7244 private @NonNull LongSparseLongArray getOrCreateAccessDuration() { 7245 if (mAccessDuration == null) { 7246 mAccessDuration = new LongSparseLongArray(); 7247 } 7248 return mAccessDuration; 7249 } 7250 getOrCreateDiscreteAccesses()7251 private @NonNull List<AttributedOpEntry> getOrCreateDiscreteAccesses() { 7252 if (mDiscreteAccesses == null) { 7253 mDiscreteAccesses = new ArrayList<>(); 7254 } 7255 return mDiscreteAccesses; 7256 } 7257 7258 /** 7259 * Multiplies the entries in the array with the passed in scale factor and 7260 * rounds the result at up 0.5 boundary. 7261 * 7262 * @param data The data to scale. 7263 * @param scaleFactor The scale factor. 7264 */ scale(@onNull LongSparseLongArray data, double scaleFactor)7265 private static void scale(@NonNull LongSparseLongArray data, double scaleFactor) { 7266 if (data != null) { 7267 final int size = data.size(); 7268 for (int i = 0; i < size; i++) { 7269 data.put(data.keyAt(i), (long) HistoricalOps.round( 7270 (double) data.valueAt(i) * scaleFactor)); 7271 } 7272 } 7273 } 7274 7275 /** 7276 * Merges two arrays while lazily acquiring the destination. 7277 * 7278 * @param thisSupplier The destination supplier. 7279 * @param other The array to merge in. 7280 */ merge(@onNull Supplier<LongSparseLongArray> thisSupplier, @Nullable LongSparseLongArray other)7281 private static void merge(@NonNull Supplier<LongSparseLongArray> thisSupplier, 7282 @Nullable LongSparseLongArray other) { 7283 if (other != null) { 7284 final int otherSize = other.size(); 7285 for (int i = 0; i < otherSize; i++) { 7286 final LongSparseLongArray that = thisSupplier.get(); 7287 final long otherKey = other.keyAt(i); 7288 final long otherValue = other.valueAt(i); 7289 that.put(otherKey, that.get(otherKey) + otherValue); 7290 } 7291 } 7292 } 7293 7294 /** @hide */ collectKeys()7295 public @Nullable LongSparseArray<Object> collectKeys() { 7296 LongSparseArray<Object> result = AppOpsManager.collectKeys(mAccessCount, 7297 null /*result*/); 7298 result = AppOpsManager.collectKeys(mRejectCount, result); 7299 result = AppOpsManager.collectKeys(mAccessDuration, result); 7300 return result; 7301 } 7302 7303 public static final @android.annotation.NonNull Creator<HistoricalOp> CREATOR = 7304 new Creator<HistoricalOp>() { 7305 @Override 7306 public @NonNull HistoricalOp createFromParcel(@NonNull Parcel source) { 7307 return new HistoricalOp(source); 7308 } 7309 7310 @Override 7311 public @NonNull HistoricalOp[] newArray(int size) { 7312 return new HistoricalOp[size]; 7313 } 7314 }; 7315 } 7316 7317 /** 7318 * Computes the sum of the counts for the given flags in between the begin and 7319 * end UID states. 7320 * 7321 * @param counts The data array. 7322 * @param beginUidState The beginning UID state (inclusive). 7323 * @param endUidState The end UID state (inclusive). 7324 * @param flags The UID flags. 7325 * @return The sum. 7326 */ sumForFlagsInStates(@ullable LongSparseLongArray counts, @UidState int beginUidState, @UidState int endUidState, @OpFlags int flags)7327 private static long sumForFlagsInStates(@Nullable LongSparseLongArray counts, 7328 @UidState int beginUidState, @UidState int endUidState, @OpFlags int flags) { 7329 if (counts == null) { 7330 return 0; 7331 } 7332 long sum = 0; 7333 while (flags != 0) { 7334 final int flag = 1 << Integer.numberOfTrailingZeros(flags); 7335 flags &= ~flag; 7336 for (int uidState : UID_STATES) { 7337 if (uidState < beginUidState || uidState > endUidState) { 7338 continue; 7339 } 7340 final long key = makeKey(uidState, flag); 7341 sum += counts.get(key); 7342 } 7343 } 7344 return sum; 7345 } 7346 7347 /** 7348 * Returns list of events filtered by UidState and UID flags. 7349 * 7350 * @param accesses The events list. 7351 * @param beginUidState The beginning UID state (inclusive). 7352 * @param endUidState The end UID state (inclusive). 7353 * @param flags The UID flags. 7354 * @return filtered list of events. 7355 */ listForFlagsInStates(List<AttributedOpEntry> accesses, @UidState int beginUidState, @UidState int endUidState, @OpFlags int flags)7356 private static List<AttributedOpEntry> listForFlagsInStates(List<AttributedOpEntry> accesses, 7357 @UidState int beginUidState, @UidState int endUidState, @OpFlags int flags) { 7358 List<AttributedOpEntry> result = new ArrayList<>(); 7359 if (accesses == null) { 7360 return result; 7361 } 7362 int nAccesses = accesses.size(); 7363 for (int i = 0; i < nAccesses; i++) { 7364 AttributedOpEntry entry = accesses.get(i); 7365 if (entry.getLastAccessTime(beginUidState, endUidState, flags) == -1) { 7366 continue; 7367 } 7368 result.add(entry); 7369 } 7370 return deduplicateDiscreteEvents(result); 7371 } 7372 7373 /** 7374 * Callback for notification of changes to operation state. 7375 */ 7376 public interface OnOpChangedListener { onOpChanged(String op, String packageName)7377 public void onOpChanged(String op, String packageName); 7378 } 7379 7380 /** 7381 * Callback for notification of changes to operation active state. 7382 */ 7383 public interface OnOpActiveChangedListener { 7384 /** 7385 * Called when the active state of an app-op changes. 7386 * 7387 * @param op The operation that changed. 7388 * @param packageName The package performing the operation. 7389 * @param active Whether the operation became active or inactive. 7390 */ onOpActiveChanged(@onNull String op, int uid, @NonNull String packageName, boolean active)7391 void onOpActiveChanged(@NonNull String op, int uid, @NonNull String packageName, 7392 boolean active); 7393 7394 /** 7395 * Called when the active state of an app-op changes. 7396 * 7397 * @param op The operation that changed. 7398 * @param uid The UID performing the operation. 7399 * @param packageName The package performing the operation. 7400 * @param attributionTag The operation's attribution tag. 7401 * @param active Whether the operation became active or inactive. 7402 * @param attributionFlags the attribution flags for this operation. 7403 * @param attributionChainId the unique id of the attribution chain this op is a part of. 7404 * @hide 7405 */ 7406 @TestApi onOpActiveChanged(@onNull String op, int uid, @NonNull String packageName, @Nullable String attributionTag, boolean active, @AttributionFlags int attributionFlags, int attributionChainId)7407 default void onOpActiveChanged(@NonNull String op, int uid, @NonNull String packageName, 7408 @Nullable String attributionTag, boolean active, @AttributionFlags 7409 int attributionFlags, int attributionChainId) { 7410 onOpActiveChanged(op, uid, packageName, active); 7411 } 7412 } 7413 7414 /** 7415 * Callback for notification of an op being noted. 7416 * 7417 * @hide 7418 */ 7419 public interface OnOpNotedListener { 7420 /** 7421 * Called when an op was noted. 7422 * @param code The op code. 7423 * @param uid The UID performing the operation. 7424 * @param packageName The package performing the operation. 7425 * @param attributionTag The attribution tag performing the operation. 7426 * @param flags The flags of this op 7427 * @param result The result of the note. 7428 */ onOpNoted(int code, int uid, String packageName, String attributionTag, @OpFlags int flags, @Mode int result)7429 void onOpNoted(int code, int uid, String packageName, String attributionTag, 7430 @OpFlags int flags, @Mode int result); 7431 } 7432 7433 /** 7434 * Callback for notification of changes to operation state. 7435 * This allows you to see the raw op codes instead of strings. 7436 * @hide 7437 */ 7438 public static class OnOpChangedInternalListener implements OnOpChangedListener { onOpChanged(String op, String packageName)7439 public void onOpChanged(String op, String packageName) { } onOpChanged(int op, String packageName)7440 public void onOpChanged(int op, String packageName) { } 7441 } 7442 7443 /** 7444 * Callback for notification of changes to operation state. 7445 * This allows you to see the raw op codes instead of strings. 7446 * @hide 7447 */ 7448 public interface OnOpActiveChangedInternalListener extends OnOpActiveChangedListener { onOpActiveChanged(String op, int uid, String packageName, boolean active)7449 default void onOpActiveChanged(String op, int uid, String packageName, boolean active) { } onOpActiveChanged(int op, int uid, String packageName, boolean active)7450 default void onOpActiveChanged(int op, int uid, String packageName, boolean active) { } 7451 } 7452 7453 /** 7454 * Callback for notification of an op being started. 7455 * 7456 * @hide 7457 */ 7458 public interface OnOpStartedListener { 7459 7460 /** 7461 * Represents a start operation that was unsuccessful 7462 * @hide 7463 */ 7464 public int START_TYPE_FAILED = 0; 7465 7466 /** 7467 * Represents a successful start operation 7468 * @hide 7469 */ 7470 public int START_TYPE_STARTED = 1; 7471 7472 /** 7473 * Represents an operation where a restricted operation became unrestricted, and resumed. 7474 * @hide 7475 */ 7476 public int START_TYPE_RESUMED = 2; 7477 7478 /** @hide */ 7479 @Retention(RetentionPolicy.SOURCE) 7480 @IntDef(flag = true, prefix = { "TYPE_" }, value = { 7481 START_TYPE_FAILED, 7482 START_TYPE_STARTED, 7483 START_TYPE_RESUMED 7484 }) 7485 public @interface StartedType {} 7486 7487 /** 7488 * Called when an op was started. 7489 * 7490 * Note: This is only for op starts. It is not called when an op is noted or stopped. 7491 * @param op The op code. 7492 * @param uid The UID performing the operation. 7493 * @param packageName The package performing the operation. 7494 * @param attributionTag The attribution tag performing the operation. 7495 * @param flags The flags of this op. 7496 * @param result The result of the start. 7497 */ onOpStarted(int op, int uid, String packageName, String attributionTag, @OpFlags int flags, @Mode int result)7498 void onOpStarted(int op, int uid, String packageName, String attributionTag, 7499 @OpFlags int flags, @Mode int result); 7500 7501 /** 7502 * Called when an op was started. 7503 * 7504 * Note: This is only for op starts. It is not called when an op is noted or stopped. 7505 * By default, unless this method is overridden, no code will be executed for resume 7506 * events. 7507 * @param op The op code. 7508 * @param uid The UID performing the operation. 7509 * @param packageName The package performing the operation. 7510 * @param attributionTag The attribution tag performing the operation. 7511 * @param flags The flags of this op. 7512 * @param result The result of the start. 7513 * @param startType The start type of this start event. Either failed, resumed, or started. 7514 * @param attributionFlags The location of this started op in an attribution chain. 7515 * @param attributionChainId The ID of the attribution chain of this op, if it is in one. 7516 */ onOpStarted(int op, int uid, String packageName, String attributionTag, @OpFlags int flags, @Mode int result, @StartedType int startType, @AttributionFlags int attributionFlags, int attributionChainId)7517 default void onOpStarted(int op, int uid, String packageName, String attributionTag, 7518 @OpFlags int flags, @Mode int result, @StartedType int startType, 7519 @AttributionFlags int attributionFlags, int attributionChainId) { 7520 if (startType != START_TYPE_RESUMED) { 7521 onOpStarted(op, uid, packageName, attributionTag, flags, result); 7522 } 7523 } 7524 } 7525 AppOpsManager(Context context, IAppOpsService service)7526 AppOpsManager(Context context, IAppOpsService service) { 7527 mContext = context; 7528 mService = service; 7529 7530 if (mContext != null) { 7531 final PackageManager pm = mContext.getPackageManager(); 7532 try { 7533 if (pm != null && pm.checkPermission(Manifest.permission.READ_DEVICE_CONFIG, 7534 mContext.getPackageName()) == PackageManager.PERMISSION_GRANTED) { 7535 DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_PRIVACY, 7536 mContext.getMainExecutor(), properties -> { 7537 if (properties.getKeyset().contains(FULL_LOG)) { 7538 sFullLog = properties.getBoolean(FULL_LOG, false); 7539 } 7540 }); 7541 return; 7542 } 7543 } catch (Exception e) { 7544 // This manager was made before DeviceConfig is ready, so it's a low-level 7545 // system app. We likely don't care about its logs. 7546 } 7547 } 7548 sFullLog = false; 7549 } 7550 7551 /** 7552 * Retrieve current operation state for all applications. 7553 * 7554 * The mode of the ops returned are set for the package but may not reflect their effective 7555 * state due to UID policy or because it's controlled by a different global op. 7556 * 7557 * Use {@link #unsafeCheckOp(String, int, String)}} or 7558 * {@link #noteOp(String, int, String, String, String)} if the effective mode is needed. 7559 * 7560 * @param ops The set of operations you are interested in, or null if you want all of them. 7561 * @hide 7562 */ 7563 @SystemApi 7564 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) getPackagesForOps(@ullable String[] ops)7565 public @NonNull List<AppOpsManager.PackageOps> getPackagesForOps(@Nullable String[] ops) { 7566 final int opCount = ops.length; 7567 final int[] opCodes = new int[opCount]; 7568 for (int i = 0; i < opCount; i++) { 7569 opCodes[i] = sOpStrToOp.get(ops[i]); 7570 } 7571 final List<AppOpsManager.PackageOps> result = getPackagesForOps(opCodes); 7572 return (result != null) ? result : Collections.emptyList(); 7573 } 7574 7575 /** 7576 * Retrieve current operation state for all applications. 7577 * 7578 * The mode of the ops returned are set for the package but may not reflect their effective 7579 * state due to UID policy or because it's controlled by a different global op. 7580 * 7581 * Use {@link #unsafeCheckOp(String, int, String)}} or 7582 * {@link #noteOp(String, int, String, String, String)} if the effective mode is needed. 7583 * 7584 * @param ops The set of operations you are interested in, or null if you want all of them. 7585 * @hide 7586 */ 7587 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) 7588 @UnsupportedAppUsage getPackagesForOps(int[] ops)7589 public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) { 7590 try { 7591 return mService.getPackagesForOps(ops); 7592 } catch (RemoteException e) { 7593 throw e.rethrowFromSystemServer(); 7594 } 7595 } 7596 7597 /** 7598 * Retrieve current operation state for one application. 7599 * 7600 * The mode of the ops returned are set for the package but may not reflect their effective 7601 * state due to UID policy or because it's controlled by a different global op. 7602 * 7603 * Use {@link #unsafeCheckOp(String, int, String)}} or 7604 * {@link #noteOp(String, int, String, String, String)} if the effective mode is needed. 7605 * 7606 * @param uid The uid of the application of interest. 7607 * @param packageName The name of the application of interest. 7608 * @param ops The set of operations you are interested in, or null if you want all of them. 7609 * 7610 * @deprecated The int op codes are not stable and you should use the string based op 7611 * names which are stable and namespaced. Use 7612 * {@link #getOpsForPackage(int, String, String...)})}. 7613 * 7614 * @hide 7615 * @removed 7616 */ 7617 @Deprecated 7618 @SystemApi 7619 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) getOpsForPackage(int uid, @NonNull String packageName, @Nullable int[] ops)7620 public @NonNull List<PackageOps> getOpsForPackage(int uid, @NonNull String packageName, 7621 @Nullable int[] ops) { 7622 try { 7623 return mService.getOpsForPackage(uid, packageName, ops); 7624 } catch (RemoteException e) { 7625 throw e.rethrowFromSystemServer(); 7626 } 7627 } 7628 7629 /** 7630 * Retrieve current operation state for one application. The UID and the 7631 * package must match. 7632 * 7633 * The mode of the ops returned are set for the package but may not reflect their effective 7634 * state due to UID policy or because it's controlled by a different global op. 7635 * 7636 * Use {@link #unsafeCheckOp(String, int, String)}} or 7637 * {@link #noteOp(String, int, String, String, String)} if the effective mode is needed. 7638 * 7639 * @param uid The uid of the application of interest. 7640 * @param packageName The name of the application of interest. 7641 * @param ops The set of operations you are interested in, or null if you want all of them. 7642 * 7643 * @hide 7644 */ 7645 @SystemApi 7646 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) getOpsForPackage(int uid, @NonNull String packageName, @Nullable String... ops)7647 public @NonNull List<AppOpsManager.PackageOps> getOpsForPackage(int uid, 7648 @NonNull String packageName, @Nullable String... ops) { 7649 int[] opCodes = null; 7650 if (ops != null) { 7651 opCodes = new int[ops.length]; 7652 for (int i = 0; i < ops.length; i++) { 7653 opCodes[i] = strOpToOp(ops[i]); 7654 } 7655 } 7656 try { 7657 final List<PackageOps> result = mService.getOpsForPackage(uid, packageName, opCodes); 7658 if (result == null) { 7659 return Collections.emptyList(); 7660 } 7661 return result; 7662 } catch (RemoteException e) { 7663 throw e.rethrowFromSystemServer(); 7664 } 7665 } 7666 7667 /** 7668 * Retrieve historical app op stats for a period. 7669 * 7670 * @param request A request object describing the data being queried for. 7671 * @param executor Executor on which to run the callback. If <code>null</code> 7672 * the callback is executed on the default executor running on the main thread. 7673 * @param callback Callback on which to deliver the result. 7674 * 7675 * @throws IllegalArgumentException If any of the argument contracts is violated. 7676 * 7677 * @hide 7678 */ 7679 @SystemApi 7680 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) getHistoricalOps(@onNull HistoricalOpsRequest request, @NonNull Executor executor, @NonNull Consumer<HistoricalOps> callback)7681 public void getHistoricalOps(@NonNull HistoricalOpsRequest request, 7682 @NonNull Executor executor, @NonNull Consumer<HistoricalOps> callback) { 7683 Objects.requireNonNull(executor, "executor cannot be null"); 7684 Objects.requireNonNull(callback, "callback cannot be null"); 7685 try { 7686 mService.getHistoricalOps(request.mUid, request.mPackageName, request.mAttributionTag, 7687 request.mOpNames, request.mHistoryFlags, request.mFilter, 7688 request.mBeginTimeMillis, request.mEndTimeMillis, request.mFlags, 7689 new RemoteCallback((result) -> { 7690 final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS); 7691 final long identity = Binder.clearCallingIdentity(); 7692 try { 7693 executor.execute(() -> callback.accept(ops)); 7694 } finally { 7695 Binder.restoreCallingIdentity(identity); 7696 } 7697 })); 7698 } catch (RemoteException e) { 7699 throw e.rethrowFromSystemServer(); 7700 } 7701 } 7702 7703 /** 7704 * Retrieve historical app op stats for a period. 7705 * <p> 7706 * This method queries only the on disk state and the returned ops are raw, 7707 * which is their times are relative to the history start as opposed to the 7708 * epoch start. 7709 * 7710 * @param request A request object describing the data being queried for. 7711 * @param executor Executor on which to run the callback. If <code>null</code> 7712 * the callback is executed on the default executor running on the main thread. 7713 * @param callback Callback on which to deliver the result. 7714 * 7715 * @throws IllegalArgumentException If any of the argument contracts is violated. 7716 * 7717 * @hide 7718 */ 7719 @TestApi 7720 @RequiresPermission(Manifest.permission.MANAGE_APPOPS) getHistoricalOpsFromDiskRaw(@onNull HistoricalOpsRequest request, @Nullable Executor executor, @NonNull Consumer<HistoricalOps> callback)7721 public void getHistoricalOpsFromDiskRaw(@NonNull HistoricalOpsRequest request, 7722 @Nullable Executor executor, @NonNull Consumer<HistoricalOps> callback) { 7723 Objects.requireNonNull(executor, "executor cannot be null"); 7724 Objects.requireNonNull(callback, "callback cannot be null"); 7725 try { 7726 mService.getHistoricalOpsFromDiskRaw(request.mUid, request.mPackageName, 7727 request.mAttributionTag, request.mOpNames, request.mHistoryFlags, 7728 request.mFilter, request.mBeginTimeMillis, request.mEndTimeMillis, 7729 request.mFlags, new RemoteCallback((result) -> { 7730 final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS); 7731 final long identity = Binder.clearCallingIdentity(); 7732 try { 7733 executor.execute(() -> callback.accept(ops)); 7734 } finally { 7735 Binder.restoreCallingIdentity(identity); 7736 } 7737 })); 7738 } catch (RemoteException e) { 7739 throw e.rethrowFromSystemServer(); 7740 } 7741 } 7742 7743 /** 7744 * Reloads the non historical state to allow testing the read/write path. 7745 * 7746 * @hide 7747 */ 7748 @TestApi 7749 @RequiresPermission(Manifest.permission.MANAGE_APPOPS) reloadNonHistoricalState()7750 public void reloadNonHistoricalState() { 7751 try { 7752 mService.reloadNonHistoricalState(); 7753 } catch (RemoteException e) { 7754 throw e.rethrowFromSystemServer(); 7755 } 7756 } 7757 7758 /** 7759 * Sets given app op in the specified mode for app ops in the UID. 7760 * This applies to all apps currently in the UID or installed in 7761 * this UID in the future. 7762 * 7763 * @param code The app op. 7764 * @param uid The UID for which to set the app. 7765 * @param mode The app op mode to set. 7766 * @hide 7767 */ 7768 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES) setUidMode(int code, int uid, @Mode int mode)7769 public void setUidMode(int code, int uid, @Mode int mode) { 7770 try { 7771 mService.setUidMode(code, uid, mode); 7772 } catch (RemoteException e) { 7773 throw e.rethrowFromSystemServer(); 7774 } 7775 } 7776 7777 /** 7778 * Sets given app op in the specified mode for app ops in the UID. 7779 * This applies to all apps currently in the UID or installed in 7780 * this UID in the future. 7781 * 7782 * @param appOp The app op. 7783 * @param uid The UID for which to set the app. 7784 * @param mode The app op mode to set. 7785 * @hide 7786 */ 7787 @SystemApi 7788 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES) setUidMode(@onNull String appOp, int uid, @Mode int mode)7789 public void setUidMode(@NonNull String appOp, int uid, @Mode int mode) { 7790 try { 7791 mService.setUidMode(AppOpsManager.strOpToOp(appOp), uid, mode); 7792 } catch (RemoteException e) { 7793 throw e.rethrowFromSystemServer(); 7794 } 7795 } 7796 7797 /** @hide */ setUserRestriction(int code, boolean restricted, IBinder token)7798 public void setUserRestriction(int code, boolean restricted, IBinder token) { 7799 setUserRestriction(code, restricted, token, null); 7800 } 7801 7802 /** 7803 * An empty array of attribution tags means exclude all tags under that package. 7804 * @hide 7805 */ setUserRestriction(int code, boolean restricted, IBinder token, @Nullable PackageTagsList excludedPackageTags)7806 public void setUserRestriction(int code, boolean restricted, IBinder token, 7807 @Nullable PackageTagsList excludedPackageTags) { 7808 setUserRestrictionForUser(code, restricted, token, excludedPackageTags, 7809 mContext.getUserId()); 7810 } 7811 7812 /** 7813 * An empty array of attribution tags means exclude all tags under that package. 7814 * @hide 7815 */ setUserRestrictionForUser(int code, boolean restricted, IBinder token, @Nullable PackageTagsList excludedPackageTags, int userId)7816 public void setUserRestrictionForUser(int code, boolean restricted, IBinder token, 7817 @Nullable PackageTagsList excludedPackageTags, int userId) { 7818 try { 7819 mService.setUserRestriction(code, restricted, token, userId, excludedPackageTags); 7820 } catch (RemoteException e) { 7821 throw e.rethrowFromSystemServer(); 7822 } 7823 } 7824 7825 /** @hide */ 7826 @UnsupportedAppUsage 7827 @TestApi 7828 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES) setMode(int code, int uid, String packageName, @Mode int mode)7829 public void setMode(int code, int uid, String packageName, @Mode int mode) { 7830 try { 7831 mService.setMode(code, uid, packageName, mode); 7832 } catch (RemoteException e) { 7833 throw e.rethrowFromSystemServer(); 7834 } 7835 } 7836 7837 /** 7838 * Change the operating mode for the given op in the given app package. You must pass 7839 * in both the uid and name of the application whose mode is being modified; if these 7840 * do not match, the modification will not be applied. 7841 * 7842 * @param op The operation to modify. One of the OPSTR_* constants. 7843 * @param uid The user id of the application whose mode will be changed. 7844 * @param packageName The name of the application package name whose mode will 7845 * be changed. 7846 * @hide 7847 */ 7848 @SystemApi 7849 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES) setMode(@onNull String op, int uid, @Nullable String packageName, @Mode int mode)7850 public void setMode(@NonNull String op, int uid, @Nullable String packageName, 7851 @Mode int mode) { 7852 try { 7853 mService.setMode(strOpToOp(op), uid, packageName, mode); 7854 } catch (RemoteException e) { 7855 throw e.rethrowFromSystemServer(); 7856 } 7857 } 7858 7859 /** 7860 * Set a non-persisted restriction on an audio operation at a stream-level. 7861 * Restrictions are temporary additional constraints imposed on top of the persisted rules 7862 * defined by {@link #setMode}. 7863 * 7864 * @param code The operation to restrict. 7865 * @param usage The {@link android.media.AudioAttributes} usage value. 7866 * @param mode The restriction mode (MODE_IGNORED,MODE_ERRORED) or MODE_ALLOWED to unrestrict. 7867 * @param exceptionPackages Optional list of packages to exclude from the restriction. 7868 * @hide 7869 */ 7870 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES) 7871 @UnsupportedAppUsage setRestriction(int code, @AttributeUsage int usage, @Mode int mode, String[] exceptionPackages)7872 public void setRestriction(int code, @AttributeUsage int usage, @Mode int mode, 7873 String[] exceptionPackages) { 7874 try { 7875 final int uid = Binder.getCallingUid(); 7876 mService.setAudioRestriction(code, usage, uid, mode, exceptionPackages); 7877 } catch (RemoteException e) { 7878 throw e.rethrowFromSystemServer(); 7879 } 7880 } 7881 7882 /** @hide */ 7883 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES) 7884 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) resetAllModes()7885 public void resetAllModes() { 7886 try { 7887 mService.resetAllModes(mContext.getUserId(), null); 7888 } catch (RemoteException e) { 7889 throw e.rethrowFromSystemServer(); 7890 } 7891 } 7892 7893 /** 7894 * Gets the app-op name associated with a given permission. 7895 * 7896 * <p>The app-op name is one of the public constants defined 7897 * in this class such as {@link #OPSTR_COARSE_LOCATION}. 7898 * This API is intended to be used for mapping runtime 7899 * permissions to the corresponding app-op. 7900 * 7901 * @param permission The permission. 7902 * @return The app-op associated with the permission or {@code null}. 7903 */ permissionToOp(@onNull String permission)7904 public static @Nullable String permissionToOp(@NonNull String permission) { 7905 final Integer opCode = sPermToOp.get(permission); 7906 if (opCode == null) { 7907 return null; 7908 } 7909 return sOpToString[opCode]; 7910 } 7911 7912 /** 7913 * Resolves special UID's pakcages such as root, shell, media, etc. 7914 * 7915 * @param uid The uid to resolve. 7916 * @param packageName Optional package. If caller system and null returns "android" 7917 * @return The resolved package name. 7918 * 7919 * @hide 7920 */ resolvePackageName(int uid, @Nullable String packageName)7921 public static @Nullable String resolvePackageName(int uid, @Nullable String packageName) { 7922 if (uid == Process.ROOT_UID) { 7923 return "root"; 7924 } else if (uid == Process.SHELL_UID) { 7925 return "com.android.shell"; 7926 } else if (uid == Process.MEDIA_UID) { 7927 return "media"; 7928 } else if (uid == Process.AUDIOSERVER_UID) { 7929 return "audioserver"; 7930 } else if (uid == Process.CAMERASERVER_UID) { 7931 return "cameraserver"; 7932 } else if (uid == Process.SYSTEM_UID && packageName == null) { 7933 return "android"; 7934 } 7935 return packageName; 7936 } 7937 7938 /** 7939 * Monitor for changes to the operating mode for the given op in the given app package. 7940 * You can watch op changes only for your UID. 7941 * 7942 * @param op The operation to monitor, one of OPSTR_*. 7943 * @param packageName The name of the application to monitor. 7944 * @param callback Where to report changes. 7945 */ startWatchingMode(@onNull String op, @Nullable String packageName, @NonNull final OnOpChangedListener callback)7946 public void startWatchingMode(@NonNull String op, @Nullable String packageName, 7947 @NonNull final OnOpChangedListener callback) { 7948 startWatchingMode(strOpToOp(op), packageName, callback); 7949 } 7950 7951 /** 7952 * Monitor for changes to the operating mode for the given op in the given app package. 7953 * You can watch op changes only for your UID. 7954 * 7955 * @param op The operation to monitor, one of OPSTR_*. 7956 * @param packageName The name of the application to monitor. 7957 * @param flags Option flags: any combination of {@link #WATCH_FOREGROUND_CHANGES} or 0. 7958 * @param callback Where to report changes. 7959 */ startWatchingMode(@onNull String op, @Nullable String packageName, int flags, @NonNull final OnOpChangedListener callback)7960 public void startWatchingMode(@NonNull String op, @Nullable String packageName, int flags, 7961 @NonNull final OnOpChangedListener callback) { 7962 startWatchingMode(strOpToOp(op), packageName, flags, callback); 7963 } 7964 7965 /** 7966 * Monitor for changes to the operating mode for the given op in the given app package. 7967 * 7968 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission 7969 * you can watch changes only for your UID. 7970 * 7971 * @param op The operation to monitor, one of OP_*. 7972 * @param packageName The name of the application to monitor. 7973 * @param callback Where to report changes. 7974 * @hide 7975 */ 7976 @RequiresPermission(value=android.Manifest.permission.WATCH_APPOPS, conditional=true) startWatchingMode(int op, String packageName, final OnOpChangedListener callback)7977 public void startWatchingMode(int op, String packageName, final OnOpChangedListener callback) { 7978 startWatchingMode(op, packageName, 0, callback); 7979 } 7980 7981 /** 7982 * Monitor for changes to the operating mode for the given op in the given app package. 7983 * 7984 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission 7985 * you can watch changes only for your UID. 7986 * 7987 * @param op The operation to monitor, one of OP_*. 7988 * @param packageName The name of the application to monitor. 7989 * @param flags Option flags: any combination of {@link #WATCH_FOREGROUND_CHANGES} or 0. 7990 * @param callback Where to report changes. 7991 * @hide 7992 */ 7993 @RequiresPermission(value=android.Manifest.permission.WATCH_APPOPS, conditional=true) startWatchingMode(int op, String packageName, int flags, final OnOpChangedListener callback)7994 public void startWatchingMode(int op, String packageName, int flags, 7995 final OnOpChangedListener callback) { 7996 synchronized (mModeWatchers) { 7997 IAppOpsCallback cb = mModeWatchers.get(callback); 7998 if (cb == null) { 7999 cb = new IAppOpsCallback.Stub() { 8000 public void opChanged(int op, int uid, String packageName) { 8001 if (callback instanceof OnOpChangedInternalListener) { 8002 ((OnOpChangedInternalListener)callback).onOpChanged(op, packageName); 8003 } 8004 if (sOpToString[op] != null) { 8005 callback.onOpChanged(sOpToString[op], packageName); 8006 } 8007 } 8008 }; 8009 mModeWatchers.put(callback, cb); 8010 } 8011 8012 // See CALL_BACK_ON_CHANGED_LISTENER_WITH_SWITCHED_OP_CHANGE 8013 if (!Compatibility.isChangeEnabled( 8014 CALL_BACK_ON_CHANGED_LISTENER_WITH_SWITCHED_OP_CHANGE)) { 8015 flags |= CALL_BACK_ON_SWITCHED_OP; 8016 } 8017 8018 try { 8019 mService.startWatchingModeWithFlags(op, packageName, flags, cb); 8020 } catch (RemoteException e) { 8021 throw e.rethrowFromSystemServer(); 8022 } 8023 } 8024 } 8025 8026 /** 8027 * Stop monitoring that was previously started with {@link #startWatchingMode}. All 8028 * monitoring associated with this callback will be removed. 8029 */ stopWatchingMode(@onNull OnOpChangedListener callback)8030 public void stopWatchingMode(@NonNull OnOpChangedListener callback) { 8031 synchronized (mModeWatchers) { 8032 IAppOpsCallback cb = mModeWatchers.remove(callback); 8033 if (cb != null) { 8034 try { 8035 mService.stopWatchingMode(cb); 8036 } catch (RemoteException e) { 8037 throw e.rethrowFromSystemServer(); 8038 } 8039 } 8040 } 8041 } 8042 8043 /** {@hide} */ 8044 @Deprecated startWatchingActive(@onNull int[] ops, @NonNull OnOpActiveChangedListener callback)8045 public void startWatchingActive(@NonNull int[] ops, 8046 @NonNull OnOpActiveChangedListener callback) { 8047 final String[] strOps = new String[ops.length]; 8048 for (int i = 0; i < ops.length; i++) { 8049 strOps[i] = opToPublicName(ops[i]); 8050 } 8051 startWatchingActive(strOps, mContext.getMainExecutor(), callback); 8052 } 8053 8054 /** 8055 * Start watching for changes to the active state of app-ops. An app-op may be 8056 * long running and it has a clear start and stop delimiters. If an op is being 8057 * started or stopped by any package you will get a callback. To change the 8058 * watched ops for a registered callback you need to unregister and register it 8059 * again. 8060 * 8061 * <p> If you don't hold the {@code android.Manifest.permission#WATCH_APPOPS} permission 8062 * you can watch changes only for your UID. 8063 * 8064 * @param ops The operations to watch. 8065 * @param callback Where to report changes. 8066 * 8067 * @see #stopWatchingActive 8068 */ 8069 // TODO: Uncomment below annotation once b/73559440 is fixed 8070 // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true) startWatchingActive(@onNull String[] ops, @CallbackExecutor @NonNull Executor executor, @NonNull OnOpActiveChangedListener callback)8071 public void startWatchingActive(@NonNull String[] ops, 8072 @CallbackExecutor @NonNull Executor executor, 8073 @NonNull OnOpActiveChangedListener callback) { 8074 Objects.requireNonNull(ops); 8075 Objects.requireNonNull(executor); 8076 Objects.requireNonNull(callback); 8077 IAppOpsActiveCallback cb; 8078 synchronized (mActiveWatchers) { 8079 cb = mActiveWatchers.get(callback); 8080 if (cb != null) { 8081 return; 8082 } 8083 cb = new IAppOpsActiveCallback.Stub() { 8084 @Override 8085 public void opActiveChanged(int op, int uid, String packageName, 8086 String attributionTag, boolean active, @AttributionFlags 8087 int attributionFlags, int attributionChainId) { 8088 executor.execute(() -> { 8089 if (callback instanceof OnOpActiveChangedInternalListener) { 8090 ((OnOpActiveChangedInternalListener) callback).onOpActiveChanged(op, 8091 uid, packageName, active); 8092 } 8093 if (sOpToString[op] != null) { 8094 callback.onOpActiveChanged(sOpToString[op], uid, packageName, 8095 attributionTag, active, attributionFlags, attributionChainId); 8096 } 8097 }); 8098 } 8099 }; 8100 mActiveWatchers.put(callback, cb); 8101 } 8102 final int[] rawOps = new int[ops.length]; 8103 for (int i = 0; i < ops.length; i++) { 8104 rawOps[i] = strOpToOp(ops[i]); 8105 } 8106 try { 8107 mService.startWatchingActive(rawOps, cb); 8108 } catch (RemoteException e) { 8109 throw e.rethrowFromSystemServer(); 8110 } 8111 } 8112 8113 /** 8114 * Stop watching for changes to the active state of an app-op. An app-op may be 8115 * long running and it has a clear start and stop delimiters. Unregistering a 8116 * non-registered callback has no effect. 8117 * 8118 * @see #startWatchingActive 8119 */ stopWatchingActive(@onNull OnOpActiveChangedListener callback)8120 public void stopWatchingActive(@NonNull OnOpActiveChangedListener callback) { 8121 synchronized (mActiveWatchers) { 8122 final IAppOpsActiveCallback cb = mActiveWatchers.remove(callback); 8123 if (cb != null) { 8124 try { 8125 mService.stopWatchingActive(cb); 8126 } catch (RemoteException e) { 8127 throw e.rethrowFromSystemServer(); 8128 } 8129 } 8130 } 8131 } 8132 8133 /** 8134 * Start watching for started app-ops. 8135 * An app-op may be long running and it has a clear start delimiter. 8136 * If an op start is attempted by any package, you will get a callback. 8137 * To change the watched ops for a registered callback you need to unregister and register it 8138 * again. 8139 * 8140 * <p> If you don't hold the {@code android.Manifest.permission#WATCH_APPOPS} permission 8141 * you can watch changes only for your UID. 8142 * 8143 * @param ops The operations to watch. 8144 * @param callback Where to report changes. 8145 * 8146 * @see #stopWatchingStarted(OnOpStartedListener) 8147 * @see #startWatchingActive(int[], OnOpActiveChangedListener) 8148 * @see #startWatchingNoted(int[], OnOpNotedListener) 8149 * @see #startOp(int, int, String, boolean, String, String) 8150 * @see #finishOp(int, int, String, String) 8151 * 8152 * @hide 8153 */ 8154 @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true) startWatchingStarted(@onNull int[] ops, @NonNull OnOpStartedListener callback)8155 public void startWatchingStarted(@NonNull int[] ops, @NonNull OnOpStartedListener callback) { 8156 IAppOpsStartedCallback cb; 8157 synchronized (mStartedWatchers) { 8158 if (mStartedWatchers.containsKey(callback)) { 8159 return; 8160 } 8161 cb = new IAppOpsStartedCallback.Stub() { 8162 @Override 8163 public void opStarted(int op, int uid, String packageName, String attributionTag, 8164 int flags, int mode, int startType, int attributionFlags, 8165 int attributionChainId) { 8166 callback.onOpStarted(op, uid, packageName, attributionTag, flags, mode, 8167 startType, attributionFlags, attributionChainId); 8168 } 8169 }; 8170 mStartedWatchers.put(callback, cb); 8171 } 8172 try { 8173 mService.startWatchingStarted(ops, cb); 8174 } catch (RemoteException e) { 8175 throw e.rethrowFromSystemServer(); 8176 } 8177 } 8178 8179 /** 8180 * Stop watching for started app-ops. 8181 * An app-op may be long running and it has a clear start delimiter. 8182 * Henceforth, if an op start is attempted by any package, you will not get a callback. 8183 * Unregistering a non-registered callback has no effect. 8184 * 8185 * @see #startWatchingStarted(int[], OnOpStartedListener) 8186 * @see #startOp(int, int, String, boolean, String, String) 8187 * 8188 * @hide 8189 */ stopWatchingStarted(@onNull OnOpStartedListener callback)8190 public void stopWatchingStarted(@NonNull OnOpStartedListener callback) { 8191 synchronized (mStartedWatchers) { 8192 final IAppOpsStartedCallback cb = mStartedWatchers.remove(callback); 8193 if (cb != null) { 8194 try { 8195 mService.stopWatchingStarted(cb); 8196 } catch (RemoteException e) { 8197 throw e.rethrowFromSystemServer(); 8198 } 8199 } 8200 } 8201 } 8202 8203 /** 8204 * Start watching for noted app ops. An app op may be immediate or long running. 8205 * Immediate ops are noted while long running ones are started and stopped. This 8206 * method allows registering a listener to be notified when an app op is noted. If 8207 * an op is being noted by any package you will get a callback. To change the 8208 * watched ops for a registered callback you need to unregister and register it again. 8209 * 8210 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission 8211 * you can watch changes only for your UID. 8212 * 8213 * @param ops The ops to watch. 8214 * @param callback Where to report changes. 8215 * 8216 * @see #startWatchingActive(int[], OnOpActiveChangedListener) 8217 * @see #startWatchingStarted(int[], OnOpStartedListener) 8218 * @see #stopWatchingNoted(OnOpNotedListener) 8219 * @see #noteOp(String, int, String, String, String) 8220 * 8221 * @hide 8222 */ 8223 @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true) startWatchingNoted(@onNull int[] ops, @NonNull OnOpNotedListener callback)8224 public void startWatchingNoted(@NonNull int[] ops, @NonNull OnOpNotedListener callback) { 8225 IAppOpsNotedCallback cb; 8226 synchronized (mNotedWatchers) { 8227 cb = mNotedWatchers.get(callback); 8228 if (cb != null) { 8229 return; 8230 } 8231 cb = new IAppOpsNotedCallback.Stub() { 8232 @Override 8233 public void opNoted(int op, int uid, String packageName, String attributionTag, 8234 int flags, int mode) { 8235 callback.onOpNoted(op, uid, packageName, attributionTag, flags, mode); 8236 } 8237 }; 8238 mNotedWatchers.put(callback, cb); 8239 } 8240 try { 8241 mService.startWatchingNoted(ops, cb); 8242 } catch (RemoteException e) { 8243 throw e.rethrowFromSystemServer(); 8244 } 8245 } 8246 8247 /** 8248 * Stop watching for noted app ops. An app op may be immediate or long running. 8249 * Unregistering a non-registered callback has no effect. 8250 * 8251 * @see #startWatchingNoted(int[], OnOpNotedListener) 8252 * @see #noteOp(String, int, String, String, String) 8253 * 8254 * @hide 8255 */ stopWatchingNoted(@onNull OnOpNotedListener callback)8256 public void stopWatchingNoted(@NonNull OnOpNotedListener callback) { 8257 synchronized (mNotedWatchers) { 8258 final IAppOpsNotedCallback cb = mNotedWatchers.remove(callback); 8259 if (cb != null) { 8260 try { 8261 mService.stopWatchingNoted(cb); 8262 } catch (RemoteException e) { 8263 throw e.rethrowFromSystemServer(); 8264 } 8265 } 8266 } 8267 } 8268 buildSecurityExceptionMsg(int op, int uid, String packageName)8269 private String buildSecurityExceptionMsg(int op, int uid, String packageName) { 8270 return packageName + " from uid " + uid + " not allowed to perform " + sOpNames[op]; 8271 } 8272 8273 /** 8274 * {@hide} 8275 */ 8276 @UnsupportedAppUsage 8277 @TestApi strOpToOp(@onNull String op)8278 public static int strOpToOp(@NonNull String op) { 8279 Integer val = sOpStrToOp.get(op); 8280 if (val == null) { 8281 throw new IllegalArgumentException("Unknown operation string: " + op); 8282 } 8283 return val; 8284 } 8285 8286 /** 8287 * Do a quick check for whether an application might be able to perform an operation. 8288 * This is <em>not</em> a security check; you must use {@link #noteOp(String, int, String, 8289 * String, String)} or {@link #startOp(String, int, String, String, String)} for your actual 8290 * security checks, which also ensure that the given uid and package name are consistent. This 8291 * function can just be used for a quick check to see if an operation has been disabled for the 8292 * application, as an early reject of some work. This does not modify the time stamp or other 8293 * data about the operation. 8294 * 8295 * <p>Important things this will not do (which you need to ultimate use 8296 * {@link #noteOp(String, int, String, String, String)} or 8297 * {@link #startOp(String, int, String, String, String)} to cover):</p> 8298 * <ul> 8299 * <li>Verifying the uid and package are consistent, so callers can't spoof 8300 * their identity.</li> 8301 * <li>Taking into account the current foreground/background state of the 8302 * app; apps whose mode varies by this state will always be reported 8303 * as {@link #MODE_ALLOWED}.</li> 8304 * </ul> 8305 * 8306 * @param op The operation to check. One of the OPSTR_* constants. 8307 * @param uid The user id of the application attempting to perform the operation. 8308 * @param packageName The name of the application attempting to perform the operation. 8309 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or 8310 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without 8311 * causing the app to crash). 8312 * @throws SecurityException If the app has been configured to crash on this op. 8313 */ unsafeCheckOp(@onNull String op, int uid, @NonNull String packageName)8314 public int unsafeCheckOp(@NonNull String op, int uid, @NonNull String packageName) { 8315 return checkOp(strOpToOp(op), uid, packageName); 8316 } 8317 8318 /** 8319 * @deprecated Renamed to {@link #unsafeCheckOp(String, int, String)}. 8320 */ 8321 @Deprecated checkOp(@onNull String op, int uid, @NonNull String packageName)8322 public int checkOp(@NonNull String op, int uid, @NonNull String packageName) { 8323 return checkOp(strOpToOp(op), uid, packageName); 8324 } 8325 8326 /** 8327 * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it 8328 * returns {@link #MODE_ERRORED}. 8329 */ unsafeCheckOpNoThrow(@onNull String op, int uid, @NonNull String packageName)8330 public int unsafeCheckOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) { 8331 return checkOpNoThrow(strOpToOp(op), uid, packageName); 8332 } 8333 8334 /** 8335 * @deprecated Renamed to {@link #unsafeCheckOpNoThrow(String, int, String)}. 8336 */ 8337 @Deprecated checkOpNoThrow(@onNull String op, int uid, @NonNull String packageName)8338 public int checkOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) { 8339 return checkOpNoThrow(strOpToOp(op), uid, packageName); 8340 } 8341 8342 /** 8343 * Like {@link #checkOp} but returns the <em>raw</em> mode associated with the op. 8344 * Does not throw a security exception, does not translate {@link #MODE_FOREGROUND}. 8345 */ unsafeCheckOpRaw(@onNull String op, int uid, @NonNull String packageName)8346 public int unsafeCheckOpRaw(@NonNull String op, int uid, @NonNull String packageName) { 8347 return unsafeCheckOpRawNoThrow(op, uid, packageName); 8348 } 8349 8350 /** 8351 * Like {@link #unsafeCheckOpNoThrow(String, int, String)} but returns the <em>raw</em> 8352 * mode associated with the op. Does not throw a security exception, does not translate 8353 * {@link #MODE_FOREGROUND}. 8354 */ unsafeCheckOpRawNoThrow(@onNull String op, int uid, @NonNull String packageName)8355 public int unsafeCheckOpRawNoThrow(@NonNull String op, int uid, @NonNull String packageName) { 8356 return unsafeCheckOpRawNoThrow(strOpToOp(op), uid, packageName); 8357 } 8358 8359 /** 8360 * Returns the <em>raw</em> mode associated with the op. 8361 * Does not throw a security exception, does not translate {@link #MODE_FOREGROUND}. 8362 * @hide 8363 */ unsafeCheckOpRawNoThrow(int op, int uid, @NonNull String packageName)8364 public int unsafeCheckOpRawNoThrow(int op, int uid, @NonNull String packageName) { 8365 try { 8366 return mService.checkOperationRaw(op, uid, packageName, null); 8367 } catch (RemoteException e) { 8368 throw e.rethrowFromSystemServer(); 8369 } 8370 } 8371 8372 /** 8373 * @deprecated Use {@link #noteOp(String, int, String, String, String)} instead 8374 */ 8375 @Deprecated noteOp(@onNull String op, int uid, @NonNull String packageName)8376 public int noteOp(@NonNull String op, int uid, @NonNull String packageName) { 8377 return noteOp(op, uid, packageName, null, null); 8378 } 8379 8380 /** 8381 * @deprecated Use {@link #noteOp(String, int, String, String, String)} instead 8382 * 8383 * @hide 8384 */ 8385 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link " 8386 + "#noteOp(java.lang.String, int, java.lang.String, java.lang.String, " 8387 + "java.lang.String)} instead") 8388 @Deprecated noteOp(int op)8389 public int noteOp(int op) { 8390 return noteOp(op, Process.myUid(), mContext.getOpPackageName(), null, null); 8391 } 8392 8393 /** 8394 * @deprecated Use {@link #noteOp(String, int, String, String, String)} instead 8395 * 8396 * @hide 8397 */ 8398 @Deprecated 8399 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link " 8400 + "#noteOp(java.lang.String, int, java.lang.String, java.lang.String, " 8401 + "java.lang.String)} instead") noteOp(int op, int uid, @Nullable String packageName)8402 public int noteOp(int op, int uid, @Nullable String packageName) { 8403 return noteOp(op, uid, packageName, null, null); 8404 } 8405 8406 /** 8407 * Make note of an application performing an operation and check if the application is allowed 8408 * to perform it. 8409 * 8410 * <p>If this is a check that is not preceding the protected operation, use 8411 * {@link #unsafeCheckOp} instead. 8412 * 8413 * <p>The identity of the package the app-op is noted for is specified by the 8414 * {@code uid} and {@code packageName} parameters. If this is noted for a regular app both 8415 * should be set and the package needs to be part of the uid. In the very rare case that an 8416 * app-op is noted for an entity that does not have a package name, the package can be 8417 * {@code null}. As it is possible that a single process contains more than one package the 8418 * {@code packageName} should be {@link Context#getPackageName() read} from the context of the 8419 * caller of the API (in the app process) that eventually triggers this check. If this op is 8420 * not noted for a running process the {@code packageName} cannot be read from the context, but 8421 * it should be clear which package the note is for. 8422 * 8423 * <p>If the {@code uid} and {@code packageName} do not match this return 8424 * {@link #MODE_IGNORED}. 8425 * 8426 * <p>Beside the access check this method also records the access. While the access check is 8427 * based on {@code uid} and/or {@code packageName} the access recording is done based on the 8428 * {@code packageName} and {@code attributionTag}. The {@code attributionTag} should be 8429 * {@link Context#getAttributionTag() read} from the same context the package name is read from. 8430 * In the case the check is not related to an API call, the {@code attributionTag} should be 8431 * {@code null}. Please note that e.g. registering a callback for later is still an API call and 8432 * the code should store the attribution tag along the package name for being used in this 8433 * method later. 8434 * 8435 * <p>The {@code message} parameter only needs to be set when this method is <ul>not</ul> 8436 * called in a two-way binder call from the client. In this case the message is a free form text 8437 * that is meant help the app developer determine what part of the app's code triggered the 8438 * note. This message is passed back to the app in the 8439 * {@link OnOpNotedCallback#onAsyncNoted(AsyncNotedAppOp)} callback. A good example of a useful 8440 * message is including the {@link System#identityHashCode(Object)} of the listener that will 8441 * receive data or the name of the manifest-receiver. 8442 * 8443 * @param op The operation to note. One of the OPSTR_* constants. 8444 * @param uid The uid of the application attempting to perform the operation. 8445 * @param packageName The name of the application attempting to perform the operation. 8446 * @param attributionTag The {@link Context#createAttributionContext attribution tag} of the 8447 * calling context or {@code null} for default attribution 8448 * @param message A message describing why the op was noted 8449 * 8450 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or 8451 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without 8452 * causing the app to crash). 8453 * 8454 * @throws SecurityException If the app has been configured to crash on this op. 8455 */ 8456 // For platform callers of this method, please read the package name parameter from 8457 // Context#getOpPackageName. 8458 // When noting a callback, the message can be computed using the #toReceiverId method. noteOp(@onNull String op, int uid, @Nullable String packageName, @Nullable String attributionTag, @Nullable String message)8459 public int noteOp(@NonNull String op, int uid, @Nullable String packageName, 8460 @Nullable String attributionTag, @Nullable String message) { 8461 return noteOp(strOpToOp(op), uid, packageName, attributionTag, message); 8462 } 8463 8464 /** 8465 * @see #noteOp(String, int, String, String, String 8466 * 8467 * @hide 8468 */ noteOp(int op, int uid, @Nullable String packageName, @Nullable String attributionTag, @Nullable String message)8469 public int noteOp(int op, int uid, @Nullable String packageName, 8470 @Nullable String attributionTag, @Nullable String message) { 8471 final int mode = noteOpNoThrow(op, uid, packageName, attributionTag, message); 8472 if (mode == MODE_ERRORED) { 8473 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName)); 8474 } 8475 return mode; 8476 } 8477 8478 /** 8479 * @deprecated Use {@link #noteOpNoThrow(String, int, String, String, String)} instead 8480 */ 8481 @Deprecated noteOpNoThrow(@onNull String op, int uid, @NonNull String packageName)8482 public int noteOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) { 8483 return noteOpNoThrow(op, uid, packageName, null, null); 8484 } 8485 8486 /** 8487 * @deprecated Use {@link #noteOpNoThrow(int, int, String, String, String)} instead 8488 * 8489 * @hide 8490 */ 8491 @Deprecated 8492 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link " 8493 + "#noteOpNoThrow(java.lang.String, int, java.lang.String, java.lang.String, " 8494 + "java.lang.String)} instead") noteOpNoThrow(int op, int uid, String packageName)8495 public int noteOpNoThrow(int op, int uid, String packageName) { 8496 return noteOpNoThrow(op, uid, packageName, null, null); 8497 } 8498 8499 /** 8500 * Like {@link #noteOp(String, int, String, String, String)} but instead of throwing a 8501 * {@link SecurityException} it returns {@link #MODE_ERRORED}. 8502 * 8503 * @see #noteOp(String, int, String, String, String) 8504 */ noteOpNoThrow(@onNull String op, int uid, @NonNull String packageName, @Nullable String attributionTag, @Nullable String message)8505 public int noteOpNoThrow(@NonNull String op, int uid, @NonNull String packageName, 8506 @Nullable String attributionTag, @Nullable String message) { 8507 return noteOpNoThrow(strOpToOp(op), uid, packageName, attributionTag, message); 8508 } 8509 8510 /** 8511 * @see #noteOpNoThrow(String, int, String, String, String) 8512 * 8513 * @hide 8514 */ noteOpNoThrow(int op, int uid, @Nullable String packageName, @Nullable String attributionTag, @Nullable String message)8515 public int noteOpNoThrow(int op, int uid, @Nullable String packageName, 8516 @Nullable String attributionTag, @Nullable String message) { 8517 try { 8518 collectNoteOpCallsForValidation(op); 8519 int collectionMode = getNotedOpCollectionMode(uid, packageName, op); 8520 boolean shouldCollectMessage = Process.myUid() == Process.SYSTEM_UID; 8521 if (collectionMode == COLLECT_ASYNC) { 8522 if (message == null) { 8523 // Set stack trace as default message 8524 message = getFormattedStackTrace(); 8525 shouldCollectMessage = true; 8526 } 8527 } 8528 8529 SyncNotedAppOp syncOp = mService.noteOperation(op, uid, packageName, attributionTag, 8530 collectionMode == COLLECT_ASYNC, message, shouldCollectMessage); 8531 8532 if (syncOp.getOpMode() == MODE_ALLOWED) { 8533 if (collectionMode == COLLECT_SELF) { 8534 collectNotedOpForSelf(syncOp); 8535 } else if (collectionMode == COLLECT_SYNC) { 8536 collectNotedOpSync(syncOp); 8537 } 8538 } 8539 8540 return syncOp.getOpMode(); 8541 } catch (RemoteException e) { 8542 throw e.rethrowFromSystemServer(); 8543 } 8544 } 8545 8546 /** 8547 * @deprecated Use {@link #noteProxyOp(String, String, int, String, String)} instead 8548 */ 8549 @Deprecated noteProxyOp(@onNull String op, @NonNull String proxiedPackageName)8550 public int noteProxyOp(@NonNull String op, @NonNull String proxiedPackageName) { 8551 return noteProxyOp(op, proxiedPackageName, Binder.getCallingUid(), null, null); 8552 } 8553 8554 /** 8555 * @deprecated Use {@link #noteProxyOp(String, String, int, String, String)} instead 8556 * 8557 * @hide 8558 */ 8559 @Deprecated 8560 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link " 8561 + "#noteProxyOp(java.lang.String, java.lang.String, int, java.lang.String, " 8562 + "java.lang.String)} instead") noteProxyOp(int op, @Nullable String proxiedPackageName)8563 public int noteProxyOp(int op, @Nullable String proxiedPackageName) { 8564 return noteProxyOp(op, proxiedPackageName, Binder.getCallingUid(), null, null); 8565 } 8566 8567 /** 8568 * @see #noteProxyOp(String, String, int, String, String) 8569 * 8570 * @hide 8571 */ noteProxyOp(int op, @Nullable String proxiedPackageName, int proxiedUid, @Nullable String proxiedAttributionTag, @Nullable String message)8572 public int noteProxyOp(int op, @Nullable String proxiedPackageName, int proxiedUid, 8573 @Nullable String proxiedAttributionTag, @Nullable String message) { 8574 return noteProxyOp(op, new AttributionSource(mContext.getAttributionSource(), 8575 new AttributionSource(proxiedUid, proxiedPackageName, proxiedAttributionTag, 8576 mContext.getAttributionSource().getToken())), message, 8577 /*skipProxyOperation*/ false); 8578 } 8579 8580 /** 8581 * Make note of an application performing an operation on behalf of another application when 8582 * handling an IPC. This function will verify that the calling uid and proxied package name 8583 * match, and if not, return {@link #MODE_IGNORED}. If this call succeeds, the last execution 8584 * time of the operation for the proxied app and your app will be updated to the current time. 8585 * 8586 * @param op The operation to note. One of the OPSTR_* constants. 8587 * @param proxiedPackageName The name of the application calling into the proxy application. 8588 * @param proxiedUid The uid of the proxied application 8589 * @param proxiedAttributionTag The proxied {@link Context#createAttributionContext 8590 * attribution tag} or {@code null} for default attribution 8591 * @param message A message describing the reason the op was noted 8592 * 8593 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or {@link #MODE_IGNORED} 8594 * if it is not allowed and should be silently ignored (without causing the app to crash). 8595 * 8596 * @throws SecurityException If the proxy or proxied app has been configured to crash on this 8597 * op. 8598 */ noteProxyOp(@onNull String op, @Nullable String proxiedPackageName, int proxiedUid, @Nullable String proxiedAttributionTag, @Nullable String message)8599 public int noteProxyOp(@NonNull String op, @Nullable String proxiedPackageName, int proxiedUid, 8600 @Nullable String proxiedAttributionTag, @Nullable String message) { 8601 return noteProxyOp(strOpToOp(op), proxiedPackageName, proxiedUid, proxiedAttributionTag, 8602 message); 8603 } 8604 8605 /** 8606 * Make note of an application performing an operation on behalf of another application(s). 8607 * 8608 * @param op The operation to note. One of the OPSTR_* constants. 8609 * @param attributionSource The permission identity for which to note. 8610 * @param message A message describing the reason the op was noted 8611 * @param skipProxyOperation Whether to skip the proxy note. 8612 * 8613 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or {@link #MODE_IGNORED} 8614 * if it is not allowed and should be silently ignored (without causing the app to crash). 8615 * 8616 * @throws SecurityException If the any proxying operations in the permission identityf 8617 * chain fails. 8618 * 8619 * @hide 8620 */ noteProxyOp(@onNull int op, @NonNull AttributionSource attributionSource, @Nullable String message, boolean skipProxyOperation)8621 public int noteProxyOp(@NonNull int op, @NonNull AttributionSource attributionSource, 8622 @Nullable String message, boolean skipProxyOperation) { 8623 final int mode = noteProxyOpNoThrow(op, attributionSource, message, skipProxyOperation); 8624 if (mode == MODE_ERRORED) { 8625 throw new SecurityException("Proxy package " 8626 + attributionSource.getPackageName() + " from uid " 8627 + attributionSource.getUid() + " or calling package " 8628 + attributionSource.getNextPackageName() + " from uid " 8629 + attributionSource.getNextUid() + " not allowed to perform " 8630 + sOpNames[op]); 8631 } 8632 return mode; 8633 } 8634 8635 /** 8636 * @deprecated Use {@link #noteProxyOpNoThrow(String, String, int, String, String)} instead 8637 */ 8638 @Deprecated noteProxyOpNoThrow(@onNull String op, @NonNull String proxiedPackageName)8639 public int noteProxyOpNoThrow(@NonNull String op, @NonNull String proxiedPackageName) { 8640 return noteProxyOpNoThrow(op, proxiedPackageName, Binder.getCallingUid(), null, null); 8641 } 8642 8643 /** 8644 * @deprecated Use {@link #noteProxyOpNoThrow(String, String, int, String, String)} instead 8645 */ 8646 @Deprecated noteProxyOpNoThrow(@onNull String op, @Nullable String proxiedPackageName, int proxiedUid)8647 public int noteProxyOpNoThrow(@NonNull String op, @Nullable String proxiedPackageName, 8648 int proxiedUid) { 8649 return noteProxyOpNoThrow(op, proxiedPackageName, proxiedUid, null, null); 8650 } 8651 8652 /** 8653 * Like {@link #noteProxyOp(String, String, int, String, String)} but instead 8654 * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}. 8655 * 8656 * @see #noteOpNoThrow(String, int, String, String, String) 8657 */ noteProxyOpNoThrow(@onNull String op, @Nullable String proxiedPackageName, int proxiedUid, @Nullable String proxiedAttributionTag, @Nullable String message)8658 public int noteProxyOpNoThrow(@NonNull String op, @Nullable String proxiedPackageName, 8659 int proxiedUid, @Nullable String proxiedAttributionTag, @Nullable String message) { 8660 return noteProxyOpNoThrow(strOpToOp(op), new AttributionSource( 8661 mContext.getAttributionSource(), new AttributionSource(proxiedUid, 8662 proxiedPackageName, proxiedAttributionTag, mContext.getAttributionSource() 8663 .getToken())), message,/*skipProxyOperation*/ false); 8664 } 8665 8666 /** 8667 * Make note of an application performing an operation on behalf of another application(s). 8668 * 8669 * @param op The operation to note. One of the OPSTR_* constants. 8670 * @param attributionSource The permission identity for which to note. 8671 * @param message A message describing the reason the op was noted 8672 * @param skipProxyOperation Whether to note op for the proxy 8673 * 8674 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or {@link #MODE_IGNORED} 8675 * if it is not allowed and should be silently ignored (without causing the app to crash). 8676 * 8677 * @hide 8678 */ 8679 @SuppressWarnings("AndroidFrameworkClientSidePermissionCheck") noteProxyOpNoThrow(int op, @NonNull AttributionSource attributionSource, @Nullable String message, boolean skipProxyOperation)8680 public int noteProxyOpNoThrow(int op, @NonNull AttributionSource attributionSource, 8681 @Nullable String message, boolean skipProxyOperation) { 8682 int myUid = Process.myUid(); 8683 8684 try { 8685 collectNoteOpCallsForValidation(op); 8686 int collectionMode = getNotedOpCollectionMode( 8687 attributionSource.getNextUid(), 8688 attributionSource.getNextAttributionTag(), op); 8689 boolean shouldCollectMessage = (myUid == Process.SYSTEM_UID); 8690 if (collectionMode == COLLECT_ASYNC) { 8691 if (message == null) { 8692 // Set stack trace as default message 8693 message = getFormattedStackTrace(); 8694 shouldCollectMessage = true; 8695 } 8696 } 8697 8698 SyncNotedAppOp syncOp = mService.noteProxyOperation(op, attributionSource, 8699 collectionMode == COLLECT_ASYNC, message, 8700 shouldCollectMessage, skipProxyOperation); 8701 8702 if (syncOp.getOpMode() == MODE_ALLOWED) { 8703 if (collectionMode == COLLECT_SELF) { 8704 collectNotedOpForSelf(syncOp); 8705 } else if (collectionMode == COLLECT_SYNC 8706 // Only collect app-ops when the proxy is trusted 8707 && (mContext.checkPermission(Manifest.permission.UPDATE_APP_OPS_STATS, -1, 8708 myUid) == PackageManager.PERMISSION_GRANTED || 8709 Binder.getCallingUid() == attributionSource.getNextUid())) { 8710 collectNotedOpSync(syncOp); 8711 } 8712 } 8713 8714 return syncOp.getOpMode(); 8715 } catch (RemoteException e) { 8716 throw e.rethrowFromSystemServer(); 8717 } 8718 } 8719 getComponentPackageNameFromString(String from)8720 private static String getComponentPackageNameFromString(String from) { 8721 ComponentName componentName = from != null ? ComponentName.unflattenFromString(from) : null; 8722 return componentName != null ? componentName.getPackageName() : ""; 8723 } 8724 isPackagePreInstalled(Context context, String packageName, int userId)8725 private static boolean isPackagePreInstalled(Context context, String packageName, int userId) { 8726 try { 8727 final PackageManager pm = context.getPackageManager(); 8728 final ApplicationInfo info = 8729 pm.getApplicationInfoAsUser(packageName, 0, userId); 8730 return ((info.flags & ApplicationInfo.FLAG_SYSTEM) != 0); 8731 } catch (PackageManager.NameNotFoundException e) { 8732 return false; 8733 } 8734 } 8735 8736 /** 8737 * Do a quick check for whether an application might be able to perform an operation. 8738 * This is <em>not</em> a security check; you must use {@link #noteOp(String, int, String, 8739 * String, String)} or {@link #startOp(int, int, String, boolean, String, String)} for your 8740 * actual security checks, which also ensure that the given uid and package name are consistent. 8741 * This function can just be used for a quick check to see if an operation has been disabled for 8742 * the application, as an early reject of some work. This does not modify the time stamp or 8743 * other data about the operation. 8744 * 8745 * <p>Important things this will not do (which you need to ultimate use 8746 * {@link #noteOp(String, int, String, String, String)} or 8747 * {@link #startOp(int, int, String, boolean, String, String)} to cover):</p> 8748 * <ul> 8749 * <li>Verifying the uid and package are consistent, so callers can't spoof 8750 * their identity.</li> 8751 * <li>Taking into account the current foreground/background state of the 8752 * app; apps whose mode varies by this state will always be reported 8753 * as {@link #MODE_ALLOWED}.</li> 8754 * </ul> 8755 * 8756 * @param op The operation to check. One of the OP_* constants. 8757 * @param uid The user id of the application attempting to perform the operation. 8758 * @param packageName The name of the application attempting to perform the operation. 8759 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or 8760 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without 8761 * causing the app to crash). 8762 * @throws SecurityException If the app has been configured to crash on this op. 8763 * @hide 8764 */ 8765 @UnsupportedAppUsage checkOp(int op, int uid, String packageName)8766 public int checkOp(int op, int uid, String packageName) { 8767 try { 8768 int mode = mService.checkOperation(op, uid, packageName); 8769 if (mode == MODE_ERRORED) { 8770 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName)); 8771 } 8772 return mode; 8773 } catch (RemoteException e) { 8774 throw e.rethrowFromSystemServer(); 8775 } 8776 } 8777 8778 /** 8779 * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it 8780 * returns {@link #MODE_ERRORED}. 8781 * 8782 * @see #checkOp(int, int, String) 8783 * 8784 * @hide 8785 */ 8786 @UnsupportedAppUsage checkOpNoThrow(int op, int uid, String packageName)8787 public int checkOpNoThrow(int op, int uid, String packageName) { 8788 try { 8789 int mode = mService.checkOperation(op, uid, packageName); 8790 return mode == AppOpsManager.MODE_FOREGROUND ? AppOpsManager.MODE_ALLOWED : mode; 8791 } catch (RemoteException e) { 8792 throw e.rethrowFromSystemServer(); 8793 } 8794 } 8795 8796 /** 8797 * @deprecated Use {@link PackageManager#getPackageUid} instead 8798 */ 8799 @Deprecated checkPackage(int uid, @NonNull String packageName)8800 public void checkPackage(int uid, @NonNull String packageName) { 8801 try { 8802 if (mService.checkPackage(uid, packageName) != MODE_ALLOWED) { 8803 throw new SecurityException( 8804 "Package " + packageName + " does not belong to " + uid); 8805 } 8806 } catch (RemoteException e) { 8807 throw e.rethrowFromSystemServer(); 8808 } 8809 } 8810 8811 /** 8812 * Like {@link #checkOp} but at a stream-level for audio operations. 8813 * @hide 8814 */ checkAudioOp(int op, int stream, int uid, String packageName)8815 public int checkAudioOp(int op, int stream, int uid, String packageName) { 8816 try { 8817 final int mode = mService.checkAudioOperation(op, stream, uid, packageName); 8818 if (mode == MODE_ERRORED) { 8819 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName)); 8820 } 8821 return mode; 8822 } catch (RemoteException e) { 8823 throw e.rethrowFromSystemServer(); 8824 } 8825 } 8826 8827 /** 8828 * Like {@link #checkAudioOp} but instead of throwing a {@link SecurityException} it 8829 * returns {@link #MODE_ERRORED}. 8830 * @hide 8831 */ checkAudioOpNoThrow(int op, int stream, int uid, String packageName)8832 public int checkAudioOpNoThrow(int op, int stream, int uid, String packageName) { 8833 try { 8834 return mService.checkAudioOperation(op, stream, uid, packageName); 8835 } catch (RemoteException e) { 8836 throw e.rethrowFromSystemServer(); 8837 } 8838 } 8839 8840 /** 8841 * @deprecated Use own local {@link android.os.Binder#Binder()} 8842 * 8843 * @hide 8844 */ 8845 @Deprecated 8846 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Create own " 8847 + "local {@link android.os.Binder}") getToken(IAppOpsService service)8848 public static IBinder getToken(IAppOpsService service) { 8849 return getClientId(); 8850 } 8851 8852 /** @hide */ getClientId()8853 public static IBinder getClientId() { 8854 synchronized (AppOpsManager.class) { 8855 if (sClientId == null) { 8856 sClientId = new Binder(); 8857 } 8858 8859 return sClientId; 8860 } 8861 } 8862 8863 /** @hide */ getService()8864 private static IAppOpsService getService() { 8865 synchronized (sLock) { 8866 if (sService == null) { 8867 sService = IAppOpsService.Stub.asInterface( 8868 ServiceManager.getService(Context.APP_OPS_SERVICE)); 8869 } 8870 return sService; 8871 } 8872 } 8873 8874 /** 8875 * @deprecated use {@link #startOp(String, int, String, String, String)} instead 8876 */ 8877 @Deprecated startOp(@onNull String op, int uid, @NonNull String packageName)8878 public int startOp(@NonNull String op, int uid, @NonNull String packageName) { 8879 return startOp(op, uid, packageName, null, null); 8880 } 8881 8882 /** 8883 * @deprecated Use {@link #startOp(int, int, String, boolean, String, String)} instead 8884 * 8885 * @hide 8886 */ 8887 @Deprecated startOp(int op)8888 public int startOp(int op) { 8889 return startOp(op, Process.myUid(), mContext.getOpPackageName(), false, null, null); 8890 } 8891 8892 /** 8893 * @deprecated Use {@link #startOp(int, int, String, boolean, String, String)} instead 8894 * 8895 * @hide 8896 */ 8897 @Deprecated startOp(int op, int uid, String packageName)8898 public int startOp(int op, int uid, String packageName) { 8899 return startOp(op, uid, packageName, false, null, null); 8900 } 8901 8902 /** 8903 * @deprecated Use {@link #startOp(int, int, String, boolean, String, String)} instead 8904 * 8905 * @hide 8906 */ 8907 @Deprecated startOp(int op, int uid, String packageName, boolean startIfModeDefault)8908 public int startOp(int op, int uid, String packageName, boolean startIfModeDefault) { 8909 return startOp(op, uid, packageName, startIfModeDefault, null, null); 8910 } 8911 8912 /** 8913 * Report that an application has started executing a long-running operation. 8914 * 8915 * <p>For more details how to determine the {@code callingPackageName}, 8916 * {@code callingAttributionTag}, and {@code message}, please check the description in 8917 * {@link #noteOp(String, int, String, String, String)} 8918 * 8919 * @param op The operation to start. One of the OPSTR_* constants. 8920 * @param uid The user id of the application attempting to perform the operation. 8921 * @param packageName The name of the application attempting to perform the operation. 8922 * @param attributionTag The {@link Context#createAttributionContext attribution tag} or 8923 * {@code null} for default attribution 8924 * @param message Description why op was started 8925 * 8926 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or 8927 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without 8928 * causing the app to crash). 8929 * 8930 * @throws SecurityException If the app has been configured to crash on this op or 8931 * the package is not in the passed in UID. 8932 */ startOp(@onNull String op, int uid, @Nullable String packageName, @Nullable String attributionTag, @Nullable String message)8933 public int startOp(@NonNull String op, int uid, @Nullable String packageName, 8934 @Nullable String attributionTag, @Nullable String message) { 8935 return startOp(strOpToOp(op), uid, packageName, false, attributionTag, message); 8936 } 8937 8938 /** 8939 * @see #startOp(String, int, String, String, String) 8940 * 8941 * @hide 8942 */ startOp(int op, int uid, @Nullable String packageName, boolean startIfModeDefault, @Nullable String attributionTag, @Nullable String message)8943 public int startOp(int op, int uid, @Nullable String packageName, boolean startIfModeDefault, 8944 @Nullable String attributionTag, @Nullable String message) { 8945 final int mode = startOpNoThrow(op, uid, packageName, startIfModeDefault, attributionTag, 8946 message); 8947 if (mode == MODE_ERRORED) { 8948 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName)); 8949 } 8950 return mode; 8951 } 8952 8953 /** 8954 * @deprecated use {@link #startOpNoThrow(String, int, String, String, String)} instead 8955 */ 8956 @Deprecated startOpNoThrow(@onNull String op, int uid, @NonNull String packageName)8957 public int startOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) { 8958 return startOpNoThrow(op, uid, packageName, null, null); 8959 } 8960 8961 /** 8962 * @deprecated Use {@link #startOpNoThrow(int, int, String, boolean, String, String} instead 8963 * 8964 * @hide 8965 */ 8966 @Deprecated startOpNoThrow(int op, int uid, String packageName)8967 public int startOpNoThrow(int op, int uid, String packageName) { 8968 return startOpNoThrow(op, uid, packageName, false, null, null); 8969 } 8970 8971 /** 8972 * @deprecated Use {@link #startOpNoThrow(int, int, String, boolean, String, String} instead 8973 * 8974 * @hide 8975 */ 8976 @Deprecated startOpNoThrow(int op, int uid, String packageName, boolean startIfModeDefault)8977 public int startOpNoThrow(int op, int uid, String packageName, boolean startIfModeDefault) { 8978 return startOpNoThrow(op, uid, packageName, startIfModeDefault, null, null); 8979 } 8980 8981 /** 8982 * Like {@link #startOp(String, int, String, String, String)} but instead of throwing a 8983 * {@link SecurityException} it returns {@link #MODE_ERRORED}. 8984 * 8985 * @see #startOp(String, int, String, String, String) 8986 */ startOpNoThrow(@onNull String op, int uid, @NonNull String packageName, @NonNull String attributionTag, @Nullable String message)8987 public int startOpNoThrow(@NonNull String op, int uid, @NonNull String packageName, 8988 @NonNull String attributionTag, @Nullable String message) { 8989 return startOpNoThrow(strOpToOp(op), uid, packageName, false, attributionTag, message); 8990 } 8991 8992 /** 8993 * @see #startOpNoThrow(String, int, String, String, String) 8994 * 8995 * @hide 8996 */ startOpNoThrow(int op, int uid, @NonNull String packageName, boolean startIfModeDefault, @Nullable String attributionTag, @Nullable String message)8997 public int startOpNoThrow(int op, int uid, @NonNull String packageName, 8998 boolean startIfModeDefault, @Nullable String attributionTag, @Nullable String message) { 8999 return startOpNoThrow(mContext.getAttributionSource().getToken(), op, uid, packageName, 9000 startIfModeDefault, attributionTag, message); 9001 } 9002 9003 /** 9004 * @see #startOpNoThrow(String, int, String, String, String) 9005 * 9006 * @hide 9007 */ startOpNoThrow(@onNull IBinder token, int op, int uid, @NonNull String packageName, boolean startIfModeDefault, @Nullable String attributionTag, @Nullable String message)9008 public int startOpNoThrow(@NonNull IBinder token, int op, int uid, @NonNull String packageName, 9009 boolean startIfModeDefault, @Nullable String attributionTag, @Nullable String message) { 9010 return startOpNoThrow(token, op, uid, packageName, startIfModeDefault, attributionTag, 9011 message, ATTRIBUTION_FLAGS_NONE, ATTRIBUTION_CHAIN_ID_NONE); 9012 } 9013 9014 /** 9015 * @see #startOpNoThrow(String, int, String, String, String) 9016 * 9017 * @hide 9018 */ startOpNoThrow(@onNull IBinder token, int op, int uid, @NonNull String packageName, boolean startIfModeDefault, @Nullable String attributionTag, @Nullable String message, @AttributionFlags int attributionFlags, int attributionChainId)9019 public int startOpNoThrow(@NonNull IBinder token, int op, int uid, @NonNull String packageName, 9020 boolean startIfModeDefault, @Nullable String attributionTag, @Nullable String message, 9021 @AttributionFlags int attributionFlags, int attributionChainId) { 9022 try { 9023 collectNoteOpCallsForValidation(op); 9024 int collectionMode = getNotedOpCollectionMode(uid, packageName, op); 9025 boolean shouldCollectMessage = Process.myUid() == Process.SYSTEM_UID; 9026 if (collectionMode == COLLECT_ASYNC) { 9027 if (message == null) { 9028 // Set stack trace as default message 9029 message = getFormattedStackTrace(); 9030 shouldCollectMessage = true; 9031 } 9032 } 9033 9034 SyncNotedAppOp syncOp = mService.startOperation(token, op, uid, packageName, 9035 attributionTag, startIfModeDefault, collectionMode == COLLECT_ASYNC, message, 9036 shouldCollectMessage, attributionFlags, attributionChainId); 9037 9038 if (syncOp.getOpMode() == MODE_ALLOWED) { 9039 if (collectionMode == COLLECT_SELF) { 9040 collectNotedOpForSelf(syncOp); 9041 } else if (collectionMode == COLLECT_SYNC) { 9042 collectNotedOpSync(syncOp); 9043 } 9044 } 9045 9046 return syncOp.getOpMode(); 9047 } catch (RemoteException e) { 9048 throw e.rethrowFromSystemServer(); 9049 } 9050 } 9051 9052 /** 9053 * Report that an application has started executing a long-running operation on behalf of 9054 * another application when handling an IPC. This function will verify that the calling uid and 9055 * proxied package name match, and if not, return {@link #MODE_IGNORED}. 9056 * 9057 * @param op The op to note 9058 * @param proxiedUid The uid to note the op for {@code null} 9059 * @param proxiedPackageName The package name the uid belongs to 9060 * @param proxiedAttributionTag The proxied {@link Context#createAttributionContext 9061 * attribution tag} or {@code null} for default attribution 9062 * @param message A message describing the reason the op was noted 9063 * 9064 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or {@link #MODE_IGNORED} 9065 * if it is not allowed and should be silently ignored (without causing the app to crash). 9066 * 9067 * @throws SecurityException If the proxy or proxied app has been configured to crash on this 9068 * op. 9069 */ startProxyOp(@onNull String op, int proxiedUid, @NonNull String proxiedPackageName, @Nullable String proxiedAttributionTag, @Nullable String message)9070 public int startProxyOp(@NonNull String op, int proxiedUid, @NonNull String proxiedPackageName, 9071 @Nullable String proxiedAttributionTag, @Nullable String message) { 9072 return startProxyOp(op, new AttributionSource(mContext.getAttributionSource(), 9073 new AttributionSource(proxiedUid, proxiedPackageName, proxiedAttributionTag, 9074 mContext.getAttributionSource().getToken())), message, 9075 /*skipProxyOperation*/ false); 9076 } 9077 9078 /** 9079 * Report that an application has started executing a long-running operation on behalf of 9080 * another application for the attribution chain specified by the {@link AttributionSource}}. 9081 * 9082 * @param op The op to note 9083 * @param attributionSource The permission identity for which to check 9084 * @param message A message describing the reason the op was noted 9085 * @param skipProxyOperation Whether to skip the proxy start. 9086 * 9087 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or {@link #MODE_IGNORED} 9088 * if it is not allowed and should be silently ignored (without causing the app to crash). 9089 * 9090 * @throws SecurityException If the any proxying operations in the permission identity 9091 * chain fails. 9092 * 9093 * @hide 9094 */ startProxyOp(@onNull String op, @NonNull AttributionSource attributionSource, @Nullable String message, boolean skipProxyOperation)9095 public int startProxyOp(@NonNull String op, @NonNull AttributionSource attributionSource, 9096 @Nullable String message, boolean skipProxyOperation) { 9097 final int mode = startProxyOpNoThrow(AppOpsManager.strOpToOp(op), attributionSource, 9098 message, skipProxyOperation); 9099 if (mode == MODE_ERRORED) { 9100 throw new SecurityException("Proxy package " 9101 + attributionSource.getPackageName() + " from uid " 9102 + attributionSource.getUid() + " or calling package " 9103 + attributionSource.getNextPackageName() + " from uid " 9104 + attributionSource.getNextUid() + " not allowed to perform " 9105 + op); 9106 } 9107 return mode; 9108 } 9109 9110 /** 9111 * Like {@link #startProxyOp(String, int, String, String, String)} but instead 9112 * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}. 9113 * 9114 * @see #startProxyOp(String, int, String, String, String) 9115 */ startProxyOpNoThrow(@onNull String op, int proxiedUid, @NonNull String proxiedPackageName, @Nullable String proxiedAttributionTag, @Nullable String message)9116 public int startProxyOpNoThrow(@NonNull String op, int proxiedUid, 9117 @NonNull String proxiedPackageName, @Nullable String proxiedAttributionTag, 9118 @Nullable String message) { 9119 return startProxyOpNoThrow(AppOpsManager.strOpToOp(op), new AttributionSource( 9120 mContext.getAttributionSource(), new AttributionSource(proxiedUid, 9121 proxiedPackageName, proxiedAttributionTag, 9122 mContext.getAttributionSource().getToken())), message, 9123 /*skipProxyOperation*/ false); 9124 } 9125 9126 /** 9127 * Like {@link #startProxyOp(String, AttributionSource, String)} but instead 9128 * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED} and 9129 * the checks is for the attribution chain specified by the {@link AttributionSource}. 9130 * 9131 * @see #startProxyOp(String, AttributionSource, String) 9132 * 9133 * @hide 9134 */ startProxyOpNoThrow(int op, @NonNull AttributionSource attributionSource, @Nullable String message, boolean skipProxyOperation)9135 public int startProxyOpNoThrow(int op, @NonNull AttributionSource attributionSource, 9136 @Nullable String message, boolean skipProxyOperation) { 9137 return startProxyOpNoThrow(attributionSource.getToken(), op, attributionSource, message, 9138 skipProxyOperation, ATTRIBUTION_FLAGS_NONE, ATTRIBUTION_FLAGS_NONE, 9139 ATTRIBUTION_CHAIN_ID_NONE); 9140 } 9141 9142 /** 9143 * Like {@link #startProxyOp(String, AttributionSource, String)} but instead 9144 * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED} and 9145 * the checks is for the attribution chain specified by the {@link AttributionSource}. 9146 * 9147 * @see #startProxyOp(String, AttributionSource, String) 9148 * 9149 * @hide 9150 */ startProxyOpNoThrow(@onNull IBinder clientId, int op, @NonNull AttributionSource attributionSource, @Nullable String message, boolean skipProxyOperation, @AttributionFlags int proxyAttributionFlags, @AttributionFlags int proxiedAttributionFlags, int attributionChainId)9151 public int startProxyOpNoThrow(@NonNull IBinder clientId, int op, 9152 @NonNull AttributionSource attributionSource, 9153 @Nullable String message, boolean skipProxyOperation, @AttributionFlags 9154 int proxyAttributionFlags, @AttributionFlags int proxiedAttributionFlags, 9155 int attributionChainId) { 9156 try { 9157 collectNoteOpCallsForValidation(op); 9158 int collectionMode = getNotedOpCollectionMode( 9159 attributionSource.getNextUid(), 9160 attributionSource.getNextPackageName(), op); 9161 boolean shouldCollectMessage = Process.myUid() == Process.SYSTEM_UID; 9162 if (collectionMode == COLLECT_ASYNC) { 9163 if (message == null) { 9164 // Set stack trace as default message 9165 message = getFormattedStackTrace(); 9166 shouldCollectMessage = true; 9167 } 9168 } 9169 9170 SyncNotedAppOp syncOp = mService.startProxyOperation(clientId, op, 9171 attributionSource, false, collectionMode == COLLECT_ASYNC, message, 9172 shouldCollectMessage, skipProxyOperation, proxyAttributionFlags, 9173 proxiedAttributionFlags, attributionChainId); 9174 9175 if (syncOp.getOpMode() == MODE_ALLOWED) { 9176 if (collectionMode == COLLECT_SELF) { 9177 collectNotedOpForSelf(syncOp); 9178 } else if (collectionMode == COLLECT_SYNC 9179 // Only collect app-ops when the proxy is trusted 9180 && (mContext.checkPermission(Manifest.permission.UPDATE_APP_OPS_STATS, -1, 9181 Process.myUid()) == PackageManager.PERMISSION_GRANTED 9182 || Binder.getCallingUid() == attributionSource.getNextUid())) { 9183 collectNotedOpSync(syncOp); 9184 } 9185 } 9186 9187 return syncOp.getOpMode(); 9188 } catch (RemoteException e) { 9189 throw e.rethrowFromSystemServer(); 9190 } 9191 } 9192 9193 /** 9194 * @deprecated Use {@link #finishOp(String, int, String, String)} instead 9195 * 9196 * @hide 9197 */ 9198 @Deprecated finishOp(int op)9199 public void finishOp(int op) { 9200 finishOp(op, Process.myUid(), mContext.getOpPackageName(), null); 9201 } 9202 9203 /** 9204 * @deprecated Use {@link #finishOp(String, int, String, String)} instead 9205 */ finishOp(@onNull String op, int uid, @NonNull String packageName)9206 public void finishOp(@NonNull String op, int uid, @NonNull String packageName) { 9207 finishOp(strOpToOp(op), uid, packageName, null); 9208 } 9209 9210 /** 9211 * Report that an application is no longer performing an operation that had previously 9212 * been started with {@link #startOp(String, int, String, String, String)}. There is no 9213 * validation of input or result; the parameters supplied here must be the exact same ones 9214 * previously passed in when starting the operation. 9215 */ finishOp(@onNull String op, int uid, @NonNull String packageName, @Nullable String attributionTag)9216 public void finishOp(@NonNull String op, int uid, @NonNull String packageName, 9217 @Nullable String attributionTag) { 9218 finishOp(strOpToOp(op), uid, packageName, attributionTag); 9219 } 9220 9221 /** 9222 * @deprecated Use {@link #finishOp(int, int, String, String)} instead 9223 * 9224 * @hide 9225 */ finishOp(int op, int uid, @NonNull String packageName)9226 public void finishOp(int op, int uid, @NonNull String packageName) { 9227 finishOp(op, uid, packageName, null); 9228 } 9229 9230 /** 9231 * @see #finishOp(String, int, String, String) 9232 * 9233 * @hide 9234 */ finishOp(int op, int uid, @NonNull String packageName, @Nullable String attributionTag)9235 public void finishOp(int op, int uid, @NonNull String packageName, 9236 @Nullable String attributionTag) { 9237 finishOp(mContext.getAttributionSource().getToken(), op, uid, packageName, attributionTag); 9238 } 9239 9240 /** 9241 * @see #finishOp(String, int, String, String) 9242 * 9243 * @hide 9244 */ finishOp(IBinder token, int op, int uid, @NonNull String packageName, @Nullable String attributionTag)9245 public void finishOp(IBinder token, int op, int uid, @NonNull String packageName, 9246 @Nullable String attributionTag) { 9247 try { 9248 mService.finishOperation(token, op, uid, packageName, attributionTag); 9249 } catch (RemoteException e) { 9250 throw e.rethrowFromSystemServer(); 9251 } 9252 } 9253 9254 /** 9255 * Report that an application is no longer performing an operation that had previously 9256 * been started with {@link #startProxyOp(String, int, String, String, String)}. There is no 9257 * validation of input or result; the parameters supplied here must be the exact same ones 9258 * previously passed in when starting the operation. 9259 * 9260 * @param op The operation which was started 9261 * @param proxiedUid The proxied appp's UID 9262 * @param proxiedPackageName The proxied appp's package name 9263 * @param proxiedAttributionTag The proxied appp's attribution tag or 9264 * {@code null} for default attribution 9265 */ finishProxyOp(@onNull String op, int proxiedUid, @NonNull String proxiedPackageName, @Nullable String proxiedAttributionTag)9266 public void finishProxyOp(@NonNull String op, int proxiedUid, 9267 @NonNull String proxiedPackageName, @Nullable String proxiedAttributionTag) { 9268 IBinder token = mContext.getAttributionSource().getToken(); 9269 finishProxyOp(token, op, new AttributionSource(mContext.getAttributionSource(), 9270 new AttributionSource(proxiedUid, proxiedPackageName, proxiedAttributionTag, 9271 token)), /*skipProxyOperation*/ false); 9272 } 9273 9274 /** 9275 * Report that an application is no longer performing an operation that had previously 9276 * been started with {@link #startProxyOp(String, AttributionSource, String, boolean)}. There 9277 * is no validation of input or result; the parameters supplied here must be the exact same 9278 * ones previously passed in when starting the operation. 9279 * 9280 * @param op The operation which was started 9281 * @param attributionSource The permission identity for which to finish 9282 * @param skipProxyOperation Whether to skip the proxy finish. 9283 * 9284 * @hide 9285 */ finishProxyOp(@onNull IBinder clientId, @NonNull String op, @NonNull AttributionSource attributionSource, boolean skipProxyOperation)9286 public void finishProxyOp(@NonNull IBinder clientId, @NonNull String op, 9287 @NonNull AttributionSource attributionSource, boolean skipProxyOperation) { 9288 try { 9289 mService.finishProxyOperation(clientId, strOpToOp(op), attributionSource, 9290 skipProxyOperation); 9291 } catch (RemoteException e) { 9292 throw e.rethrowFromSystemServer(); 9293 } 9294 } 9295 9296 /** 9297 * Checks whether the given op for a package is active, i.e. did someone call {@link #startOp} 9298 * without {@link #finishOp} yet. 9299 * <p> 9300 * If you don't hold the {@code android.Manifest.permission#WATCH_APPOPS} 9301 * permission you can query only for your UID. 9302 * 9303 * @see #finishOp(String, int, String, String) 9304 * @see #startOp(String, int, String, String, String) 9305 */ isOpActive(@onNull String op, int uid, @NonNull String packageName)9306 public boolean isOpActive(@NonNull String op, int uid, @NonNull String packageName) { 9307 return isOperationActive(strOpToOp(op), uid, packageName); 9308 } 9309 9310 /** 9311 * Get whether you are currently proxying to another package. That applies only 9312 * for long running operations like {@link #OP_RECORD_AUDIO}. 9313 * 9314 * @param op The op. 9315 * @param proxyAttributionTag Your attribution tag to query for. 9316 * @param proxiedUid The proxied UID to query for. 9317 * @param proxiedPackageName The proxied package to query for. 9318 * @return Whether you are currently proxying to this target. 9319 * 9320 * @hide 9321 */ isProxying(int op, @NonNull String proxyAttributionTag, int proxiedUid, @NonNull String proxiedPackageName)9322 public boolean isProxying(int op, @NonNull String proxyAttributionTag, int proxiedUid, 9323 @NonNull String proxiedPackageName) { 9324 try { 9325 return mService.isProxying(op, mContext.getOpPackageName(), 9326 mContext.getAttributionTag(), proxiedUid, proxiedPackageName); 9327 } catch (RemoteException e) { 9328 throw e.rethrowFromSystemServer(); 9329 } 9330 } 9331 9332 /** 9333 * Clears the op state (last accesses + op modes) for a package but not 9334 * the historical state. 9335 * 9336 * @param packageName The package to reset. 9337 * 9338 * @hide 9339 */ 9340 @TestApi 9341 @RequiresPermission(Manifest.permission.MANAGE_APPOPS) resetPackageOpsNoHistory(@onNull String packageName)9342 public void resetPackageOpsNoHistory(@NonNull String packageName) { 9343 try { 9344 mService.resetPackageOpsNoHistory(packageName); 9345 } catch (RemoteException e) { 9346 throw e.rethrowFromSystemServer(); 9347 } 9348 } 9349 9350 /** 9351 * Start collection of noted appops on this thread. 9352 * 9353 * <p>Called at the beginning of a two way binder transaction. 9354 * 9355 * @see #finishNotedAppOpsCollection() 9356 * 9357 * @hide 9358 */ startNotedAppOpsCollection(int callingUid)9359 public static void startNotedAppOpsCollection(int callingUid) { 9360 sBinderThreadCallingUid.set(callingUid); 9361 } 9362 9363 /** 9364 * State of a temporarily paused noted app-ops collection. 9365 * 9366 * @see #pauseNotedAppOpsCollection() 9367 * 9368 * @hide 9369 */ 9370 public static class PausedNotedAppOpsCollection { 9371 final int mUid; 9372 final @Nullable ArrayMap<String, long[]> mCollectedNotedAppOps; 9373 PausedNotedAppOpsCollection(int uid, @Nullable ArrayMap<String, long[]> collectedNotedAppOps)9374 PausedNotedAppOpsCollection(int uid, @Nullable ArrayMap<String, 9375 long[]> collectedNotedAppOps) { 9376 mUid = uid; 9377 mCollectedNotedAppOps = collectedNotedAppOps; 9378 } 9379 } 9380 9381 /** 9382 * Temporarily suspend collection of noted app-ops when binder-thread calls into the other 9383 * process. During such a call there might be call-backs coming back on the same thread which 9384 * should not be accounted to the current collection. 9385 * 9386 * @return a state needed to resume the collection 9387 * 9388 * @hide 9389 */ pauseNotedAppOpsCollection()9390 public static @Nullable PausedNotedAppOpsCollection pauseNotedAppOpsCollection() { 9391 Integer previousUid = sBinderThreadCallingUid.get(); 9392 if (previousUid != null) { 9393 ArrayMap<String, long[]> previousCollectedNotedAppOps = 9394 sAppOpsNotedInThisBinderTransaction.get(); 9395 9396 sBinderThreadCallingUid.remove(); 9397 sAppOpsNotedInThisBinderTransaction.remove(); 9398 9399 return new PausedNotedAppOpsCollection(previousUid, previousCollectedNotedAppOps); 9400 } 9401 9402 return null; 9403 } 9404 9405 /** 9406 * Resume a collection paused via {@link #pauseNotedAppOpsCollection}. 9407 * 9408 * @param prevCollection The state of the previous collection 9409 * 9410 * @hide 9411 */ resumeNotedAppOpsCollection( @ullable PausedNotedAppOpsCollection prevCollection)9412 public static void resumeNotedAppOpsCollection( 9413 @Nullable PausedNotedAppOpsCollection prevCollection) { 9414 if (prevCollection != null) { 9415 sBinderThreadCallingUid.set(prevCollection.mUid); 9416 9417 if (prevCollection.mCollectedNotedAppOps != null) { 9418 sAppOpsNotedInThisBinderTransaction.set(prevCollection.mCollectedNotedAppOps); 9419 } 9420 } 9421 } 9422 9423 /** 9424 * Finish collection of noted appops on this thread. 9425 * 9426 * <p>Called at the end of a two way binder transaction. 9427 * 9428 * @see #startNotedAppOpsCollection(int) 9429 * 9430 * @hide 9431 */ finishNotedAppOpsCollection()9432 public static void finishNotedAppOpsCollection() { 9433 sBinderThreadCallingUid.remove(); 9434 sAppOpsNotedInThisBinderTransaction.remove(); 9435 } 9436 9437 /** 9438 * Collect a noted op for the current process. 9439 * 9440 * @param op The noted op 9441 * @param attributionTag The attribution tag the op is noted for 9442 */ collectNotedOpForSelf(SyncNotedAppOp syncOp)9443 private void collectNotedOpForSelf(SyncNotedAppOp syncOp) { 9444 synchronized (sLock) { 9445 if (sOnOpNotedCallback != null) { 9446 sOnOpNotedCallback.onSelfNoted(syncOp); 9447 } 9448 } 9449 sMessageCollector.onSelfNoted(syncOp); 9450 } 9451 9452 /** 9453 * Collect a noted op when inside of a two-way binder call. 9454 * 9455 * <p> Delivered to caller via {@link #prefixParcelWithAppOpsIfNeeded} 9456 * 9457 * @param syncOp the op and attribution tag to note for 9458 * 9459 * @hide 9460 */ 9461 @TestApi collectNotedOpSync(@onNull SyncNotedAppOp syncOp)9462 public static void collectNotedOpSync(@NonNull SyncNotedAppOp syncOp) { 9463 // If this is inside of a two-way binder call: 9464 // We are inside of a two-way binder call. Delivered to caller via 9465 // {@link #prefixParcelWithAppOpsIfNeeded} 9466 int op = sOpStrToOp.get(syncOp.getOp()); 9467 ArrayMap<String, long[]> appOpsNoted = sAppOpsNotedInThisBinderTransaction.get(); 9468 if (appOpsNoted == null) { 9469 appOpsNoted = new ArrayMap<>(1); 9470 sAppOpsNotedInThisBinderTransaction.set(appOpsNoted); 9471 } 9472 9473 long[] appOpsNotedForAttribution = appOpsNoted.get(syncOp.getAttributionTag()); 9474 if (appOpsNotedForAttribution == null) { 9475 appOpsNotedForAttribution = new long[2]; 9476 appOpsNoted.put(syncOp.getAttributionTag(), appOpsNotedForAttribution); 9477 } 9478 9479 if (op < 64) { 9480 appOpsNotedForAttribution[0] |= 1L << op; 9481 } else { 9482 appOpsNotedForAttribution[1] |= 1L << (op - 64); 9483 } 9484 } 9485 9486 /** @hide */ 9487 @Retention(RetentionPolicy.SOURCE) 9488 @IntDef(value = { 9489 DONT_COLLECT, 9490 COLLECT_SELF, 9491 COLLECT_SYNC, 9492 COLLECT_ASYNC 9493 }) 9494 private @interface NotedOpCollectionMode {} 9495 private static final int DONT_COLLECT = 0; 9496 private static final int COLLECT_SELF = 1; 9497 private static final int COLLECT_SYNC = 2; 9498 private static final int COLLECT_ASYNC = 3; 9499 9500 /** 9501 * Mark an app-op as noted. 9502 */ getNotedOpCollectionMode(int uid, @Nullable String packageName, int op)9503 private @NotedOpCollectionMode int getNotedOpCollectionMode(int uid, 9504 @Nullable String packageName, int op) { 9505 if (packageName == null) { 9506 packageName = "android"; 9507 } 9508 9509 // check if the appops needs to be collected and cache result 9510 if (sAppOpsToNote[op] == SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED) { 9511 boolean shouldCollectNotes; 9512 try { 9513 shouldCollectNotes = mService.shouldCollectNotes(op); 9514 } catch (RemoteException e) { 9515 return DONT_COLLECT; 9516 } 9517 9518 if (shouldCollectNotes) { 9519 sAppOpsToNote[op] = SHOULD_COLLECT_NOTE_OP; 9520 } else { 9521 sAppOpsToNote[op] = SHOULD_NOT_COLLECT_NOTE_OP; 9522 } 9523 } 9524 9525 if (sAppOpsToNote[op] != SHOULD_COLLECT_NOTE_OP) { 9526 return DONT_COLLECT; 9527 } 9528 9529 synchronized (sLock) { 9530 if (uid == Process.myUid() 9531 && packageName.equals(ActivityThread.currentOpPackageName())) { 9532 return COLLECT_SELF; 9533 } 9534 } 9535 9536 Integer binderUid = sBinderThreadCallingUid.get(); 9537 9538 if (binderUid != null && binderUid == uid) { 9539 return COLLECT_SYNC; 9540 } else { 9541 return COLLECT_ASYNC; 9542 } 9543 } 9544 9545 /** 9546 * Append app-ops noted in the current two-way binder transaction to parcel. 9547 * 9548 * <p>This is called on the callee side of a two way binder transaction just before the 9549 * transaction returns. 9550 * 9551 * @param p the parcel to append the noted app-ops to 9552 * 9553 * @hide 9554 */ 9555 // TODO (b/186872903) Refactor how sync noted ops are propagated. prefixParcelWithAppOpsIfNeeded(@onNull Parcel p)9556 public static void prefixParcelWithAppOpsIfNeeded(@NonNull Parcel p) { 9557 ArrayMap<String, long[]> notedAppOps = sAppOpsNotedInThisBinderTransaction.get(); 9558 if (notedAppOps == null) { 9559 return; 9560 } 9561 9562 p.writeInt(Parcel.EX_HAS_NOTED_APPOPS_REPLY_HEADER); 9563 9564 int numAttributionWithNotesAppOps = notedAppOps.size(); 9565 p.writeInt(numAttributionWithNotesAppOps); 9566 9567 for (int i = 0; i < numAttributionWithNotesAppOps; i++) { 9568 p.writeString(notedAppOps.keyAt(i)); 9569 p.writeLong(notedAppOps.valueAt(i)[0]); 9570 p.writeLong(notedAppOps.valueAt(i)[1]); 9571 } 9572 } 9573 9574 /** 9575 * Read app-ops noted during a two-way binder transaction from parcel. 9576 * 9577 * <p>This is called on the calling side of a two way binder transaction just after the 9578 * transaction returns. 9579 * 9580 * @param p The parcel to read from 9581 * 9582 * @hide 9583 */ readAndLogNotedAppops(@onNull Parcel p)9584 public static void readAndLogNotedAppops(@NonNull Parcel p) { 9585 int numAttributionsWithNotedAppOps = p.readInt(); 9586 9587 for (int i = 0; i < numAttributionsWithNotedAppOps; i++) { 9588 String attributionTag = p.readString(); 9589 long[] rawNotedAppOps = new long[2]; 9590 rawNotedAppOps[0] = p.readLong(); 9591 rawNotedAppOps[1] = p.readLong(); 9592 9593 if (rawNotedAppOps[0] != 0 || rawNotedAppOps[1] != 0) { 9594 BitSet notedAppOps = BitSet.valueOf(rawNotedAppOps); 9595 9596 synchronized (sLock) { 9597 for (int code = notedAppOps.nextSetBit(0); code != -1; 9598 code = notedAppOps.nextSetBit(code + 1)) { 9599 if (sOnOpNotedCallback != null) { 9600 sOnOpNotedCallback.onNoted(new SyncNotedAppOp(code, attributionTag)); 9601 } else { 9602 String message = getFormattedStackTrace(); 9603 sUnforwardedOps.add( 9604 new AsyncNotedAppOp(code, Process.myUid(), attributionTag, 9605 message, System.currentTimeMillis())); 9606 if (sUnforwardedOps.size() > MAX_UNFORWARDED_OPS) { 9607 sUnforwardedOps.remove(0); 9608 } 9609 } 9610 } 9611 } 9612 for (int code = notedAppOps.nextSetBit(0); code != -1; 9613 code = notedAppOps.nextSetBit(code + 1)) { 9614 sMessageCollector.onNoted(new SyncNotedAppOp(code, attributionTag)); 9615 } 9616 } 9617 } 9618 } 9619 9620 /** 9621 * Set a new {@link OnOpNotedCallback}. 9622 * 9623 * <p>There can only ever be one collector per process. If there currently is another callback 9624 * set, this will fail. 9625 * 9626 * @param asyncExecutor executor to execute {@link OnOpNotedCallback#onAsyncNoted} on, {@code 9627 * null} to unset 9628 * @param callback listener to set, {@code null} to unset 9629 * 9630 * @throws IllegalStateException If another callback is already registered 9631 */ setOnOpNotedCallback(@ullable @allbackExecutor Executor asyncExecutor, @Nullable OnOpNotedCallback callback)9632 public void setOnOpNotedCallback(@Nullable @CallbackExecutor Executor asyncExecutor, 9633 @Nullable OnOpNotedCallback callback) { 9634 Preconditions.checkState((callback == null) == (asyncExecutor == null)); 9635 9636 synchronized (sLock) { 9637 if (callback == null) { 9638 Preconditions.checkState(sOnOpNotedCallback != null, 9639 "No callback is currently registered"); 9640 9641 try { 9642 mService.stopWatchingAsyncNoted(mContext.getPackageName(), 9643 sOnOpNotedCallback.mAsyncCb); 9644 } catch (RemoteException e) { 9645 e.rethrowFromSystemServer(); 9646 } 9647 9648 sOnOpNotedCallback = null; 9649 } else { 9650 Preconditions.checkState(sOnOpNotedCallback == null, 9651 "Another callback is already registered"); 9652 9653 callback.mAsyncExecutor = asyncExecutor; 9654 sOnOpNotedCallback = callback; 9655 9656 List<AsyncNotedAppOp> missedAsyncOps = null; 9657 try { 9658 mService.startWatchingAsyncNoted(mContext.getPackageName(), 9659 sOnOpNotedCallback.mAsyncCb); 9660 missedAsyncOps = mService.extractAsyncOps(mContext.getPackageName()); 9661 } catch (RemoteException e) { 9662 e.rethrowFromSystemServer(); 9663 } 9664 9665 // Copy pointer so callback can be dispatched out of lock 9666 OnOpNotedCallback onOpNotedCallback = sOnOpNotedCallback; 9667 if (onOpNotedCallback != null && missedAsyncOps != null) { 9668 int numMissedAsyncOps = missedAsyncOps.size(); 9669 for (int i = 0; i < numMissedAsyncOps; i++) { 9670 final AsyncNotedAppOp asyncNotedAppOp = missedAsyncOps.get(i); 9671 onOpNotedCallback.getAsyncNotedExecutor().execute( 9672 () -> onOpNotedCallback.onAsyncNoted(asyncNotedAppOp)); 9673 } 9674 } 9675 synchronized (this) { 9676 int numMissedSyncOps = sUnforwardedOps.size(); 9677 if (onOpNotedCallback != null) { 9678 for (int i = 0; i < numMissedSyncOps; i++) { 9679 final AsyncNotedAppOp syncNotedAppOp = sUnforwardedOps.get(i); 9680 onOpNotedCallback.getAsyncNotedExecutor().execute( 9681 () -> onOpNotedCallback.onAsyncNoted(syncNotedAppOp)); 9682 } 9683 } 9684 sUnforwardedOps.clear(); 9685 } 9686 } 9687 } 9688 } 9689 9690 // TODO moltmann: Remove 9691 /** 9692 * Will be removed before R ships, leave it just to not break apps immediately. 9693 * 9694 * @removed 9695 * 9696 * @hide 9697 */ 9698 @SystemApi 9699 @Deprecated setNotedAppOpsCollector(@ullable AppOpsCollector collector)9700 public void setNotedAppOpsCollector(@Nullable AppOpsCollector collector) { 9701 synchronized (sLock) { 9702 if (collector != null) { 9703 if (isListeningForOpNoted()) { 9704 setOnOpNotedCallback(null, null); 9705 } 9706 setOnOpNotedCallback(new HandlerExecutor(Handler.getMain()), collector); 9707 } else if (sOnOpNotedCallback != null) { 9708 setOnOpNotedCallback(null, null); 9709 } 9710 } 9711 } 9712 9713 /** 9714 * @return {@code true} iff the process currently is currently collecting noted appops. 9715 * 9716 * @see #setOnOpNotedCallback 9717 * 9718 * @hide 9719 */ isListeningForOpNoted()9720 public static boolean isListeningForOpNoted() { 9721 return sOnOpNotedCallback != null || isCollectingStackTraces(); 9722 } 9723 9724 /** 9725 * @return {@code true} iff the process is currently sampled for stacktrace collection. 9726 * 9727 * @see #setOnOpNotedCallback 9728 * 9729 * @hide 9730 */ isCollectingStackTraces()9731 private static boolean isCollectingStackTraces() { 9732 if (sConfig.getSampledOpCode() == OP_NONE && sConfig.getAcceptableLeftDistance() == 0 && 9733 sConfig.getExpirationTimeSinceBootMillis() >= SystemClock.elapsedRealtime()) { 9734 return false; 9735 } 9736 return true; 9737 } 9738 9739 /** 9740 * Callback an app can {@link #setOnOpNotedCallback set} to monitor the app-ops the 9741 * system has tracked for it. I.e. each time any app calls {@link #noteOp} or {@link #startOp} 9742 * one of a method of this object is called. 9743 * 9744 * <p><b>There will be a call for all app-ops related to runtime permissions, but not 9745 * necessarily for all other app-ops. 9746 * 9747 * <pre> 9748 * setOnOpNotedCallback(getMainExecutor(), new OnOpNotedCallback() { 9749 * ArraySet<Pair<String, String>> opsNotedForThisProcess = new ArraySet<>(); 9750 * 9751 * private synchronized void addAccess(String op, String accessLocation) { 9752 * // Ops are often noted when runtime permission protected APIs were called. 9753 * // In this case permissionToOp() allows to resolve the permission<->op 9754 * opsNotedForThisProcess.add(new Pair(accessType, accessLocation)); 9755 * } 9756 * 9757 * public void onNoted(SyncNotedAppOp op) { 9758 * // Accesses is currently happening, hence stack trace describes location of access 9759 * addAccess(op.getOp(), Arrays.toString(Thread.currentThread().getStackTrace())); 9760 * } 9761 * 9762 * public void onSelfNoted(SyncNotedAppOp op) { 9763 * onNoted(op); 9764 * } 9765 * 9766 * public void onAsyncNoted(AsyncNotedAppOp asyncOp) { 9767 * // Stack trace is not useful for async ops as accessed happened on different thread 9768 * addAccess(asyncOp.getOp(), asyncOp.getMessage()); 9769 * } 9770 * }); 9771 * </pre> 9772 * 9773 * @see #setOnOpNotedCallback 9774 */ 9775 public abstract static class OnOpNotedCallback { 9776 private @NonNull Executor mAsyncExecutor; 9777 9778 /** Callback registered with the system. This will receive the async notes ops */ 9779 private final IAppOpsAsyncNotedCallback mAsyncCb = new IAppOpsAsyncNotedCallback.Stub() { 9780 @Override 9781 public void opNoted(AsyncNotedAppOp op) { 9782 Objects.requireNonNull(op); 9783 9784 final long token = Binder.clearCallingIdentity(); 9785 try { 9786 getAsyncNotedExecutor().execute(() -> onAsyncNoted(op)); 9787 } finally { 9788 Binder.restoreCallingIdentity(token); 9789 } 9790 } 9791 }; 9792 9793 // TODO moltmann: Remove 9794 /** 9795 * Will be removed before R ships. 9796 * 9797 * @return The executor for the system to use when calling {@link #onAsyncNoted}. 9798 * 9799 * @hide 9800 */ getAsyncNotedExecutor()9801 protected @NonNull Executor getAsyncNotedExecutor() { 9802 return mAsyncExecutor; 9803 } 9804 9805 /** 9806 * Called when an app-op was {@link #noteOp noted} for this package inside of a synchronous 9807 * API call, i.e. a API call that returned data or waited until the action was performed. 9808 * 9809 * <p>Called on the calling thread before the API returns. This allows the app to e.g. 9810 * collect stack traces to figure out where the access came from. 9811 * 9812 * @param op op noted 9813 */ onNoted(@onNull SyncNotedAppOp op)9814 public abstract void onNoted(@NonNull SyncNotedAppOp op); 9815 9816 /** 9817 * Called when this app noted an app-op for its own package, 9818 * 9819 * <p>This is very similar to {@link #onNoted} only that the tracking was not caused by the 9820 * API provider in a separate process, but by one in the app's own process. 9821 * 9822 * @param op op noted 9823 */ onSelfNoted(@onNull SyncNotedAppOp op)9824 public abstract void onSelfNoted(@NonNull SyncNotedAppOp op); 9825 9826 /** 9827 * Called when an app-op was noted for this package which cannot be delivered via the other 9828 * two mechanisms. 9829 * 9830 * <p>Called as soon as possible after the app-op was noted, but the delivery delay is not 9831 * guaranteed. Due to how async calls work in Android this might even be delivered slightly 9832 * before the private data is delivered to the app. 9833 * 9834 * <p>If the app is not running or no {@link OnOpNotedCallback} is registered a small amount 9835 * of noted app-ops are buffered and then delivered as soon as a listener is registered. 9836 * 9837 * @param asyncOp op noted 9838 */ onAsyncNoted(@onNull AsyncNotedAppOp asyncOp)9839 public abstract void onAsyncNoted(@NonNull AsyncNotedAppOp asyncOp); 9840 } 9841 9842 // TODO moltmann: Remove 9843 /** 9844 * Will be removed before R ships, leave it just to not break apps immediately. 9845 * 9846 * @removed 9847 * 9848 * @hide 9849 */ 9850 @SystemApi 9851 @Deprecated 9852 public abstract static class AppOpsCollector extends OnOpNotedCallback { getAsyncNotedExecutor()9853 public @NonNull Executor getAsyncNotedExecutor() { 9854 return new HandlerExecutor(Handler.getMain()); 9855 } 9856 }; 9857 9858 /** 9859 * Generate a stack trace used for noted app-ops logging. 9860 * 9861 * <p>This strips away the first few and last few stack trace elements as they are not 9862 * interesting to apps. 9863 */ getFormattedStackTrace()9864 private static String getFormattedStackTrace() { 9865 StackTraceElement[] trace = new Exception().getStackTrace(); 9866 9867 int firstInteresting = 0; 9868 for (int i = 0; i < trace.length; i++) { 9869 if (trace[i].getClassName().startsWith(AppOpsManager.class.getName()) 9870 || trace[i].getClassName().startsWith(Parcel.class.getName()) 9871 || trace[i].getClassName().contains("$Stub$Proxy") 9872 || trace[i].getClassName().startsWith(DatabaseUtils.class.getName()) 9873 || trace[i].getClassName().startsWith("android.content.ContentProviderProxy") 9874 || trace[i].getClassName().startsWith(ContentResolver.class.getName())) { 9875 firstInteresting = i; 9876 } else { 9877 break; 9878 } 9879 } 9880 9881 int lastInteresting = trace.length - 1; 9882 for (int i = trace.length - 1; i >= 0; i--) { 9883 if (trace[i].getClassName().startsWith(HandlerThread.class.getName()) 9884 || trace[i].getClassName().startsWith(Handler.class.getName()) 9885 || trace[i].getClassName().startsWith(Looper.class.getName()) 9886 || trace[i].getClassName().startsWith(Binder.class.getName()) 9887 || trace[i].getClassName().startsWith(RuntimeInit.class.getName()) 9888 || trace[i].getClassName().startsWith(ZygoteInit.class.getName()) 9889 || trace[i].getClassName().startsWith(ActivityThread.class.getName()) 9890 || trace[i].getClassName().startsWith(Method.class.getName()) 9891 || trace[i].getClassName().startsWith("com.android.server.SystemServer")) { 9892 lastInteresting = i; 9893 } else { 9894 break; 9895 } 9896 } 9897 9898 StringBuilder sb = new StringBuilder(); 9899 for (int i = firstInteresting; i <= lastInteresting; i++) { 9900 if (sFullLog == null) { 9901 try { 9902 sFullLog = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY, 9903 FULL_LOG, false); 9904 } catch (Exception e) { 9905 // This should not happen, but it may, in rare cases 9906 sFullLog = false; 9907 } 9908 } 9909 9910 if (i != firstInteresting) { 9911 sb.append('\n'); 9912 } 9913 if (!sFullLog && sb.length() + trace[i].toString().length() > 600) { 9914 break; 9915 } 9916 sb.append(trace[i]); 9917 } 9918 9919 return sb.toString(); 9920 } 9921 9922 /** 9923 * Checks whether the given op for a UID and package is active. 9924 * 9925 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission 9926 * you can query only for your UID. 9927 * 9928 * @see #startWatchingActive(int[], OnOpActiveChangedListener) 9929 * @see #stopWatchingMode(OnOpChangedListener) 9930 * @see #finishOp(int, int, String, String) 9931 * @see #startOp(int, int, String, boolean, String, String) 9932 * 9933 * @hide */ 9934 @TestApi 9935 // TODO: Uncomment below annotation once b/73559440 is fixed 9936 // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true) isOperationActive(int code, int uid, String packageName)9937 public boolean isOperationActive(int code, int uid, String packageName) { 9938 try { 9939 return mService.isOperationActive(code, uid, packageName); 9940 } catch (RemoteException e) { 9941 throw e.rethrowFromSystemServer(); 9942 } 9943 } 9944 9945 /** 9946 * Configures the app ops persistence for testing. 9947 * 9948 * @param mode The mode in which the historical registry operates. 9949 * @param baseSnapshotInterval The base interval on which we would be persisting a snapshot of 9950 * the historical data. The history is recursive where every subsequent step encompasses 9951 * {@code compressionStep} longer interval with {@code compressionStep} distance between 9952 * snapshots. 9953 * @param compressionStep The compression step in every iteration. 9954 * 9955 * @see #HISTORICAL_MODE_DISABLED 9956 * @see #HISTORICAL_MODE_ENABLED_ACTIVE 9957 * @see #HISTORICAL_MODE_ENABLED_PASSIVE 9958 * 9959 * @hide 9960 */ 9961 @TestApi 9962 @RequiresPermission(Manifest.permission.MANAGE_APPOPS) setHistoryParameters(@istoricalMode int mode, long baseSnapshotInterval, int compressionStep)9963 public void setHistoryParameters(@HistoricalMode int mode, long baseSnapshotInterval, 9964 int compressionStep) { 9965 try { 9966 mService.setHistoryParameters(mode, baseSnapshotInterval, compressionStep); 9967 } catch (RemoteException e) { 9968 throw e.rethrowFromSystemServer(); 9969 } 9970 } 9971 9972 /** 9973 * Offsets the history by the given duration. 9974 * 9975 * @param offsetMillis The offset duration. 9976 * 9977 * @hide 9978 */ 9979 @TestApi 9980 @RequiresPermission(Manifest.permission.MANAGE_APPOPS) offsetHistory(long offsetMillis)9981 public void offsetHistory(long offsetMillis) { 9982 try { 9983 mService.offsetHistory(offsetMillis); 9984 } catch (RemoteException e) { 9985 throw e.rethrowFromSystemServer(); 9986 } 9987 } 9988 9989 /** 9990 * Adds ops to the history directly. This could be useful for testing especially 9991 * when the historical registry operates in {@link #HISTORICAL_MODE_ENABLED_PASSIVE} 9992 * mode. 9993 * 9994 * @param ops The ops to add to the history. 9995 * 9996 * @see #setHistoryParameters(int, long, int) 9997 * @see #HISTORICAL_MODE_ENABLED_PASSIVE 9998 * 9999 * @hide 10000 */ 10001 @TestApi 10002 @RequiresPermission(Manifest.permission.MANAGE_APPOPS) addHistoricalOps(@onNull HistoricalOps ops)10003 public void addHistoricalOps(@NonNull HistoricalOps ops) { 10004 try { 10005 mService.addHistoricalOps(ops); 10006 } catch (RemoteException e) { 10007 throw e.rethrowFromSystemServer(); 10008 } 10009 } 10010 10011 /** 10012 * Resets the app ops persistence for testing. 10013 * 10014 * @see #setHistoryParameters(int, long, int) 10015 * 10016 * @hide 10017 */ 10018 @TestApi 10019 @RequiresPermission(Manifest.permission.MANAGE_APPOPS) resetHistoryParameters()10020 public void resetHistoryParameters() { 10021 try { 10022 mService.resetHistoryParameters(); 10023 } catch (RemoteException e) { 10024 throw e.rethrowFromSystemServer(); 10025 } 10026 } 10027 10028 /** 10029 * Clears all app ops history. 10030 * 10031 * @hide 10032 */ 10033 @TestApi 10034 @RequiresPermission(Manifest.permission.MANAGE_APPOPS) clearHistory()10035 public void clearHistory() { 10036 try { 10037 mService.clearHistory(); 10038 } catch (RemoteException e) { 10039 throw e.rethrowFromSystemServer(); 10040 } 10041 } 10042 10043 /** 10044 * Reboots the ops history. 10045 * 10046 * @param offlineDurationMillis The duration to wait between 10047 * tearing down and initializing the history. Must be greater 10048 * than or equal to zero. 10049 * 10050 * @hide 10051 */ 10052 @TestApi 10053 @RequiresPermission(Manifest.permission.MANAGE_APPOPS) rebootHistory(long offlineDurationMillis)10054 public void rebootHistory(long offlineDurationMillis) { 10055 try { 10056 mService.rebootHistory(offlineDurationMillis); 10057 } catch (RemoteException e) { 10058 throw e.rethrowFromSystemServer(); 10059 } 10060 } 10061 10062 /** 10063 * Pulls current AppOps access report and picks package and op to watch for next access report 10064 * Returns null if no reports were collected since last call. There is no guarantee of report 10065 * collection, hence this method should be called periodically even if no report was collected 10066 * to pick different package and op to watch. 10067 * @hide 10068 */ 10069 @SystemApi 10070 @RequiresPermission(Manifest.permission.GET_APP_OPS_STATS) collectRuntimeAppOpAccessMessage()10071 public @Nullable RuntimeAppOpAccessMessage collectRuntimeAppOpAccessMessage() { 10072 try { 10073 return mService.collectRuntimeAppOpAccessMessage(); 10074 } catch (RemoteException e) { 10075 throw e.rethrowFromSystemServer(); 10076 } 10077 } 10078 10079 /** 10080 * Returns all supported operation names. 10081 * @hide 10082 */ 10083 @SystemApi getOpStrs()10084 public static String[] getOpStrs() { 10085 return Arrays.copyOf(sOpToString, sOpToString.length); 10086 } 10087 10088 10089 /** 10090 * @return number of App ops 10091 * @hide 10092 */ 10093 @TestApi getNumOps()10094 public static int getNumOps() { 10095 return _NUM_OP; 10096 } 10097 10098 /** 10099 * Gets the last of the event. 10100 * 10101 * @param events The events 10102 * @param flags The UID flags 10103 * @param beginUidState The maximum UID state (inclusive) 10104 * @param endUidState The minimum UID state (inclusive) 10105 * 10106 * @return The last event of {@code null} 10107 */ getLastEvent( @ullable LongSparseArray<NoteOpEvent> events, @UidState int beginUidState, @UidState int endUidState, @OpFlags int flags)10108 private static @Nullable NoteOpEvent getLastEvent( 10109 @Nullable LongSparseArray<NoteOpEvent> events, @UidState int beginUidState, 10110 @UidState int endUidState, @OpFlags int flags) { 10111 if (events == null) { 10112 return null; 10113 } 10114 10115 NoteOpEvent lastEvent = null; 10116 while (flags != 0) { 10117 final int flag = 1 << Integer.numberOfTrailingZeros(flags); 10118 flags &= ~flag; 10119 for (int uidState : UID_STATES) { 10120 if (uidState < beginUidState || uidState > endUidState) { 10121 continue; 10122 } 10123 final long key = makeKey(uidState, flag); 10124 10125 NoteOpEvent event = events.get(key); 10126 if (lastEvent == null 10127 || event != null && event.getNoteTime() > lastEvent.getNoteTime()) { 10128 lastEvent = event; 10129 } 10130 } 10131 } 10132 10133 return lastEvent; 10134 } 10135 equalsLongSparseLongArray(@ullable LongSparseLongArray a, @Nullable LongSparseLongArray b)10136 private static boolean equalsLongSparseLongArray(@Nullable LongSparseLongArray a, 10137 @Nullable LongSparseLongArray b) { 10138 if (a == b) { 10139 return true; 10140 } 10141 10142 if (a == null || b == null) { 10143 return false; 10144 } 10145 10146 if (a.size() != b.size()) { 10147 return false; 10148 } 10149 10150 int numEntries = a.size(); 10151 for (int i = 0; i < numEntries; i++) { 10152 if (a.keyAt(i) != b.keyAt(i) || a.valueAt(i) != b.valueAt(i)) { 10153 return false; 10154 } 10155 } 10156 10157 return true; 10158 } 10159 writeLongSparseLongArrayToParcel( @ullable LongSparseLongArray array, @NonNull Parcel parcel)10160 private static void writeLongSparseLongArrayToParcel( 10161 @Nullable LongSparseLongArray array, @NonNull Parcel parcel) { 10162 if (array != null) { 10163 final int size = array.size(); 10164 parcel.writeInt(size); 10165 for (int i = 0; i < size; i++) { 10166 parcel.writeLong(array.keyAt(i)); 10167 parcel.writeLong(array.valueAt(i)); 10168 } 10169 } else { 10170 parcel.writeInt(-1); 10171 } 10172 } 10173 readLongSparseLongArrayFromParcel( @onNull Parcel parcel)10174 private static @Nullable LongSparseLongArray readLongSparseLongArrayFromParcel( 10175 @NonNull Parcel parcel) { 10176 final int size = parcel.readInt(); 10177 if (size < 0) { 10178 return null; 10179 } 10180 final LongSparseLongArray array = new LongSparseLongArray(size); 10181 for (int i = 0; i < size; i++) { 10182 array.append(parcel.readLong(), parcel.readLong()); 10183 } 10184 return array; 10185 } 10186 writeDiscreteAccessArrayToParcel( @ullable List<AttributedOpEntry> array, @NonNull Parcel parcel, int flags)10187 private static void writeDiscreteAccessArrayToParcel( 10188 @Nullable List<AttributedOpEntry> array, @NonNull Parcel parcel, int flags) { 10189 ParceledListSlice<AttributedOpEntry> listSlice = 10190 array == null ? null : new ParceledListSlice<>(array); 10191 parcel.writeParcelable(listSlice, flags); 10192 } 10193 readDiscreteAccessArrayFromParcel( @onNull Parcel parcel)10194 private static @Nullable List<AttributedOpEntry> readDiscreteAccessArrayFromParcel( 10195 @NonNull Parcel parcel) { 10196 final ParceledListSlice<AttributedOpEntry> listSlice = parcel.readParcelable(null, android.content.pm.ParceledListSlice.class); 10197 return listSlice == null ? null : listSlice.getList(); 10198 } 10199 10200 /** 10201 * Collects the keys from an array to the result creating the result if needed. 10202 * 10203 * @param array The array whose keys to collect. 10204 * @param result The optional result store collected keys. 10205 * @return The result collected keys array. 10206 */ collectKeys(@ullable LongSparseLongArray array, @Nullable LongSparseArray<Object> result)10207 private static LongSparseArray<Object> collectKeys(@Nullable LongSparseLongArray array, 10208 @Nullable LongSparseArray<Object> result) { 10209 if (array != null) { 10210 if (result == null) { 10211 result = new LongSparseArray<>(); 10212 } 10213 final int accessSize = array.size(); 10214 for (int i = 0; i < accessSize; i++) { 10215 result.put(array.keyAt(i), null); 10216 } 10217 } 10218 return result; 10219 } 10220 10221 /** @hide */ uidStateToString(@idState int uidState)10222 public static String uidStateToString(@UidState int uidState) { 10223 switch (uidState) { 10224 case UID_STATE_PERSISTENT: { 10225 return "UID_STATE_PERSISTENT"; 10226 } 10227 case UID_STATE_TOP: { 10228 return "UID_STATE_TOP"; 10229 } 10230 case UID_STATE_FOREGROUND_SERVICE_LOCATION: { 10231 return "UID_STATE_FOREGROUND_SERVICE_LOCATION"; 10232 } 10233 case UID_STATE_FOREGROUND_SERVICE: { 10234 return "UID_STATE_FOREGROUND_SERVICE"; 10235 } 10236 case UID_STATE_FOREGROUND: { 10237 return "UID_STATE_FOREGROUND"; 10238 } 10239 case UID_STATE_BACKGROUND: { 10240 return "UID_STATE_BACKGROUND"; 10241 } 10242 case UID_STATE_CACHED: { 10243 return "UID_STATE_CACHED"; 10244 } 10245 default: { 10246 return "UNKNOWN"; 10247 } 10248 } 10249 } 10250 10251 /** @hide */ parseHistoricalMode(@onNull String mode)10252 public static int parseHistoricalMode(@NonNull String mode) { 10253 switch (mode) { 10254 case "HISTORICAL_MODE_ENABLED_ACTIVE": { 10255 return HISTORICAL_MODE_ENABLED_ACTIVE; 10256 } 10257 case "HISTORICAL_MODE_ENABLED_PASSIVE": { 10258 return HISTORICAL_MODE_ENABLED_PASSIVE; 10259 } 10260 default: { 10261 return HISTORICAL_MODE_DISABLED; 10262 } 10263 } 10264 } 10265 10266 /** @hide */ historicalModeToString(@istoricalMode int mode)10267 public static String historicalModeToString(@HistoricalMode int mode) { 10268 switch (mode) { 10269 case HISTORICAL_MODE_DISABLED: { 10270 return "HISTORICAL_MODE_DISABLED"; 10271 } 10272 case HISTORICAL_MODE_ENABLED_ACTIVE: { 10273 return "HISTORICAL_MODE_ENABLED_ACTIVE"; 10274 } 10275 case HISTORICAL_MODE_ENABLED_PASSIVE: { 10276 return "HISTORICAL_MODE_ENABLED_PASSIVE"; 10277 } 10278 default: { 10279 return "UNKNOWN"; 10280 } 10281 } 10282 } 10283 getSystemAlertWindowDefault()10284 private static int getSystemAlertWindowDefault() { 10285 final Context context = ActivityThread.currentApplication(); 10286 if (context == null) { 10287 return AppOpsManager.MODE_DEFAULT; 10288 } 10289 10290 // system alert window is disable on low ram phones starting from Q 10291 final PackageManager pm = context.getPackageManager(); 10292 // TVs are constantly plugged in and has less concern for memory/power 10293 if (ActivityManager.isLowRamDeviceStatic() 10294 && !pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK, 0)) { 10295 return AppOpsManager.MODE_IGNORED; 10296 } 10297 10298 return AppOpsManager.MODE_DEFAULT; 10299 } 10300 10301 /** 10302 * Calculate left circular distance for two numbers modulo size. 10303 * @hide 10304 */ leftCircularDistance(int from, int to, int size)10305 public static int leftCircularDistance(int from, int to, int size) { 10306 return (to + size - from) % size; 10307 } 10308 10309 /** 10310 * Helper method for noteOp, startOp and noteProxyOp to call AppOpsService to collect/log 10311 * stack traces 10312 * 10313 * <p> For each call, the stacktrace op code, package name and long version code will be 10314 * passed along where it will be logged/collected 10315 * 10316 * @param op The operation to note 10317 */ collectNoteOpCallsForValidation(int op)10318 private void collectNoteOpCallsForValidation(int op) { 10319 if (NOTE_OP_COLLECTION_ENABLED) { 10320 try { 10321 mService.collectNoteOpCallsForValidation(getFormattedStackTrace(), 10322 op, mContext.getOpPackageName(), mContext.getApplicationInfo().longVersionCode); 10323 } catch (RemoteException e) { 10324 // Swallow error, only meant for logging ops, should not affect flow of the code 10325 } 10326 } 10327 } 10328 deduplicateDiscreteEvents(List<AttributedOpEntry> list)10329 private static List<AttributedOpEntry> deduplicateDiscreteEvents(List<AttributedOpEntry> list) { 10330 int n = list.size(); 10331 int i = 0; 10332 for (int j = 0, k = 0; j < n; i++, j = k) { 10333 long currentAccessTime = list.get(j).getLastAccessTime(OP_FLAGS_ALL); 10334 k = j + 1; 10335 while(k < n && list.get(k).getLastAccessTime(OP_FLAGS_ALL) == currentAccessTime) { 10336 k++; 10337 } 10338 list.set(i, mergeAttributedOpEntries(list.subList(j, k))); 10339 } 10340 for (; i < n; i++) { 10341 list.remove(list.size() - 1); 10342 } 10343 return list; 10344 } 10345 mergeAttributedOpEntries(List<AttributedOpEntry> opEntries)10346 private static AttributedOpEntry mergeAttributedOpEntries(List<AttributedOpEntry> opEntries) { 10347 if (opEntries.size() == 1) { 10348 return opEntries.get(0); 10349 } 10350 LongSparseArray<AppOpsManager.NoteOpEvent> accessEvents = new LongSparseArray<>(); 10351 LongSparseArray<AppOpsManager.NoteOpEvent> rejectEvents = new LongSparseArray<>(); 10352 int opCount = opEntries.size(); 10353 for (int i = 0; i < opCount; i++) { 10354 AttributedOpEntry a = opEntries.get(i); 10355 ArraySet<Long> keys = a.collectKeys(); 10356 final int keyCount = keys.size(); 10357 for (int k = 0; k < keyCount; k++) { 10358 final long key = keys.valueAt(k); 10359 10360 final int uidState = extractUidStateFromKey(key); 10361 final int flags = extractFlagsFromKey(key); 10362 10363 NoteOpEvent access = a.getLastAccessEvent(uidState, uidState, flags); 10364 NoteOpEvent reject = a.getLastRejectEvent(uidState, uidState, flags); 10365 10366 if (access != null) { 10367 NoteOpEvent existingAccess = accessEvents.get(key); 10368 if (existingAccess == null || existingAccess.getDuration() == -1) { 10369 accessEvents.append(key, access); 10370 } else if (existingAccess.mProxy == null && access.mProxy != null ) { 10371 existingAccess.mProxy = access.mProxy; 10372 } 10373 } 10374 if (reject != null) { 10375 rejectEvents.append(key, reject); 10376 } 10377 } 10378 } 10379 return new AttributedOpEntry(opEntries.get(0).mOp, false, accessEvents, rejectEvents); 10380 } 10381 } 10382