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