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