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