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