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