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