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