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