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