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