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