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