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.IntDef;
21 import android.annotation.IntRange;
22 import android.annotation.NonNull;
23 import android.annotation.Nullable;
24 import android.annotation.RequiresPermission;
25 import android.annotation.SystemApi;
26 import android.annotation.SystemService;
27 import android.annotation.TestApi;
28 import android.app.usage.UsageStatsManager;
29 import android.compat.annotation.UnsupportedAppUsage;
30 import android.content.Context;
31 import android.content.pm.PackageManager;
32 import android.content.pm.ParceledListSlice;
33 import android.media.AudioAttributes.AttributeUsage;
34 import android.os.Binder;
35 import android.os.IBinder;
36 import android.os.Parcel;
37 import android.os.Parcelable;
38 import android.os.Process;
39 import android.os.RemoteCallback;
40 import android.os.RemoteException;
41 import android.os.UserManager;
42 import android.util.ArrayMap;
43 import android.util.LongSparseArray;
44 import android.util.LongSparseLongArray;
45 import android.util.SparseArray;
46 
47 import com.android.internal.annotations.GuardedBy;
48 import com.android.internal.annotations.Immutable;
49 import com.android.internal.app.IAppOpsActiveCallback;
50 import com.android.internal.app.IAppOpsCallback;
51 import com.android.internal.app.IAppOpsNotedCallback;
52 import com.android.internal.app.IAppOpsService;
53 import com.android.internal.util.ArrayUtils;
54 import com.android.internal.util.Preconditions;
55 
56 import java.lang.annotation.ElementType;
57 import java.lang.annotation.Retention;
58 import java.lang.annotation.RetentionPolicy;
59 import java.lang.annotation.Target;
60 import java.math.BigDecimal;
61 import java.math.RoundingMode;
62 import java.util.ArrayList;
63 import java.util.Arrays;
64 import java.util.Collections;
65 import java.util.HashMap;
66 import java.util.List;
67 import java.util.Objects;
68 import java.util.concurrent.Executor;
69 import java.util.function.Consumer;
70 import java.util.function.Supplier;
71 
72 /**
73  * API for interacting with "application operation" tracking.
74  *
75  * <p>This API is not generally intended for third party application developers; most
76  * features are only available to system applications.
77  */
78 @SystemService(Context.APP_OPS_SERVICE)
79 public class AppOpsManager {
80     /**
81      * <p>App ops allows callers to:</p>
82      *
83      * <ul>
84      * <li> Note when operations are happening, and find out if they are allowed for the current
85      * caller.</li>
86      * <li> Disallow specific apps from doing specific operations.</li>
87      * <li> Collect all of the current information about operations that have been executed or
88      * are not being allowed.</li>
89      * <li> Monitor for changes in whether an operation is allowed.</li>
90      * </ul>
91      *
92      * <p>Each operation is identified by a single integer; these integers are a fixed set of
93      * operations, enumerated by the OP_* constants.
94      *
95      * <p></p>When checking operations, the result is a "mode" integer indicating the current
96      * setting for the operation under that caller: MODE_ALLOWED, MODE_IGNORED (don't execute
97      * the operation but fake its behavior enough so that the caller doesn't crash),
98      * MODE_ERRORED (throw a SecurityException back to the caller; the normal operation calls
99      * will do this for you).
100      */
101 
102     final Context mContext;
103 
104     @UnsupportedAppUsage
105     final IAppOpsService mService;
106 
107     @GuardedBy("mModeWatchers")
108     private final ArrayMap<OnOpChangedListener, IAppOpsCallback> mModeWatchers =
109             new ArrayMap<>();
110 
111     @GuardedBy("mActiveWatchers")
112     private final ArrayMap<OnOpActiveChangedListener, IAppOpsActiveCallback> mActiveWatchers =
113             new ArrayMap<>();
114 
115     @GuardedBy("mNotedWatchers")
116     private final ArrayMap<OnOpNotedListener, IAppOpsNotedCallback> mNotedWatchers =
117             new ArrayMap<>();
118 
119     static IBinder sToken;
120 
121     /** @hide */
122     @Retention(RetentionPolicy.SOURCE)
123     @IntDef(flag = true, prefix = { "HISTORICAL_MODE_" }, value = {
124             HISTORICAL_MODE_DISABLED,
125             HISTORICAL_MODE_ENABLED_ACTIVE,
126             HISTORICAL_MODE_ENABLED_PASSIVE
127     })
128     public @interface HistoricalMode {}
129 
130     /**
131      * Mode in which app op history is completely disabled.
132      * @hide
133      */
134     @TestApi
135     public static final int HISTORICAL_MODE_DISABLED = 0;
136 
137     /**
138      * Mode in which app op history is enabled and app ops performed by apps would
139      * be tracked. This is the mode in which the feature is completely enabled.
140      * @hide
141      */
142     @TestApi
143     public static final int HISTORICAL_MODE_ENABLED_ACTIVE = 1;
144 
145     /**
146      * Mode in which app op history is enabled but app ops performed by apps would
147      * not be tracked and the only way to add ops to the history is via explicit calls
148      * to dedicated APIs. This mode is useful for testing to allow full control of
149      * the historical content.
150      * @hide
151      */
152     @TestApi
153     public static final int HISTORICAL_MODE_ENABLED_PASSIVE = 2;
154 
155     /** @hide */
156     @Retention(RetentionPolicy.SOURCE)
157     @IntDef(flag = true, prefix = { "MODE_" }, value = {
158             MODE_ALLOWED,
159             MODE_IGNORED,
160             MODE_ERRORED,
161             MODE_DEFAULT,
162             MODE_FOREGROUND
163     })
164     public @interface Mode {}
165 
166     /**
167      * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is
168      * allowed to perform the given operation.
169      */
170     public static final int MODE_ALLOWED = 0;
171 
172     /**
173      * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is
174      * not allowed to perform the given operation, and this attempt should
175      * <em>silently fail</em> (it should not cause the app to crash).
176      */
177     public static final int MODE_IGNORED = 1;
178 
179     /**
180      * Result from {@link #checkOpNoThrow}, {@link #noteOpNoThrow}, {@link #startOpNoThrow}: the
181      * given caller is not allowed to perform the given operation, and this attempt should
182      * cause it to have a fatal error, typically a {@link SecurityException}.
183      */
184     public static final int MODE_ERRORED = 2;
185 
186     /**
187      * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller should
188      * use its default security check.  This mode is not normally used; it should only be used
189      * with appop permissions, and callers must explicitly check for it and deal with it.
190      */
191     public static final int MODE_DEFAULT = 3;
192 
193     /**
194      * Special mode that means "allow only when app is in foreground."  This is <b>not</b>
195      * returned from {@link #unsafeCheckOp}, {@link #noteOp}, {@link #startOp}.  Rather,
196      * {@link #unsafeCheckOp} will always return {@link #MODE_ALLOWED} (because it is always
197      * possible for it to be ultimately allowed, depending on the app's background state),
198      * and {@link #noteOp} and {@link #startOp} will return {@link #MODE_ALLOWED} when the app
199      * being checked is currently in the foreground, otherwise {@link #MODE_IGNORED}.
200      *
201      * <p>The only place you will this normally see this value is through
202      * {@link #unsafeCheckOpRaw}, which returns the actual raw mode of the op.  Note that because
203      * you can't know the current state of the app being checked (and it can change at any
204      * point), you can only treat the result here as an indication that it will vary between
205      * {@link #MODE_ALLOWED} and {@link #MODE_IGNORED} depending on changes in the background
206      * state of the app.  You thus must always use {@link #noteOp} or {@link #startOp} to do
207      * the actual check for access to the op.</p>
208      */
209     public static final int MODE_FOREGROUND = 4;
210 
211     /**
212      * Flag for {@link #startWatchingMode(String, String, int, OnOpChangedListener)}:
213      * Also get reports if the foreground state of an op's uid changes.  This only works
214      * when watching a particular op, not when watching a package.
215      */
216     public static final int WATCH_FOREGROUND_CHANGES = 1 << 0;
217 
218     /**
219      * @hide
220      */
221     public static final String[] MODE_NAMES = new String[] {
222             "allow",        // MODE_ALLOWED
223             "ignore",       // MODE_IGNORED
224             "deny",         // MODE_ERRORED
225             "default",      // MODE_DEFAULT
226             "foreground",   // MODE_FOREGROUND
227     };
228 
229     /** @hide */
230     @Retention(RetentionPolicy.SOURCE)
231     @IntDef(prefix = { "UID_STATE_" }, value = {
232             UID_STATE_PERSISTENT,
233             UID_STATE_TOP,
234             UID_STATE_FOREGROUND_SERVICE_LOCATION,
235             UID_STATE_FOREGROUND_SERVICE,
236             UID_STATE_FOREGROUND,
237             UID_STATE_BACKGROUND,
238             UID_STATE_CACHED
239     })
240     public @interface UidState {}
241 
242     /**
243      * Uid state: The UID is a foreground persistent app. The lower the UID
244      * state the more important the UID is for the user.
245      * @hide
246      */
247     @TestApi
248     @SystemApi
249     public static final int UID_STATE_PERSISTENT = 100;
250 
251     /**
252      * Uid state: The UID is top foreground app. The lower the UID
253      * state the more important the UID is for the user.
254      * @hide
255      */
256     @TestApi
257     @SystemApi
258     public static final int UID_STATE_TOP = 200;
259 
260     /**
261      * Uid state: The UID is running a foreground service of location type.
262      * The lower the UID state the more important the UID is for the user.
263      * @hide
264      */
265     @TestApi
266     @SystemApi
267     public static final int UID_STATE_FOREGROUND_SERVICE_LOCATION = 300;
268 
269     /**
270      * Uid state: The UID is running a foreground service. The lower the UID
271      * state the more important the UID is for the user.
272      * @hide
273      */
274     @TestApi
275     @SystemApi
276     public static final int UID_STATE_FOREGROUND_SERVICE = 400;
277 
278     /**
279      * The max, which is min priority, UID state for which any app op
280      * would be considered as performed in the foreground.
281      * @hide
282      */
283     public static final int UID_STATE_MAX_LAST_NON_RESTRICTED = UID_STATE_FOREGROUND_SERVICE;
284 
285     /**
286      * Uid state: The UID is a foreground app. The lower the UID
287      * state the more important the UID is for the user.
288      * @hide
289      */
290     @TestApi
291     @SystemApi
292     public static final int UID_STATE_FOREGROUND = 500;
293 
294     /**
295      * Uid state: The UID is a background app. The lower the UID
296      * state the more important the UID is for the user.
297      * @hide
298      */
299     @TestApi
300     @SystemApi
301     public static final int UID_STATE_BACKGROUND = 600;
302 
303     /**
304      * Uid state: The UID is a cached app. The lower the UID
305      * state the more important the UID is for the user.
306      * @hide
307      */
308     @TestApi
309     @SystemApi
310     public static final int UID_STATE_CACHED = 700;
311 
312     /**
313      * Uid state: The UID state with the highest priority.
314      * @hide
315      */
316     public static final int MAX_PRIORITY_UID_STATE = UID_STATE_PERSISTENT;
317 
318     /**
319      * Uid state: The UID state with the lowest priority.
320      * @hide
321      */
322     public static final int MIN_PRIORITY_UID_STATE = UID_STATE_CACHED;
323 
324     /**
325      * Resolves the first unrestricted state given an app op. Location is
326      * special as we want to allow its access only if a dedicated location
327      * foreground service is running. For other ops we consider any foreground
328      * service as a foreground state.
329      *
330      * @param op The op to resolve.
331      * @return The last restricted UID state.
332      *
333      * @hide
334      */
resolveFirstUnrestrictedUidState(int op)335     public static int resolveFirstUnrestrictedUidState(int op) {
336         switch (op) {
337             case OP_FINE_LOCATION:
338             case OP_COARSE_LOCATION:
339             case OP_MONITOR_LOCATION:
340             case OP_MONITOR_HIGH_POWER_LOCATION: {
341                 return UID_STATE_FOREGROUND_SERVICE_LOCATION;
342             }
343         }
344         return UID_STATE_FOREGROUND_SERVICE;
345     }
346 
347     /**
348      * Resolves the last restricted state given an app op. Location is
349      * special as we want to allow its access only if a dedicated location
350      * foreground service is running. For other ops we consider any foreground
351      * service as a foreground state.
352      *
353      * @param op The op to resolve.
354      * @return The last restricted UID state.
355      *
356      * @hide
357      */
resolveLastRestrictedUidState(int op)358     public static int resolveLastRestrictedUidState(int op) {
359         switch (op) {
360             case OP_FINE_LOCATION:
361             case OP_COARSE_LOCATION: {
362                 return UID_STATE_FOREGROUND_SERVICE;
363             }
364         }
365         return UID_STATE_FOREGROUND;
366     }
367 
368     /** @hide Note: Keep these sorted */
369     public static final int[] UID_STATES = {
370             UID_STATE_PERSISTENT,
371             UID_STATE_TOP,
372             UID_STATE_FOREGROUND_SERVICE_LOCATION,
373             UID_STATE_FOREGROUND_SERVICE,
374             UID_STATE_FOREGROUND,
375             UID_STATE_BACKGROUND,
376             UID_STATE_CACHED
377     };
378 
379     /** @hide */
getUidStateName(@idState int uidState)380     public static String getUidStateName(@UidState int uidState) {
381         switch (uidState) {
382             case UID_STATE_PERSISTENT:
383                 return "pers";
384             case UID_STATE_TOP:
385                 return "top";
386             case UID_STATE_FOREGROUND_SERVICE_LOCATION:
387                 return "fgsvcl";
388             case UID_STATE_FOREGROUND_SERVICE:
389                 return "fgsvc";
390             case UID_STATE_FOREGROUND:
391                 return "fg";
392             case UID_STATE_BACKGROUND:
393                 return "bg";
394             case UID_STATE_CACHED:
395                 return "cch";
396             default:
397                 return "unknown";
398         }
399     }
400 
401     /**
402      * Flag: non proxy operations. These are operations
403      * performed on behalf of the app itself and not on behalf of
404      * another one.
405      *
406      * @hide
407      */
408     @TestApi
409     @SystemApi
410     public static final int OP_FLAG_SELF = 0x1;
411 
412     /**
413      * Flag: trusted proxy operations. These are operations
414      * performed on behalf of another app by a trusted app.
415      * Which is work a trusted app blames on another app.
416      *
417      * @hide
418      */
419     @TestApi
420     @SystemApi
421     public static final int OP_FLAG_TRUSTED_PROXY = 0x2;
422 
423     /**
424      * Flag: untrusted proxy operations. These are operations
425      * performed on behalf of another app by an untrusted app.
426      * Which is work an untrusted app blames on another app.
427      *
428      * @hide
429      */
430     @TestApi
431     @SystemApi
432     public static final int OP_FLAG_UNTRUSTED_PROXY = 0x4;
433 
434     /**
435      * Flag: trusted proxied operations. These are operations
436      * performed by a trusted other app on behalf of an app.
437      * Which is work an app was blamed for by a trusted app.
438      *
439      * @hide
440      */
441     @TestApi
442     @SystemApi
443     public static final int OP_FLAG_TRUSTED_PROXIED = 0x8;
444 
445     /**
446      * Flag: untrusted proxied operations. These are operations
447      * performed by an untrusted other app on behalf of an app.
448      * Which is work an app was blamed for by an untrusted app.
449      *
450      * @hide
451      */
452     @TestApi
453     @SystemApi
454     public static final int OP_FLAG_UNTRUSTED_PROXIED = 0x10;
455 
456     /**
457      * Flags: all operations. These include operations matched
458      * by {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXIED},
459      * {@link #OP_FLAG_UNTRUSTED_PROXIED}, {@link #OP_FLAG_TRUSTED_PROXIED},
460      * {@link #OP_FLAG_UNTRUSTED_PROXIED}.
461      *
462      * @hide
463      */
464     @TestApi
465     @SystemApi
466     public static final int OP_FLAGS_ALL =
467             OP_FLAG_SELF
468                 | OP_FLAG_TRUSTED_PROXY
469                 | OP_FLAG_UNTRUSTED_PROXY
470                 | OP_FLAG_TRUSTED_PROXIED
471                 | OP_FLAG_UNTRUSTED_PROXIED;
472 
473     /**
474      * Flags: all trusted operations which is ones either the app did {@link #OP_FLAG_SELF},
475      * or it was blamed for by a trusted app {@link #OP_FLAG_TRUSTED_PROXIED}, or ones the
476      * app if untrusted blamed on other apps {@link #OP_FLAG_UNTRUSTED_PROXY}.
477      *
478      * @hide
479      */
480     @SystemApi
481     public static final int OP_FLAGS_ALL_TRUSTED = AppOpsManager.OP_FLAG_SELF
482         | AppOpsManager.OP_FLAG_UNTRUSTED_PROXY
483         | AppOpsManager.OP_FLAG_TRUSTED_PROXIED;
484 
485     /** @hide */
486     @Retention(RetentionPolicy.SOURCE)
487     @IntDef(flag = true, prefix = { "FLAG_" }, value = {
488             OP_FLAG_SELF,
489             OP_FLAG_TRUSTED_PROXY,
490             OP_FLAG_UNTRUSTED_PROXY,
491             OP_FLAG_TRUSTED_PROXIED,
492             OP_FLAG_UNTRUSTED_PROXIED
493     })
494     public @interface OpFlags {}
495 
496 
497     /** @hide */
getFlagName(@pFlags int flag)498     public static final String getFlagName(@OpFlags int flag) {
499         switch (flag) {
500             case OP_FLAG_SELF:
501                 return "s";
502             case OP_FLAG_TRUSTED_PROXY:
503                 return "tp";
504             case OP_FLAG_UNTRUSTED_PROXY:
505                 return "up";
506             case OP_FLAG_TRUSTED_PROXIED:
507                 return "tpd";
508             case OP_FLAG_UNTRUSTED_PROXIED:
509                 return "upd";
510             default:
511                 return "unknown";
512         }
513     }
514 
515     private static final int UID_STATE_OFFSET = 31;
516     private static final int FLAGS_MASK = 0xFFFFFFFF;
517 
518     /**
519      * Key for a data bucket storing app op state. The bucket
520      * is composed of the uid state and state flags. This way
521      * we can query data for given uid state and a set of flags where
522      * the flags control which type of data to get. For example,
523      * one can get the ops an app did on behalf of other apps
524      * while in the background.
525      *
526      * @hide
527      */
528     @Retention(RetentionPolicy.SOURCE)
529     @Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
530     public @interface DataBucketKey {
531     }
532 
533     /** @hide */
keyToString(@ataBucketKey long key)534     public static String keyToString(@DataBucketKey long key) {
535         final int uidState = extractUidStateFromKey(key);
536         final int flags = extractFlagsFromKey(key);
537         return "[" + getUidStateName(uidState) + "-" + flagsToString(flags) + "]";
538     }
539 
540     /** @hide */
makeKey(@idState int uidState, @OpFlags int flags)541     public static @DataBucketKey long makeKey(@UidState int uidState, @OpFlags int flags) {
542         return ((long) uidState << UID_STATE_OFFSET) | flags;
543     }
544 
545     /** @hide */
extractUidStateFromKey(@ataBucketKey long key)546     public static int extractUidStateFromKey(@DataBucketKey long key) {
547         return (int) (key >> UID_STATE_OFFSET);
548     }
549 
550     /** @hide */
extractFlagsFromKey(@ataBucketKey long key)551     public static int extractFlagsFromKey(@DataBucketKey long key) {
552         return (int) (key & FLAGS_MASK);
553     }
554 
555     /** @hide */
flagsToString(@pFlags int flags)556     public static String flagsToString(@OpFlags int flags) {
557         final StringBuilder flagsBuilder = new StringBuilder();
558         while (flags != 0) {
559             final int flag = 1 << Integer.numberOfTrailingZeros(flags);
560             flags &= ~flag;
561             if (flagsBuilder.length() > 0) {
562                 flagsBuilder.append('|');
563             }
564             flagsBuilder.append(getFlagName(flag));
565         }
566         return flagsBuilder.toString();
567     }
568 
569     // when adding one of these:
570     //  - increment _NUM_OP
571     //  - define an OPSTR_* constant (marked as @SystemApi)
572     //  - add rows to sOpToSwitch, sOpToString, sOpNames, sOpToPerms, sOpDefault
573     //  - add descriptive strings to Settings/res/values/arrays.xml
574     //  - add the op to the appropriate template in AppOpsState.OpsTemplate (settings app)
575 
576     /** @hide No operation specified. */
577     @UnsupportedAppUsage
578     public static final int OP_NONE = -1;
579     /** @hide Access to coarse location information. */
580     @UnsupportedAppUsage
581     @TestApi
582     public static final int OP_COARSE_LOCATION = 0;
583     /** @hide Access to fine location information. */
584     @UnsupportedAppUsage
585     public static final int OP_FINE_LOCATION = 1;
586     /** @hide Causing GPS to run. */
587     @UnsupportedAppUsage
588     public static final int OP_GPS = 2;
589     /** @hide */
590     @UnsupportedAppUsage
591     public static final int OP_VIBRATE = 3;
592     /** @hide */
593     @UnsupportedAppUsage
594     public static final int OP_READ_CONTACTS = 4;
595     /** @hide */
596     @UnsupportedAppUsage
597     public static final int OP_WRITE_CONTACTS = 5;
598     /** @hide */
599     @UnsupportedAppUsage
600     public static final int OP_READ_CALL_LOG = 6;
601     /** @hide */
602     @UnsupportedAppUsage
603     public static final int OP_WRITE_CALL_LOG = 7;
604     /** @hide */
605     @UnsupportedAppUsage
606     public static final int OP_READ_CALENDAR = 8;
607     /** @hide */
608     @UnsupportedAppUsage
609     public static final int OP_WRITE_CALENDAR = 9;
610     /** @hide */
611     @UnsupportedAppUsage
612     public static final int OP_WIFI_SCAN = 10;
613     /** @hide */
614     @UnsupportedAppUsage
615     public static final int OP_POST_NOTIFICATION = 11;
616     /** @hide */
617     @UnsupportedAppUsage
618     public static final int OP_NEIGHBORING_CELLS = 12;
619     /** @hide */
620     @UnsupportedAppUsage
621     public static final int OP_CALL_PHONE = 13;
622     /** @hide */
623     @UnsupportedAppUsage
624     public static final int OP_READ_SMS = 14;
625     /** @hide */
626     @UnsupportedAppUsage
627     public static final int OP_WRITE_SMS = 15;
628     /** @hide */
629     @UnsupportedAppUsage
630     public static final int OP_RECEIVE_SMS = 16;
631     /** @hide */
632     @UnsupportedAppUsage
633     public static final int OP_RECEIVE_EMERGECY_SMS = 17;
634     /** @hide */
635     @UnsupportedAppUsage
636     public static final int OP_RECEIVE_MMS = 18;
637     /** @hide */
638     @UnsupportedAppUsage
639     public static final int OP_RECEIVE_WAP_PUSH = 19;
640     /** @hide */
641     @UnsupportedAppUsage
642     public static final int OP_SEND_SMS = 20;
643     /** @hide */
644     @UnsupportedAppUsage
645     public static final int OP_READ_ICC_SMS = 21;
646     /** @hide */
647     @UnsupportedAppUsage
648     public static final int OP_WRITE_ICC_SMS = 22;
649     /** @hide */
650     @UnsupportedAppUsage
651     public static final int OP_WRITE_SETTINGS = 23;
652     /** @hide Required to draw on top of other apps. */
653     @UnsupportedAppUsage
654     @TestApi
655     public static final int OP_SYSTEM_ALERT_WINDOW = 24;
656     /** @hide */
657     @UnsupportedAppUsage
658     public static final int OP_ACCESS_NOTIFICATIONS = 25;
659     /** @hide */
660     @UnsupportedAppUsage
661     public static final int OP_CAMERA = 26;
662     /** @hide */
663     @UnsupportedAppUsage
664     @TestApi
665     public static final int OP_RECORD_AUDIO = 27;
666     /** @hide */
667     @UnsupportedAppUsage
668     public static final int OP_PLAY_AUDIO = 28;
669     /** @hide */
670     @UnsupportedAppUsage
671     public static final int OP_READ_CLIPBOARD = 29;
672     /** @hide */
673     @UnsupportedAppUsage
674     public static final int OP_WRITE_CLIPBOARD = 30;
675     /** @hide */
676     @UnsupportedAppUsage
677     public static final int OP_TAKE_MEDIA_BUTTONS = 31;
678     /** @hide */
679     @UnsupportedAppUsage
680     public static final int OP_TAKE_AUDIO_FOCUS = 32;
681     /** @hide */
682     @UnsupportedAppUsage
683     public static final int OP_AUDIO_MASTER_VOLUME = 33;
684     /** @hide */
685     @UnsupportedAppUsage
686     public static final int OP_AUDIO_VOICE_VOLUME = 34;
687     /** @hide */
688     @UnsupportedAppUsage
689     public static final int OP_AUDIO_RING_VOLUME = 35;
690     /** @hide */
691     @UnsupportedAppUsage
692     public static final int OP_AUDIO_MEDIA_VOLUME = 36;
693     /** @hide */
694     @UnsupportedAppUsage
695     public static final int OP_AUDIO_ALARM_VOLUME = 37;
696     /** @hide */
697     @UnsupportedAppUsage
698     public static final int OP_AUDIO_NOTIFICATION_VOLUME = 38;
699     /** @hide */
700     @UnsupportedAppUsage
701     public static final int OP_AUDIO_BLUETOOTH_VOLUME = 39;
702     /** @hide */
703     @UnsupportedAppUsage
704     public static final int OP_WAKE_LOCK = 40;
705     /** @hide Continually monitoring location data. */
706     @UnsupportedAppUsage
707     public static final int OP_MONITOR_LOCATION = 41;
708     /** @hide Continually monitoring location data with a relatively high power request. */
709     @UnsupportedAppUsage
710     public static final int OP_MONITOR_HIGH_POWER_LOCATION = 42;
711     /** @hide Retrieve current usage stats via {@link UsageStatsManager}. */
712     @UnsupportedAppUsage
713     public static final int OP_GET_USAGE_STATS = 43;
714     /** @hide */
715     @UnsupportedAppUsage
716     public static final int OP_MUTE_MICROPHONE = 44;
717     /** @hide */
718     @UnsupportedAppUsage
719     public static final int OP_TOAST_WINDOW = 45;
720     /** @hide Capture the device's display contents and/or audio */
721     @UnsupportedAppUsage
722     public static final int OP_PROJECT_MEDIA = 46;
723 
724     /**
725      * Start (without additional user intervention) a VPN connection, as used by {@link
726      * android.net.VpnService} along with as Platform VPN connections, as used by {@link
727      * android.net.VpnManager}
728      *
729      * <p>This appop is granted to apps that have already been given user consent to start
730      * VpnService based VPN connections. As this is a superset of OP_ACTIVATE_PLATFORM_VPN, this
731      * appop also allows the starting of Platform VPNs.
732      *
733      * @hide
734      */
735     @UnsupportedAppUsage
736     public static final int OP_ACTIVATE_VPN = 47;
737     /** @hide Access the WallpaperManagerAPI to write wallpapers. */
738     @UnsupportedAppUsage
739     public static final int OP_WRITE_WALLPAPER = 48;
740     /** @hide Received the assist structure from an app. */
741     @UnsupportedAppUsage
742     public static final int OP_ASSIST_STRUCTURE = 49;
743     /** @hide Received a screenshot from assist. */
744     @UnsupportedAppUsage
745     public static final int OP_ASSIST_SCREENSHOT = 50;
746     /** @hide Read the phone state. */
747     @UnsupportedAppUsage
748     public static final int OP_READ_PHONE_STATE = 51;
749     /** @hide Add voicemail messages to the voicemail content provider. */
750     @UnsupportedAppUsage
751     public static final int OP_ADD_VOICEMAIL = 52;
752     /** @hide Access APIs for SIP calling over VOIP or WiFi. */
753     @UnsupportedAppUsage
754     public static final int OP_USE_SIP = 53;
755     /** @hide Intercept outgoing calls. */
756     @UnsupportedAppUsage
757     public static final int OP_PROCESS_OUTGOING_CALLS = 54;
758     /** @hide User the fingerprint API. */
759     @UnsupportedAppUsage
760     public static final int OP_USE_FINGERPRINT = 55;
761     /** @hide Access to body sensors such as heart rate, etc. */
762     @UnsupportedAppUsage
763     public static final int OP_BODY_SENSORS = 56;
764     /** @hide Read previously received cell broadcast messages. */
765     @UnsupportedAppUsage
766     public static final int OP_READ_CELL_BROADCASTS = 57;
767     /** @hide Inject mock location into the system. */
768     @UnsupportedAppUsage
769     public static final int OP_MOCK_LOCATION = 58;
770     /** @hide Read external storage. */
771     @UnsupportedAppUsage
772     public static final int OP_READ_EXTERNAL_STORAGE = 59;
773     /** @hide Write external storage. */
774     @UnsupportedAppUsage
775     public static final int OP_WRITE_EXTERNAL_STORAGE = 60;
776     /** @hide Turned on the screen. */
777     @UnsupportedAppUsage
778     public static final int OP_TURN_SCREEN_ON = 61;
779     /** @hide Get device accounts. */
780     @UnsupportedAppUsage
781     public static final int OP_GET_ACCOUNTS = 62;
782     /** @hide Control whether an application is allowed to run in the background. */
783     @UnsupportedAppUsage
784     public static final int OP_RUN_IN_BACKGROUND = 63;
785     /** @hide */
786     @UnsupportedAppUsage
787     public static final int OP_AUDIO_ACCESSIBILITY_VOLUME = 64;
788     /** @hide Read the phone number. */
789     @UnsupportedAppUsage
790     public static final int OP_READ_PHONE_NUMBERS = 65;
791     /** @hide Request package installs through package installer */
792     @UnsupportedAppUsage
793     public static final int OP_REQUEST_INSTALL_PACKAGES = 66;
794     /** @hide Enter picture-in-picture. */
795     @UnsupportedAppUsage
796     public static final int OP_PICTURE_IN_PICTURE = 67;
797     /** @hide Instant app start foreground service. */
798     @UnsupportedAppUsage
799     public static final int OP_INSTANT_APP_START_FOREGROUND = 68;
800     /** @hide Answer incoming phone calls */
801     @UnsupportedAppUsage
802     public static final int OP_ANSWER_PHONE_CALLS = 69;
803     /** @hide Run jobs when in background */
804     @UnsupportedAppUsage
805     public static final int OP_RUN_ANY_IN_BACKGROUND = 70;
806     /** @hide Change Wi-Fi connectivity state */
807     @UnsupportedAppUsage
808     public static final int OP_CHANGE_WIFI_STATE = 71;
809     /** @hide Request package deletion through package installer */
810     @UnsupportedAppUsage
811     public static final int OP_REQUEST_DELETE_PACKAGES = 72;
812     /** @hide Bind an accessibility service. */
813     @UnsupportedAppUsage
814     public static final int OP_BIND_ACCESSIBILITY_SERVICE = 73;
815     /** @hide Continue handover of a call from another app */
816     @UnsupportedAppUsage
817     public static final int OP_ACCEPT_HANDOVER = 74;
818     /** @hide Create and Manage IPsec Tunnels */
819     @UnsupportedAppUsage
820     public static final int OP_MANAGE_IPSEC_TUNNELS = 75;
821     /** @hide Any app start foreground service. */
822     @UnsupportedAppUsage
823     @TestApi
824     public static final int OP_START_FOREGROUND = 76;
825     /** @hide */
826     @UnsupportedAppUsage
827     public static final int OP_BLUETOOTH_SCAN = 77;
828     /** @hide Use the BiometricPrompt/BiometricManager APIs. */
829     public static final int OP_USE_BIOMETRIC = 78;
830     /** @hide Physical activity recognition. */
831     public static final int OP_ACTIVITY_RECOGNITION = 79;
832     /** @hide Financial app sms read. */
833     public static final int OP_SMS_FINANCIAL_TRANSACTIONS = 80;
834     /** @hide Read media of audio type. */
835     public static final int OP_READ_MEDIA_AUDIO = 81;
836     /** @hide Write media of audio type. */
837     public static final int OP_WRITE_MEDIA_AUDIO = 82;
838     /** @hide Read media of video type. */
839     public static final int OP_READ_MEDIA_VIDEO = 83;
840     /** @hide Write media of video type. */
841     public static final int OP_WRITE_MEDIA_VIDEO = 84;
842     /** @hide Read media of image type. */
843     public static final int OP_READ_MEDIA_IMAGES = 85;
844     /** @hide Write media of image type. */
845     public static final int OP_WRITE_MEDIA_IMAGES = 86;
846     /** @hide Has a legacy (non-isolated) view of storage. */
847     public static final int OP_LEGACY_STORAGE = 87;
848     /** @hide Accessing accessibility features */
849     public static final int OP_ACCESS_ACCESSIBILITY = 88;
850     /** @hide Read the device identifiers (IMEI / MEID, IMSI, SIM / Build serial) */
851     public static final int OP_READ_DEVICE_IDENTIFIERS = 89;
852     /** @hide Read location metadata from media */
853     public static final int OP_ACCESS_MEDIA_LOCATION = 90;
854     /**
855      * Start (without additional user intervention) a Platform VPN connection, as used by {@link
856      * android.net.VpnManager}
857      *
858      * <p>This appop is granted to apps that have already been given user consent to start Platform
859      * VPN connections. This appop is insufficient to start VpnService based VPNs (but the opposite
860      * is true).
861      *
862      * @hide
863      */
864     public static final int OP_ACTIVATE_PLATFORM_VPN = 91;
865 
866     /** @hide */
867     @UnsupportedAppUsage
868     public static final int _NUM_OP = 92;
869 
870     /** Access to coarse location information. */
871     public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
872     /** Access to fine location information. */
873     public static final String OPSTR_FINE_LOCATION =
874             "android:fine_location";
875     /** Continually monitoring location data. */
876     public static final String OPSTR_MONITOR_LOCATION
877             = "android:monitor_location";
878     /** Continually monitoring location data with a relatively high power request. */
879     public static final String OPSTR_MONITOR_HIGH_POWER_LOCATION
880             = "android:monitor_location_high_power";
881     /** Access to {@link android.app.usage.UsageStatsManager}. */
882     public static final String OPSTR_GET_USAGE_STATS
883             = "android:get_usage_stats";
884     /** Activate a VPN connection without user intervention. @hide */
885     @SystemApi @TestApi
886     public static final String OPSTR_ACTIVATE_VPN
887             = "android:activate_vpn";
888     /** Allows an application to read the user's contacts data. */
889     public static final String OPSTR_READ_CONTACTS
890             = "android:read_contacts";
891     /** Allows an application to write to the user's contacts data. */
892     public static final String OPSTR_WRITE_CONTACTS
893             = "android:write_contacts";
894     /** Allows an application to read the user's call log. */
895     public static final String OPSTR_READ_CALL_LOG
896             = "android:read_call_log";
897     /** Allows an application to write to the user's call log. */
898     public static final String OPSTR_WRITE_CALL_LOG
899             = "android:write_call_log";
900     /** Allows an application to read the user's calendar data. */
901     public static final String OPSTR_READ_CALENDAR
902             = "android:read_calendar";
903     /** Allows an application to write to the user's calendar data. */
904     public static final String OPSTR_WRITE_CALENDAR
905             = "android:write_calendar";
906     /** Allows an application to initiate a phone call. */
907     public static final String OPSTR_CALL_PHONE
908             = "android:call_phone";
909     /** Allows an application to read SMS messages. */
910     public static final String OPSTR_READ_SMS
911             = "android:read_sms";
912     /** Allows an application to receive SMS messages. */
913     public static final String OPSTR_RECEIVE_SMS
914             = "android:receive_sms";
915     /** Allows an application to receive MMS messages. */
916     public static final String OPSTR_RECEIVE_MMS
917             = "android:receive_mms";
918     /** Allows an application to receive WAP push messages. */
919     public static final String OPSTR_RECEIVE_WAP_PUSH
920             = "android:receive_wap_push";
921     /** Allows an application to send SMS messages. */
922     public static final String OPSTR_SEND_SMS
923             = "android:send_sms";
924     /** Required to be able to access the camera device. */
925     public static final String OPSTR_CAMERA
926             = "android:camera";
927     /** Required to be able to access the microphone device. */
928     public static final String OPSTR_RECORD_AUDIO
929             = "android:record_audio";
930     /** Required to access phone state related information. */
931     public static final String OPSTR_READ_PHONE_STATE
932             = "android:read_phone_state";
933     /** Required to access phone state related information. */
934     public static final String OPSTR_ADD_VOICEMAIL
935             = "android:add_voicemail";
936     /** Access APIs for SIP calling over VOIP or WiFi */
937     public static final String OPSTR_USE_SIP
938             = "android:use_sip";
939     /** Access APIs for diverting outgoing calls */
940     public static final String OPSTR_PROCESS_OUTGOING_CALLS
941             = "android:process_outgoing_calls";
942     /** Use the fingerprint API. */
943     public static final String OPSTR_USE_FINGERPRINT
944             = "android:use_fingerprint";
945     /** Access to body sensors such as heart rate, etc. */
946     public static final String OPSTR_BODY_SENSORS
947             = "android:body_sensors";
948     /** Read previously received cell broadcast messages. */
949     public static final String OPSTR_READ_CELL_BROADCASTS
950             = "android:read_cell_broadcasts";
951     /** Inject mock location into the system. */
952     public static final String OPSTR_MOCK_LOCATION
953             = "android:mock_location";
954     /** Read external storage. */
955     public static final String OPSTR_READ_EXTERNAL_STORAGE
956             = "android:read_external_storage";
957     /** Write external storage. */
958     public static final String OPSTR_WRITE_EXTERNAL_STORAGE
959             = "android:write_external_storage";
960     /** Required to draw on top of other apps. */
961     public static final String OPSTR_SYSTEM_ALERT_WINDOW
962             = "android:system_alert_window";
963     /** Required to write/modify/update system settingss. */
964     public static final String OPSTR_WRITE_SETTINGS
965             = "android:write_settings";
966     /** @hide Get device accounts. */
967     @SystemApi @TestApi
968     public static final String OPSTR_GET_ACCOUNTS
969             = "android:get_accounts";
970     public static final String OPSTR_READ_PHONE_NUMBERS
971             = "android:read_phone_numbers";
972     /** Access to picture-in-picture. */
973     public static final String OPSTR_PICTURE_IN_PICTURE
974             = "android:picture_in_picture";
975     /** @hide */
976     @SystemApi @TestApi
977     public static final String OPSTR_INSTANT_APP_START_FOREGROUND
978             = "android:instant_app_start_foreground";
979     /** Answer incoming phone calls */
980     public static final String OPSTR_ANSWER_PHONE_CALLS
981             = "android:answer_phone_calls";
982     /**
983      * Accept call handover
984      * @hide
985      */
986     @SystemApi @TestApi
987     public static final String OPSTR_ACCEPT_HANDOVER
988             = "android:accept_handover";
989     /** @hide */
990     @SystemApi @TestApi
991     public static final String OPSTR_GPS = "android:gps";
992     /** @hide */
993     @SystemApi @TestApi
994     public static final String OPSTR_VIBRATE = "android:vibrate";
995     /** @hide */
996     @SystemApi @TestApi
997     public static final String OPSTR_WIFI_SCAN = "android:wifi_scan";
998     /** @hide */
999     @SystemApi @TestApi
1000     public static final String OPSTR_POST_NOTIFICATION = "android:post_notification";
1001     /** @hide */
1002     @SystemApi @TestApi
1003     public static final String OPSTR_NEIGHBORING_CELLS = "android:neighboring_cells";
1004     /** @hide */
1005     @SystemApi @TestApi
1006     public static final String OPSTR_WRITE_SMS = "android:write_sms";
1007     /** @hide */
1008     @SystemApi @TestApi
1009     public static final String OPSTR_RECEIVE_EMERGENCY_BROADCAST =
1010             "android:receive_emergency_broadcast";
1011     /** @hide */
1012     @SystemApi @TestApi
1013     public static final String OPSTR_READ_ICC_SMS = "android:read_icc_sms";
1014     /** @hide */
1015     @SystemApi @TestApi
1016     public static final String OPSTR_WRITE_ICC_SMS = "android:write_icc_sms";
1017     /** @hide */
1018     @SystemApi @TestApi
1019     public static final String OPSTR_ACCESS_NOTIFICATIONS = "android:access_notifications";
1020     /** @hide */
1021     @SystemApi @TestApi
1022     public static final String OPSTR_PLAY_AUDIO = "android:play_audio";
1023     /** @hide */
1024     @SystemApi @TestApi
1025     public static final String OPSTR_READ_CLIPBOARD = "android:read_clipboard";
1026     /** @hide */
1027     @SystemApi @TestApi
1028     public static final String OPSTR_WRITE_CLIPBOARD = "android:write_clipboard";
1029     /** @hide */
1030     @SystemApi @TestApi
1031     public static final String OPSTR_TAKE_MEDIA_BUTTONS = "android:take_media_buttons";
1032     /** @hide */
1033     @SystemApi @TestApi
1034     public static final String OPSTR_TAKE_AUDIO_FOCUS = "android:take_audio_focus";
1035     /** @hide */
1036     @SystemApi @TestApi
1037     public static final String OPSTR_AUDIO_MASTER_VOLUME = "android:audio_master_volume";
1038     /** @hide */
1039     @SystemApi @TestApi
1040     public static final String OPSTR_AUDIO_VOICE_VOLUME = "android:audio_voice_volume";
1041     /** @hide */
1042     @SystemApi @TestApi
1043     public static final String OPSTR_AUDIO_RING_VOLUME = "android:audio_ring_volume";
1044     /** @hide */
1045     @SystemApi @TestApi
1046     public static final String OPSTR_AUDIO_MEDIA_VOLUME = "android:audio_media_volume";
1047     /** @hide */
1048     @SystemApi @TestApi
1049     public static final String OPSTR_AUDIO_ALARM_VOLUME = "android:audio_alarm_volume";
1050     /** @hide */
1051     @SystemApi @TestApi
1052     public static final String OPSTR_AUDIO_NOTIFICATION_VOLUME =
1053             "android:audio_notification_volume";
1054     /** @hide */
1055     @SystemApi @TestApi
1056     public static final String OPSTR_AUDIO_BLUETOOTH_VOLUME = "android:audio_bluetooth_volume";
1057     /** @hide */
1058     @SystemApi @TestApi
1059     public static final String OPSTR_WAKE_LOCK = "android:wake_lock";
1060     /** @hide */
1061     @SystemApi @TestApi
1062     public static final String OPSTR_MUTE_MICROPHONE = "android:mute_microphone";
1063     /** @hide */
1064     @SystemApi @TestApi
1065     public static final String OPSTR_TOAST_WINDOW = "android:toast_window";
1066     /** @hide */
1067     @SystemApi @TestApi
1068     public static final String OPSTR_PROJECT_MEDIA = "android:project_media";
1069     /** @hide */
1070     @SystemApi @TestApi
1071     public static final String OPSTR_WRITE_WALLPAPER = "android:write_wallpaper";
1072     /** @hide */
1073     @SystemApi @TestApi
1074     public static final String OPSTR_ASSIST_STRUCTURE = "android:assist_structure";
1075     /** @hide */
1076     @SystemApi @TestApi
1077     public static final String OPSTR_ASSIST_SCREENSHOT = "android:assist_screenshot";
1078     /** @hide */
1079     @SystemApi @TestApi
1080     public static final String OPSTR_TURN_SCREEN_ON = "android:turn_screen_on";
1081     /** @hide */
1082     @SystemApi @TestApi
1083     public static final String OPSTR_RUN_IN_BACKGROUND = "android:run_in_background";
1084     /** @hide */
1085     @SystemApi @TestApi
1086     public static final String OPSTR_AUDIO_ACCESSIBILITY_VOLUME =
1087             "android:audio_accessibility_volume";
1088     /** @hide */
1089     @SystemApi @TestApi
1090     public static final String OPSTR_REQUEST_INSTALL_PACKAGES = "android:request_install_packages";
1091     /** @hide */
1092     @SystemApi @TestApi
1093     public static final String OPSTR_RUN_ANY_IN_BACKGROUND = "android:run_any_in_background";
1094     /** @hide */
1095     @SystemApi @TestApi
1096     public static final String OPSTR_CHANGE_WIFI_STATE = "android:change_wifi_state";
1097     /** @hide */
1098     @SystemApi @TestApi
1099     public static final String OPSTR_REQUEST_DELETE_PACKAGES = "android:request_delete_packages";
1100     /** @hide */
1101     @SystemApi @TestApi
1102     public static final String OPSTR_BIND_ACCESSIBILITY_SERVICE =
1103             "android:bind_accessibility_service";
1104     /** @hide */
1105     @SystemApi @TestApi
1106     public static final String OPSTR_MANAGE_IPSEC_TUNNELS = "android:manage_ipsec_tunnels";
1107     /** @hide */
1108     @SystemApi @TestApi
1109     public static final String OPSTR_START_FOREGROUND = "android:start_foreground";
1110     /** @hide */
1111     public static final String OPSTR_BLUETOOTH_SCAN = "android:bluetooth_scan";
1112 
1113     /** @hide Use the BiometricPrompt/BiometricManager APIs. */
1114     public static final String OPSTR_USE_BIOMETRIC = "android:use_biometric";
1115 
1116     /** @hide Recognize physical activity. */
1117     public static final String OPSTR_ACTIVITY_RECOGNITION = "android:activity_recognition";
1118 
1119     /** @hide Financial app read sms. */
1120     public static final String OPSTR_SMS_FINANCIAL_TRANSACTIONS =
1121             "android:sms_financial_transactions";
1122 
1123     /** @hide Read media of audio type. */
1124     public static final String OPSTR_READ_MEDIA_AUDIO = "android:read_media_audio";
1125     /** @hide Write media of audio type. */
1126     public static final String OPSTR_WRITE_MEDIA_AUDIO = "android:write_media_audio";
1127     /** @hide Read media of video type. */
1128     public static final String OPSTR_READ_MEDIA_VIDEO = "android:read_media_video";
1129     /** @hide Write media of video type. */
1130     public static final String OPSTR_WRITE_MEDIA_VIDEO = "android:write_media_video";
1131     /** @hide Read media of image type. */
1132     public static final String OPSTR_READ_MEDIA_IMAGES = "android:read_media_images";
1133     /** @hide Write media of image type. */
1134     public static final String OPSTR_WRITE_MEDIA_IMAGES = "android:write_media_images";
1135     /** @hide Has a legacy (non-isolated) view of storage. */
1136     @TestApi
1137     @SystemApi
1138     public static final String OPSTR_LEGACY_STORAGE = "android:legacy_storage";
1139     /** @hide Read location metadata from media */
1140     public static final String OPSTR_ACCESS_MEDIA_LOCATION = "android:access_media_location";
1141 
1142     /** @hide Interact with accessibility. */
1143     @SystemApi
1144     public static final String OPSTR_ACCESS_ACCESSIBILITY = "android:access_accessibility";
1145     /** @hide Read device identifiers */
1146     public static final String OPSTR_READ_DEVICE_IDENTIFIERS = "android:read_device_identifiers";
1147     /** @hide Start Platform VPN without user intervention */
1148     public static final String OPSTR_ACTIVATE_PLATFORM_VPN = "android:activate_platform_vpn";
1149 
1150     // Warning: If an permission is added here it also has to be added to
1151     // com.android.packageinstaller.permission.utils.EventLogger
1152     private static final int[] RUNTIME_AND_APPOP_PERMISSIONS_OPS = {
1153             // RUNTIME PERMISSIONS
1154             // Contacts
1155             OP_READ_CONTACTS,
1156             OP_WRITE_CONTACTS,
1157             OP_GET_ACCOUNTS,
1158             // Calendar
1159             OP_READ_CALENDAR,
1160             OP_WRITE_CALENDAR,
1161             // SMS
1162             OP_SEND_SMS,
1163             OP_RECEIVE_SMS,
1164             OP_READ_SMS,
1165             OP_RECEIVE_WAP_PUSH,
1166             OP_RECEIVE_MMS,
1167             OP_READ_CELL_BROADCASTS,
1168             // Storage
1169             OP_READ_EXTERNAL_STORAGE,
1170             OP_WRITE_EXTERNAL_STORAGE,
1171             OP_ACCESS_MEDIA_LOCATION,
1172             // Location
1173             OP_COARSE_LOCATION,
1174             OP_FINE_LOCATION,
1175             // Phone
1176             OP_READ_PHONE_STATE,
1177             OP_READ_PHONE_NUMBERS,
1178             OP_CALL_PHONE,
1179             OP_READ_CALL_LOG,
1180             OP_WRITE_CALL_LOG,
1181             OP_ADD_VOICEMAIL,
1182             OP_USE_SIP,
1183             OP_PROCESS_OUTGOING_CALLS,
1184             OP_ANSWER_PHONE_CALLS,
1185             OP_ACCEPT_HANDOVER,
1186             // Microphone
1187             OP_RECORD_AUDIO,
1188             // Camera
1189             OP_CAMERA,
1190             // Body sensors
1191             OP_BODY_SENSORS,
1192             // Activity recognition
1193             OP_ACTIVITY_RECOGNITION,
1194             // Aural
1195             OP_READ_MEDIA_AUDIO,
1196             OP_WRITE_MEDIA_AUDIO,
1197             // Visual
1198             OP_READ_MEDIA_VIDEO,
1199             OP_WRITE_MEDIA_VIDEO,
1200             OP_READ_MEDIA_IMAGES,
1201             OP_WRITE_MEDIA_IMAGES,
1202 
1203             // APPOP PERMISSIONS
1204             OP_ACCESS_NOTIFICATIONS,
1205             OP_SYSTEM_ALERT_WINDOW,
1206             OP_WRITE_SETTINGS,
1207             OP_REQUEST_INSTALL_PACKAGES,
1208             OP_START_FOREGROUND,
1209             OP_SMS_FINANCIAL_TRANSACTIONS,
1210     };
1211 
1212     /**
1213      * This maps each operation to the operation that serves as the
1214      * switch to determine whether it is allowed.  Generally this is
1215      * a 1:1 mapping, but for some things (like location) that have
1216      * multiple low-level operations being tracked that should be
1217      * presented to the user as one switch then this can be used to
1218      * make them all controlled by the same single operation.
1219      */
1220     private static int[] sOpToSwitch = new int[] {
1221             OP_COARSE_LOCATION,                 // COARSE_LOCATION
1222             OP_COARSE_LOCATION,                 // FINE_LOCATION
1223             OP_COARSE_LOCATION,                 // GPS
1224             OP_VIBRATE,                         // VIBRATE
1225             OP_READ_CONTACTS,                   // READ_CONTACTS
1226             OP_WRITE_CONTACTS,                  // WRITE_CONTACTS
1227             OP_READ_CALL_LOG,                   // READ_CALL_LOG
1228             OP_WRITE_CALL_LOG,                  // WRITE_CALL_LOG
1229             OP_READ_CALENDAR,                   // READ_CALENDAR
1230             OP_WRITE_CALENDAR,                  // WRITE_CALENDAR
1231             OP_COARSE_LOCATION,                 // WIFI_SCAN
1232             OP_POST_NOTIFICATION,               // POST_NOTIFICATION
1233             OP_COARSE_LOCATION,                 // NEIGHBORING_CELLS
1234             OP_CALL_PHONE,                      // CALL_PHONE
1235             OP_READ_SMS,                        // READ_SMS
1236             OP_WRITE_SMS,                       // WRITE_SMS
1237             OP_RECEIVE_SMS,                     // RECEIVE_SMS
1238             OP_RECEIVE_SMS,                     // RECEIVE_EMERGECY_SMS
1239             OP_RECEIVE_MMS,                     // RECEIVE_MMS
1240             OP_RECEIVE_WAP_PUSH,                // RECEIVE_WAP_PUSH
1241             OP_SEND_SMS,                        // SEND_SMS
1242             OP_READ_SMS,                        // READ_ICC_SMS
1243             OP_WRITE_SMS,                       // WRITE_ICC_SMS
1244             OP_WRITE_SETTINGS,                  // WRITE_SETTINGS
1245             OP_SYSTEM_ALERT_WINDOW,             // SYSTEM_ALERT_WINDOW
1246             OP_ACCESS_NOTIFICATIONS,            // ACCESS_NOTIFICATIONS
1247             OP_CAMERA,                          // CAMERA
1248             OP_RECORD_AUDIO,                    // RECORD_AUDIO
1249             OP_PLAY_AUDIO,                      // PLAY_AUDIO
1250             OP_READ_CLIPBOARD,                  // READ_CLIPBOARD
1251             OP_WRITE_CLIPBOARD,                 // WRITE_CLIPBOARD
1252             OP_TAKE_MEDIA_BUTTONS,              // TAKE_MEDIA_BUTTONS
1253             OP_TAKE_AUDIO_FOCUS,                // TAKE_AUDIO_FOCUS
1254             OP_AUDIO_MASTER_VOLUME,             // AUDIO_MASTER_VOLUME
1255             OP_AUDIO_VOICE_VOLUME,              // AUDIO_VOICE_VOLUME
1256             OP_AUDIO_RING_VOLUME,               // AUDIO_RING_VOLUME
1257             OP_AUDIO_MEDIA_VOLUME,              // AUDIO_MEDIA_VOLUME
1258             OP_AUDIO_ALARM_VOLUME,              // AUDIO_ALARM_VOLUME
1259             OP_AUDIO_NOTIFICATION_VOLUME,       // AUDIO_NOTIFICATION_VOLUME
1260             OP_AUDIO_BLUETOOTH_VOLUME,          // AUDIO_BLUETOOTH_VOLUME
1261             OP_WAKE_LOCK,                       // WAKE_LOCK
1262             OP_COARSE_LOCATION,                 // MONITOR_LOCATION
1263             OP_COARSE_LOCATION,                 // MONITOR_HIGH_POWER_LOCATION
1264             OP_GET_USAGE_STATS,                 // GET_USAGE_STATS
1265             OP_MUTE_MICROPHONE,                 // MUTE_MICROPHONE
1266             OP_TOAST_WINDOW,                    // TOAST_WINDOW
1267             OP_PROJECT_MEDIA,                   // PROJECT_MEDIA
1268             OP_ACTIVATE_VPN,                    // ACTIVATE_VPN
1269             OP_WRITE_WALLPAPER,                 // WRITE_WALLPAPER
1270             OP_ASSIST_STRUCTURE,                // ASSIST_STRUCTURE
1271             OP_ASSIST_SCREENSHOT,               // ASSIST_SCREENSHOT
1272             OP_READ_PHONE_STATE,                // READ_PHONE_STATE
1273             OP_ADD_VOICEMAIL,                   // ADD_VOICEMAIL
1274             OP_USE_SIP,                         // USE_SIP
1275             OP_PROCESS_OUTGOING_CALLS,          // PROCESS_OUTGOING_CALLS
1276             OP_USE_FINGERPRINT,                 // USE_FINGERPRINT
1277             OP_BODY_SENSORS,                    // BODY_SENSORS
1278             OP_READ_CELL_BROADCASTS,            // READ_CELL_BROADCASTS
1279             OP_MOCK_LOCATION,                   // MOCK_LOCATION
1280             OP_READ_EXTERNAL_STORAGE,           // READ_EXTERNAL_STORAGE
1281             OP_WRITE_EXTERNAL_STORAGE,          // WRITE_EXTERNAL_STORAGE
1282             OP_TURN_SCREEN_ON,                  // TURN_SCREEN_ON
1283             OP_GET_ACCOUNTS,                    // GET_ACCOUNTS
1284             OP_RUN_IN_BACKGROUND,               // RUN_IN_BACKGROUND
1285             OP_AUDIO_ACCESSIBILITY_VOLUME,      // AUDIO_ACCESSIBILITY_VOLUME
1286             OP_READ_PHONE_NUMBERS,              // READ_PHONE_NUMBERS
1287             OP_REQUEST_INSTALL_PACKAGES,        // REQUEST_INSTALL_PACKAGES
1288             OP_PICTURE_IN_PICTURE,              // ENTER_PICTURE_IN_PICTURE_ON_HIDE
1289             OP_INSTANT_APP_START_FOREGROUND,    // INSTANT_APP_START_FOREGROUND
1290             OP_ANSWER_PHONE_CALLS,              // ANSWER_PHONE_CALLS
1291             OP_RUN_ANY_IN_BACKGROUND,           // OP_RUN_ANY_IN_BACKGROUND
1292             OP_CHANGE_WIFI_STATE,               // OP_CHANGE_WIFI_STATE
1293             OP_REQUEST_DELETE_PACKAGES,         // OP_REQUEST_DELETE_PACKAGES
1294             OP_BIND_ACCESSIBILITY_SERVICE,      // OP_BIND_ACCESSIBILITY_SERVICE
1295             OP_ACCEPT_HANDOVER,                 // ACCEPT_HANDOVER
1296             OP_MANAGE_IPSEC_TUNNELS,            // MANAGE_IPSEC_HANDOVERS
1297             OP_START_FOREGROUND,                // START_FOREGROUND
1298             OP_COARSE_LOCATION,                 // BLUETOOTH_SCAN
1299             OP_USE_BIOMETRIC,                   // BIOMETRIC
1300             OP_ACTIVITY_RECOGNITION,            // ACTIVITY_RECOGNITION
1301             OP_SMS_FINANCIAL_TRANSACTIONS,      // SMS_FINANCIAL_TRANSACTIONS
1302             OP_READ_MEDIA_AUDIO,                // READ_MEDIA_AUDIO
1303             OP_WRITE_MEDIA_AUDIO,               // WRITE_MEDIA_AUDIO
1304             OP_READ_MEDIA_VIDEO,                // READ_MEDIA_VIDEO
1305             OP_WRITE_MEDIA_VIDEO,               // WRITE_MEDIA_VIDEO
1306             OP_READ_MEDIA_IMAGES,               // READ_MEDIA_IMAGES
1307             OP_WRITE_MEDIA_IMAGES,              // WRITE_MEDIA_IMAGES
1308             OP_LEGACY_STORAGE,                  // LEGACY_STORAGE
1309             OP_ACCESS_ACCESSIBILITY,            // ACCESS_ACCESSIBILITY
1310             OP_READ_DEVICE_IDENTIFIERS,         // READ_DEVICE_IDENTIFIERS
1311             OP_ACCESS_MEDIA_LOCATION,           // ACCESS_MEDIA_LOCATION
1312             OP_ACTIVATE_PLATFORM_VPN,           // ACTIVATE_PLATFORM_VPN
1313     };
1314 
1315     /**
1316      * This maps each operation to the public string constant for it.
1317      */
1318     private static String[] sOpToString = new String[]{
1319             OPSTR_COARSE_LOCATION,
1320             OPSTR_FINE_LOCATION,
1321             OPSTR_GPS,
1322             OPSTR_VIBRATE,
1323             OPSTR_READ_CONTACTS,
1324             OPSTR_WRITE_CONTACTS,
1325             OPSTR_READ_CALL_LOG,
1326             OPSTR_WRITE_CALL_LOG,
1327             OPSTR_READ_CALENDAR,
1328             OPSTR_WRITE_CALENDAR,
1329             OPSTR_WIFI_SCAN,
1330             OPSTR_POST_NOTIFICATION,
1331             OPSTR_NEIGHBORING_CELLS,
1332             OPSTR_CALL_PHONE,
1333             OPSTR_READ_SMS,
1334             OPSTR_WRITE_SMS,
1335             OPSTR_RECEIVE_SMS,
1336             OPSTR_RECEIVE_EMERGENCY_BROADCAST,
1337             OPSTR_RECEIVE_MMS,
1338             OPSTR_RECEIVE_WAP_PUSH,
1339             OPSTR_SEND_SMS,
1340             OPSTR_READ_ICC_SMS,
1341             OPSTR_WRITE_ICC_SMS,
1342             OPSTR_WRITE_SETTINGS,
1343             OPSTR_SYSTEM_ALERT_WINDOW,
1344             OPSTR_ACCESS_NOTIFICATIONS,
1345             OPSTR_CAMERA,
1346             OPSTR_RECORD_AUDIO,
1347             OPSTR_PLAY_AUDIO,
1348             OPSTR_READ_CLIPBOARD,
1349             OPSTR_WRITE_CLIPBOARD,
1350             OPSTR_TAKE_MEDIA_BUTTONS,
1351             OPSTR_TAKE_AUDIO_FOCUS,
1352             OPSTR_AUDIO_MASTER_VOLUME,
1353             OPSTR_AUDIO_VOICE_VOLUME,
1354             OPSTR_AUDIO_RING_VOLUME,
1355             OPSTR_AUDIO_MEDIA_VOLUME,
1356             OPSTR_AUDIO_ALARM_VOLUME,
1357             OPSTR_AUDIO_NOTIFICATION_VOLUME,
1358             OPSTR_AUDIO_BLUETOOTH_VOLUME,
1359             OPSTR_WAKE_LOCK,
1360             OPSTR_MONITOR_LOCATION,
1361             OPSTR_MONITOR_HIGH_POWER_LOCATION,
1362             OPSTR_GET_USAGE_STATS,
1363             OPSTR_MUTE_MICROPHONE,
1364             OPSTR_TOAST_WINDOW,
1365             OPSTR_PROJECT_MEDIA,
1366             OPSTR_ACTIVATE_VPN,
1367             OPSTR_WRITE_WALLPAPER,
1368             OPSTR_ASSIST_STRUCTURE,
1369             OPSTR_ASSIST_SCREENSHOT,
1370             OPSTR_READ_PHONE_STATE,
1371             OPSTR_ADD_VOICEMAIL,
1372             OPSTR_USE_SIP,
1373             OPSTR_PROCESS_OUTGOING_CALLS,
1374             OPSTR_USE_FINGERPRINT,
1375             OPSTR_BODY_SENSORS,
1376             OPSTR_READ_CELL_BROADCASTS,
1377             OPSTR_MOCK_LOCATION,
1378             OPSTR_READ_EXTERNAL_STORAGE,
1379             OPSTR_WRITE_EXTERNAL_STORAGE,
1380             OPSTR_TURN_SCREEN_ON,
1381             OPSTR_GET_ACCOUNTS,
1382             OPSTR_RUN_IN_BACKGROUND,
1383             OPSTR_AUDIO_ACCESSIBILITY_VOLUME,
1384             OPSTR_READ_PHONE_NUMBERS,
1385             OPSTR_REQUEST_INSTALL_PACKAGES,
1386             OPSTR_PICTURE_IN_PICTURE,
1387             OPSTR_INSTANT_APP_START_FOREGROUND,
1388             OPSTR_ANSWER_PHONE_CALLS,
1389             OPSTR_RUN_ANY_IN_BACKGROUND,
1390             OPSTR_CHANGE_WIFI_STATE,
1391             OPSTR_REQUEST_DELETE_PACKAGES,
1392             OPSTR_BIND_ACCESSIBILITY_SERVICE,
1393             OPSTR_ACCEPT_HANDOVER,
1394             OPSTR_MANAGE_IPSEC_TUNNELS,
1395             OPSTR_START_FOREGROUND,
1396             OPSTR_BLUETOOTH_SCAN,
1397             OPSTR_USE_BIOMETRIC,
1398             OPSTR_ACTIVITY_RECOGNITION,
1399             OPSTR_SMS_FINANCIAL_TRANSACTIONS,
1400             OPSTR_READ_MEDIA_AUDIO,
1401             OPSTR_WRITE_MEDIA_AUDIO,
1402             OPSTR_READ_MEDIA_VIDEO,
1403             OPSTR_WRITE_MEDIA_VIDEO,
1404             OPSTR_READ_MEDIA_IMAGES,
1405             OPSTR_WRITE_MEDIA_IMAGES,
1406             OPSTR_LEGACY_STORAGE,
1407             OPSTR_ACCESS_ACCESSIBILITY,
1408             OPSTR_READ_DEVICE_IDENTIFIERS,
1409             OPSTR_ACCESS_MEDIA_LOCATION,
1410             OPSTR_ACTIVATE_PLATFORM_VPN,
1411     };
1412 
1413     /**
1414      * This provides a simple name for each operation to be used
1415      * in debug output.
1416      */
1417     private static String[] sOpNames = new String[] {
1418             "COARSE_LOCATION",
1419             "FINE_LOCATION",
1420             "GPS",
1421             "VIBRATE",
1422             "READ_CONTACTS",
1423             "WRITE_CONTACTS",
1424             "READ_CALL_LOG",
1425             "WRITE_CALL_LOG",
1426             "READ_CALENDAR",
1427             "WRITE_CALENDAR",
1428             "WIFI_SCAN",
1429             "POST_NOTIFICATION",
1430             "NEIGHBORING_CELLS",
1431             "CALL_PHONE",
1432             "READ_SMS",
1433             "WRITE_SMS",
1434             "RECEIVE_SMS",
1435             "RECEIVE_EMERGECY_SMS",
1436             "RECEIVE_MMS",
1437             "RECEIVE_WAP_PUSH",
1438             "SEND_SMS",
1439             "READ_ICC_SMS",
1440             "WRITE_ICC_SMS",
1441             "WRITE_SETTINGS",
1442             "SYSTEM_ALERT_WINDOW",
1443             "ACCESS_NOTIFICATIONS",
1444             "CAMERA",
1445             "RECORD_AUDIO",
1446             "PLAY_AUDIO",
1447             "READ_CLIPBOARD",
1448             "WRITE_CLIPBOARD",
1449             "TAKE_MEDIA_BUTTONS",
1450             "TAKE_AUDIO_FOCUS",
1451             "AUDIO_MASTER_VOLUME",
1452             "AUDIO_VOICE_VOLUME",
1453             "AUDIO_RING_VOLUME",
1454             "AUDIO_MEDIA_VOLUME",
1455             "AUDIO_ALARM_VOLUME",
1456             "AUDIO_NOTIFICATION_VOLUME",
1457             "AUDIO_BLUETOOTH_VOLUME",
1458             "WAKE_LOCK",
1459             "MONITOR_LOCATION",
1460             "MONITOR_HIGH_POWER_LOCATION",
1461             "GET_USAGE_STATS",
1462             "MUTE_MICROPHONE",
1463             "TOAST_WINDOW",
1464             "PROJECT_MEDIA",
1465             "ACTIVATE_VPN",
1466             "WRITE_WALLPAPER",
1467             "ASSIST_STRUCTURE",
1468             "ASSIST_SCREENSHOT",
1469             "READ_PHONE_STATE",
1470             "ADD_VOICEMAIL",
1471             "USE_SIP",
1472             "PROCESS_OUTGOING_CALLS",
1473             "USE_FINGERPRINT",
1474             "BODY_SENSORS",
1475             "READ_CELL_BROADCASTS",
1476             "MOCK_LOCATION",
1477             "READ_EXTERNAL_STORAGE",
1478             "WRITE_EXTERNAL_STORAGE",
1479             "TURN_ON_SCREEN",
1480             "GET_ACCOUNTS",
1481             "RUN_IN_BACKGROUND",
1482             "AUDIO_ACCESSIBILITY_VOLUME",
1483             "READ_PHONE_NUMBERS",
1484             "REQUEST_INSTALL_PACKAGES",
1485             "PICTURE_IN_PICTURE",
1486             "INSTANT_APP_START_FOREGROUND",
1487             "ANSWER_PHONE_CALLS",
1488             "RUN_ANY_IN_BACKGROUND",
1489             "CHANGE_WIFI_STATE",
1490             "REQUEST_DELETE_PACKAGES",
1491             "BIND_ACCESSIBILITY_SERVICE",
1492             "ACCEPT_HANDOVER",
1493             "MANAGE_IPSEC_TUNNELS",
1494             "START_FOREGROUND",
1495             "BLUETOOTH_SCAN",
1496             "USE_BIOMETRIC",
1497             "ACTIVITY_RECOGNITION",
1498             "SMS_FINANCIAL_TRANSACTIONS",
1499             "READ_MEDIA_AUDIO",
1500             "WRITE_MEDIA_AUDIO",
1501             "READ_MEDIA_VIDEO",
1502             "WRITE_MEDIA_VIDEO",
1503             "READ_MEDIA_IMAGES",
1504             "WRITE_MEDIA_IMAGES",
1505             "LEGACY_STORAGE",
1506             "ACCESS_ACCESSIBILITY",
1507             "READ_DEVICE_IDENTIFIERS",
1508             "ACCESS_MEDIA_LOCATION",
1509             "ACTIVATE_PLATFORM_VPN"
1510     };
1511 
1512     /**
1513      * This optionally maps a permission to an operation.  If there
1514      * is no permission associated with an operation, it is null.
1515      */
1516     @UnsupportedAppUsage
1517     private static String[] sOpPerms = new String[] {
1518             android.Manifest.permission.ACCESS_COARSE_LOCATION,
1519             android.Manifest.permission.ACCESS_FINE_LOCATION,
1520             null,
1521             android.Manifest.permission.VIBRATE,
1522             android.Manifest.permission.READ_CONTACTS,
1523             android.Manifest.permission.WRITE_CONTACTS,
1524             android.Manifest.permission.READ_CALL_LOG,
1525             android.Manifest.permission.WRITE_CALL_LOG,
1526             android.Manifest.permission.READ_CALENDAR,
1527             android.Manifest.permission.WRITE_CALENDAR,
1528             android.Manifest.permission.ACCESS_WIFI_STATE,
1529             null, // no permission required for notifications
1530             null, // neighboring cells shares the coarse location perm
1531             android.Manifest.permission.CALL_PHONE,
1532             android.Manifest.permission.READ_SMS,
1533             null, // no permission required for writing sms
1534             android.Manifest.permission.RECEIVE_SMS,
1535             android.Manifest.permission.RECEIVE_EMERGENCY_BROADCAST,
1536             android.Manifest.permission.RECEIVE_MMS,
1537             android.Manifest.permission.RECEIVE_WAP_PUSH,
1538             android.Manifest.permission.SEND_SMS,
1539             android.Manifest.permission.READ_SMS,
1540             null, // no permission required for writing icc sms
1541             android.Manifest.permission.WRITE_SETTINGS,
1542             android.Manifest.permission.SYSTEM_ALERT_WINDOW,
1543             android.Manifest.permission.ACCESS_NOTIFICATIONS,
1544             android.Manifest.permission.CAMERA,
1545             android.Manifest.permission.RECORD_AUDIO,
1546             null, // no permission for playing audio
1547             null, // no permission for reading clipboard
1548             null, // no permission for writing clipboard
1549             null, // no permission for taking media buttons
1550             null, // no permission for taking audio focus
1551             null, // no permission for changing master volume
1552             null, // no permission for changing voice volume
1553             null, // no permission for changing ring volume
1554             null, // no permission for changing media volume
1555             null, // no permission for changing alarm volume
1556             null, // no permission for changing notification volume
1557             null, // no permission for changing bluetooth volume
1558             android.Manifest.permission.WAKE_LOCK,
1559             null, // no permission for generic location monitoring
1560             null, // no permission for high power location monitoring
1561             android.Manifest.permission.PACKAGE_USAGE_STATS,
1562             null, // no permission for muting/unmuting microphone
1563             null, // no permission for displaying toasts
1564             null, // no permission for projecting media
1565             null, // no permission for activating vpn
1566             null, // no permission for supporting wallpaper
1567             null, // no permission for receiving assist structure
1568             null, // no permission for receiving assist screenshot
1569             Manifest.permission.READ_PHONE_STATE,
1570             Manifest.permission.ADD_VOICEMAIL,
1571             Manifest.permission.USE_SIP,
1572             Manifest.permission.PROCESS_OUTGOING_CALLS,
1573             Manifest.permission.USE_FINGERPRINT,
1574             Manifest.permission.BODY_SENSORS,
1575             Manifest.permission.READ_CELL_BROADCASTS,
1576             null,
1577             Manifest.permission.READ_EXTERNAL_STORAGE,
1578             Manifest.permission.WRITE_EXTERNAL_STORAGE,
1579             null, // no permission for turning the screen on
1580             Manifest.permission.GET_ACCOUNTS,
1581             null, // no permission for running in background
1582             null, // no permission for changing accessibility volume
1583             Manifest.permission.READ_PHONE_NUMBERS,
1584             Manifest.permission.REQUEST_INSTALL_PACKAGES,
1585             null, // no permission for entering picture-in-picture on hide
1586             Manifest.permission.INSTANT_APP_FOREGROUND_SERVICE,
1587             Manifest.permission.ANSWER_PHONE_CALLS,
1588             null, // no permission for OP_RUN_ANY_IN_BACKGROUND
1589             Manifest.permission.CHANGE_WIFI_STATE,
1590             Manifest.permission.REQUEST_DELETE_PACKAGES,
1591             Manifest.permission.BIND_ACCESSIBILITY_SERVICE,
1592             Manifest.permission.ACCEPT_HANDOVER,
1593             null, // no permission for OP_MANAGE_IPSEC_TUNNELS
1594             Manifest.permission.FOREGROUND_SERVICE,
1595             null, // no permission for OP_BLUETOOTH_SCAN
1596             Manifest.permission.USE_BIOMETRIC,
1597             Manifest.permission.ACTIVITY_RECOGNITION,
1598             Manifest.permission.SMS_FINANCIAL_TRANSACTIONS,
1599             null,
1600             null, // no permission for OP_WRITE_MEDIA_AUDIO
1601             null,
1602             null, // no permission for OP_WRITE_MEDIA_VIDEO
1603             null,
1604             null, // no permission for OP_WRITE_MEDIA_IMAGES
1605             null, // no permission for OP_LEGACY_STORAGE
1606             null, // no permission for OP_ACCESS_ACCESSIBILITY
1607             null, // no direct permission for OP_READ_DEVICE_IDENTIFIERS
1608             Manifest.permission.ACCESS_MEDIA_LOCATION,
1609             null, // no permission for OP_ACTIVATE_PLATFORM_VPN
1610     };
1611 
1612     /**
1613      * Specifies whether an Op should be restricted by a user restriction.
1614      * Each Op should be filled with a restriction string from UserManager or
1615      * null to specify it is not affected by any user restriction.
1616      */
1617     private static String[] sOpRestrictions = new String[] {
1618             UserManager.DISALLOW_SHARE_LOCATION, //COARSE_LOCATION
1619             UserManager.DISALLOW_SHARE_LOCATION, //FINE_LOCATION
1620             UserManager.DISALLOW_SHARE_LOCATION, //GPS
1621             null, //VIBRATE
1622             null, //READ_CONTACTS
1623             null, //WRITE_CONTACTS
1624             UserManager.DISALLOW_OUTGOING_CALLS, //READ_CALL_LOG
1625             UserManager.DISALLOW_OUTGOING_CALLS, //WRITE_CALL_LOG
1626             null, //READ_CALENDAR
1627             null, //WRITE_CALENDAR
1628             UserManager.DISALLOW_SHARE_LOCATION, //WIFI_SCAN
1629             null, //POST_NOTIFICATION
1630             null, //NEIGHBORING_CELLS
1631             null, //CALL_PHONE
1632             UserManager.DISALLOW_SMS, //READ_SMS
1633             UserManager.DISALLOW_SMS, //WRITE_SMS
1634             UserManager.DISALLOW_SMS, //RECEIVE_SMS
1635             null, //RECEIVE_EMERGENCY_SMS
1636             UserManager.DISALLOW_SMS, //RECEIVE_MMS
1637             null, //RECEIVE_WAP_PUSH
1638             UserManager.DISALLOW_SMS, //SEND_SMS
1639             UserManager.DISALLOW_SMS, //READ_ICC_SMS
1640             UserManager.DISALLOW_SMS, //WRITE_ICC_SMS
1641             null, //WRITE_SETTINGS
1642             UserManager.DISALLOW_CREATE_WINDOWS, //SYSTEM_ALERT_WINDOW
1643             null, //ACCESS_NOTIFICATIONS
1644             UserManager.DISALLOW_CAMERA, //CAMERA
1645             UserManager.DISALLOW_RECORD_AUDIO, //RECORD_AUDIO
1646             null, //PLAY_AUDIO
1647             null, //READ_CLIPBOARD
1648             null, //WRITE_CLIPBOARD
1649             null, //TAKE_MEDIA_BUTTONS
1650             null, //TAKE_AUDIO_FOCUS
1651             UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MASTER_VOLUME
1652             UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_VOICE_VOLUME
1653             UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_RING_VOLUME
1654             UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MEDIA_VOLUME
1655             UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ALARM_VOLUME
1656             UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_NOTIFICATION_VOLUME
1657             UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_BLUETOOTH_VOLUME
1658             null, //WAKE_LOCK
1659             UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_LOCATION
1660             UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_HIGH_POWER_LOCATION
1661             null, //GET_USAGE_STATS
1662             UserManager.DISALLOW_UNMUTE_MICROPHONE, // MUTE_MICROPHONE
1663             UserManager.DISALLOW_CREATE_WINDOWS, // TOAST_WINDOW
1664             null, //PROJECT_MEDIA
1665             null, // ACTIVATE_VPN
1666             UserManager.DISALLOW_WALLPAPER, // WRITE_WALLPAPER
1667             null, // ASSIST_STRUCTURE
1668             null, // ASSIST_SCREENSHOT
1669             null, // READ_PHONE_STATE
1670             null, // ADD_VOICEMAIL
1671             null, // USE_SIP
1672             null, // PROCESS_OUTGOING_CALLS
1673             null, // USE_FINGERPRINT
1674             null, // BODY_SENSORS
1675             null, // READ_CELL_BROADCASTS
1676             null, // MOCK_LOCATION
1677             null, // READ_EXTERNAL_STORAGE
1678             null, // WRITE_EXTERNAL_STORAGE
1679             null, // TURN_ON_SCREEN
1680             null, // GET_ACCOUNTS
1681             null, // RUN_IN_BACKGROUND
1682             UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ACCESSIBILITY_VOLUME
1683             null, // READ_PHONE_NUMBERS
1684             null, // REQUEST_INSTALL_PACKAGES
1685             null, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
1686             null, // INSTANT_APP_START_FOREGROUND
1687             null, // ANSWER_PHONE_CALLS
1688             null, // OP_RUN_ANY_IN_BACKGROUND
1689             null, // OP_CHANGE_WIFI_STATE
1690             null, // REQUEST_DELETE_PACKAGES
1691             null, // OP_BIND_ACCESSIBILITY_SERVICE
1692             null, // ACCEPT_HANDOVER
1693             null, // MANAGE_IPSEC_TUNNELS
1694             null, // START_FOREGROUND
1695             null, // maybe should be UserManager.DISALLOW_SHARE_LOCATION, //BLUETOOTH_SCAN
1696             null, // USE_BIOMETRIC
1697             null, // ACTIVITY_RECOGNITION
1698             UserManager.DISALLOW_SMS, // SMS_FINANCIAL_TRANSACTIONS
1699             null, // READ_MEDIA_AUDIO
1700             null, // WRITE_MEDIA_AUDIO
1701             null, // READ_MEDIA_VIDEO
1702             null, // WRITE_MEDIA_VIDEO
1703             null, // READ_MEDIA_IMAGES
1704             null, // WRITE_MEDIA_IMAGES
1705             null, // LEGACY_STORAGE
1706             null, // ACCESS_ACCESSIBILITY
1707             null, // READ_DEVICE_IDENTIFIERS
1708             null, // ACCESS_MEDIA_LOCATION
1709             null, // ACTIVATE_PLATFORM_VPN
1710     };
1711 
1712     /**
1713      * This specifies whether each option should allow the system
1714      * (and system ui) to bypass the user restriction when active.
1715      */
1716     private static boolean[] sOpAllowSystemRestrictionBypass = new boolean[] {
1717             true, //COARSE_LOCATION
1718             true, //FINE_LOCATION
1719             false, //GPS
1720             false, //VIBRATE
1721             false, //READ_CONTACTS
1722             false, //WRITE_CONTACTS
1723             false, //READ_CALL_LOG
1724             false, //WRITE_CALL_LOG
1725             false, //READ_CALENDAR
1726             false, //WRITE_CALENDAR
1727             true, //WIFI_SCAN
1728             false, //POST_NOTIFICATION
1729             false, //NEIGHBORING_CELLS
1730             false, //CALL_PHONE
1731             false, //READ_SMS
1732             false, //WRITE_SMS
1733             false, //RECEIVE_SMS
1734             false, //RECEIVE_EMERGECY_SMS
1735             false, //RECEIVE_MMS
1736             false, //RECEIVE_WAP_PUSH
1737             false, //SEND_SMS
1738             false, //READ_ICC_SMS
1739             false, //WRITE_ICC_SMS
1740             false, //WRITE_SETTINGS
1741             true, //SYSTEM_ALERT_WINDOW
1742             false, //ACCESS_NOTIFICATIONS
1743             false, //CAMERA
1744             false, //RECORD_AUDIO
1745             false, //PLAY_AUDIO
1746             false, //READ_CLIPBOARD
1747             false, //WRITE_CLIPBOARD
1748             false, //TAKE_MEDIA_BUTTONS
1749             false, //TAKE_AUDIO_FOCUS
1750             false, //AUDIO_MASTER_VOLUME
1751             false, //AUDIO_VOICE_VOLUME
1752             false, //AUDIO_RING_VOLUME
1753             false, //AUDIO_MEDIA_VOLUME
1754             false, //AUDIO_ALARM_VOLUME
1755             false, //AUDIO_NOTIFICATION_VOLUME
1756             false, //AUDIO_BLUETOOTH_VOLUME
1757             false, //WAKE_LOCK
1758             false, //MONITOR_LOCATION
1759             false, //MONITOR_HIGH_POWER_LOCATION
1760             false, //GET_USAGE_STATS
1761             false, //MUTE_MICROPHONE
1762             true, //TOAST_WINDOW
1763             false, //PROJECT_MEDIA
1764             false, //ACTIVATE_VPN
1765             false, //WALLPAPER
1766             false, //ASSIST_STRUCTURE
1767             false, //ASSIST_SCREENSHOT
1768             false, //READ_PHONE_STATE
1769             false, //ADD_VOICEMAIL
1770             false, // USE_SIP
1771             false, // PROCESS_OUTGOING_CALLS
1772             false, // USE_FINGERPRINT
1773             false, // BODY_SENSORS
1774             false, // READ_CELL_BROADCASTS
1775             false, // MOCK_LOCATION
1776             false, // READ_EXTERNAL_STORAGE
1777             false, // WRITE_EXTERNAL_STORAGE
1778             false, // TURN_ON_SCREEN
1779             false, // GET_ACCOUNTS
1780             false, // RUN_IN_BACKGROUND
1781             false, // AUDIO_ACCESSIBILITY_VOLUME
1782             false, // READ_PHONE_NUMBERS
1783             false, // REQUEST_INSTALL_PACKAGES
1784             false, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
1785             false, // INSTANT_APP_START_FOREGROUND
1786             false, // ANSWER_PHONE_CALLS
1787             false, // OP_RUN_ANY_IN_BACKGROUND
1788             false, // OP_CHANGE_WIFI_STATE
1789             false, // OP_REQUEST_DELETE_PACKAGES
1790             false, // OP_BIND_ACCESSIBILITY_SERVICE
1791             false, // ACCEPT_HANDOVER
1792             false, // MANAGE_IPSEC_HANDOVERS
1793             false, // START_FOREGROUND
1794             true, // BLUETOOTH_SCAN
1795             false, // USE_BIOMETRIC
1796             false, // ACTIVITY_RECOGNITION
1797             false, // SMS_FINANCIAL_TRANSACTIONS
1798             false, // READ_MEDIA_AUDIO
1799             false, // WRITE_MEDIA_AUDIO
1800             false, // READ_MEDIA_VIDEO
1801             false, // WRITE_MEDIA_VIDEO
1802             false, // READ_MEDIA_IMAGES
1803             false, // WRITE_MEDIA_IMAGES
1804             false, // LEGACY_STORAGE
1805             false, // ACCESS_ACCESSIBILITY
1806             false, // READ_DEVICE_IDENTIFIERS
1807             false, // ACCESS_MEDIA_LOCATION
1808             false, // ACTIVATE_PLATFORM_VPN
1809     };
1810 
1811     /**
1812      * This specifies the default mode for each operation.
1813      */
1814     private static int[] sOpDefaultMode = new int[] {
1815             AppOpsManager.MODE_ALLOWED, // COARSE_LOCATION
1816             AppOpsManager.MODE_ALLOWED, // FINE_LOCATION
1817             AppOpsManager.MODE_ALLOWED, // GPS
1818             AppOpsManager.MODE_ALLOWED, // VIBRATE
1819             AppOpsManager.MODE_ALLOWED, // READ_CONTACTS
1820             AppOpsManager.MODE_ALLOWED, // WRITE_CONTACTS
1821             AppOpsManager.MODE_ALLOWED, // READ_CALL_LOG
1822             AppOpsManager.MODE_ALLOWED, // WRITE_CALL_LOG
1823             AppOpsManager.MODE_ALLOWED, // READ_CALENDAR
1824             AppOpsManager.MODE_ALLOWED, // WRITE_CALENDAR
1825             AppOpsManager.MODE_ALLOWED, // WIFI_SCAN
1826             AppOpsManager.MODE_ALLOWED, // POST_NOTIFICATION
1827             AppOpsManager.MODE_ALLOWED, // NEIGHBORING_CELLS
1828             AppOpsManager.MODE_ALLOWED, // CALL_PHONE
1829             AppOpsManager.MODE_ALLOWED, // READ_SMS
1830             AppOpsManager.MODE_IGNORED, // WRITE_SMS
1831             AppOpsManager.MODE_ALLOWED, // RECEIVE_SMS
1832             AppOpsManager.MODE_ALLOWED, // RECEIVE_EMERGENCY_BROADCAST
1833             AppOpsManager.MODE_ALLOWED, // RECEIVE_MMS
1834             AppOpsManager.MODE_ALLOWED, // RECEIVE_WAP_PUSH
1835             AppOpsManager.MODE_ALLOWED, // SEND_SMS
1836             AppOpsManager.MODE_ALLOWED, // READ_ICC_SMS
1837             AppOpsManager.MODE_ALLOWED, // WRITE_ICC_SMS
1838             AppOpsManager.MODE_DEFAULT, // WRITE_SETTINGS
1839             getSystemAlertWindowDefault(), // SYSTEM_ALERT_WINDOW
1840             AppOpsManager.MODE_ALLOWED, // ACCESS_NOTIFICATIONS
1841             AppOpsManager.MODE_ALLOWED, // CAMERA
1842             AppOpsManager.MODE_ALLOWED, // RECORD_AUDIO
1843             AppOpsManager.MODE_ALLOWED, // PLAY_AUDIO
1844             AppOpsManager.MODE_ALLOWED, // READ_CLIPBOARD
1845             AppOpsManager.MODE_ALLOWED, // WRITE_CLIPBOARD
1846             AppOpsManager.MODE_ALLOWED, // TAKE_MEDIA_BUTTONS
1847             AppOpsManager.MODE_ALLOWED, // TAKE_AUDIO_FOCUS
1848             AppOpsManager.MODE_ALLOWED, // AUDIO_MASTER_VOLUME
1849             AppOpsManager.MODE_ALLOWED, // AUDIO_VOICE_VOLUME
1850             AppOpsManager.MODE_ALLOWED, // AUDIO_RING_VOLUME
1851             AppOpsManager.MODE_ALLOWED, // AUDIO_MEDIA_VOLUME
1852             AppOpsManager.MODE_ALLOWED, // AUDIO_ALARM_VOLUME
1853             AppOpsManager.MODE_ALLOWED, // AUDIO_NOTIFICATION_VOLUME
1854             AppOpsManager.MODE_ALLOWED, // AUDIO_BLUETOOTH_VOLUME
1855             AppOpsManager.MODE_ALLOWED, // WAKE_LOCK
1856             AppOpsManager.MODE_ALLOWED, // MONITOR_LOCATION
1857             AppOpsManager.MODE_ALLOWED, // MONITOR_HIGH_POWER_LOCATION
1858             AppOpsManager.MODE_DEFAULT, // GET_USAGE_STATS
1859             AppOpsManager.MODE_ALLOWED, // MUTE_MICROPHONE
1860             AppOpsManager.MODE_ALLOWED, // TOAST_WINDOW
1861             AppOpsManager.MODE_IGNORED, // PROJECT_MEDIA
1862             AppOpsManager.MODE_IGNORED, // ACTIVATE_VPN
1863             AppOpsManager.MODE_ALLOWED, // WRITE_WALLPAPER
1864             AppOpsManager.MODE_ALLOWED, // ASSIST_STRUCTURE
1865             AppOpsManager.MODE_ALLOWED, // ASSIST_SCREENSHOT
1866             AppOpsManager.MODE_ALLOWED, // READ_PHONE_STATE
1867             AppOpsManager.MODE_ALLOWED, // ADD_VOICEMAIL
1868             AppOpsManager.MODE_ALLOWED, // USE_SIP
1869             AppOpsManager.MODE_ALLOWED, // PROCESS_OUTGOING_CALLS
1870             AppOpsManager.MODE_ALLOWED, // USE_FINGERPRINT
1871             AppOpsManager.MODE_ALLOWED, // BODY_SENSORS
1872             AppOpsManager.MODE_ALLOWED, // READ_CELL_BROADCASTS
1873             AppOpsManager.MODE_ERRORED, // MOCK_LOCATION
1874             AppOpsManager.MODE_ALLOWED, // READ_EXTERNAL_STORAGE
1875             AppOpsManager.MODE_ALLOWED, // WRITE_EXTERNAL_STORAGE
1876             AppOpsManager.MODE_ALLOWED, // TURN_SCREEN_ON
1877             AppOpsManager.MODE_ALLOWED, // GET_ACCOUNTS
1878             AppOpsManager.MODE_ALLOWED, // RUN_IN_BACKGROUND
1879             AppOpsManager.MODE_ALLOWED, // AUDIO_ACCESSIBILITY_VOLUME
1880             AppOpsManager.MODE_ALLOWED, // READ_PHONE_NUMBERS
1881             AppOpsManager.MODE_DEFAULT, // REQUEST_INSTALL_PACKAGES
1882             AppOpsManager.MODE_ALLOWED, // PICTURE_IN_PICTURE
1883             AppOpsManager.MODE_DEFAULT, // INSTANT_APP_START_FOREGROUND
1884             AppOpsManager.MODE_ALLOWED, // ANSWER_PHONE_CALLS
1885             AppOpsManager.MODE_ALLOWED, // RUN_ANY_IN_BACKGROUND
1886             AppOpsManager.MODE_ALLOWED, // CHANGE_WIFI_STATE
1887             AppOpsManager.MODE_ALLOWED, // REQUEST_DELETE_PACKAGES
1888             AppOpsManager.MODE_ALLOWED, // BIND_ACCESSIBILITY_SERVICE
1889             AppOpsManager.MODE_ALLOWED, // ACCEPT_HANDOVER
1890             AppOpsManager.MODE_ERRORED, // MANAGE_IPSEC_TUNNELS
1891             AppOpsManager.MODE_ALLOWED, // START_FOREGROUND
1892             AppOpsManager.MODE_ALLOWED, // BLUETOOTH_SCAN
1893             AppOpsManager.MODE_ALLOWED, // USE_BIOMETRIC
1894             AppOpsManager.MODE_ALLOWED, // ACTIVITY_RECOGNITION
1895             AppOpsManager.MODE_DEFAULT, // SMS_FINANCIAL_TRANSACTIONS
1896             AppOpsManager.MODE_ALLOWED, // READ_MEDIA_AUDIO
1897             AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_AUDIO
1898             AppOpsManager.MODE_ALLOWED, // READ_MEDIA_VIDEO
1899             AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_VIDEO
1900             AppOpsManager.MODE_ALLOWED, // READ_MEDIA_IMAGES
1901             AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_IMAGES
1902             AppOpsManager.MODE_DEFAULT, // LEGACY_STORAGE
1903             AppOpsManager.MODE_ALLOWED, // ACCESS_ACCESSIBILITY
1904             AppOpsManager.MODE_ERRORED, // READ_DEVICE_IDENTIFIERS
1905             AppOpsManager.MODE_ALLOWED, // ALLOW_MEDIA_LOCATION
1906             AppOpsManager.MODE_IGNORED, // ACTIVATE_PLATFORM_VPN
1907     };
1908 
1909     /**
1910      * This specifies whether each option is allowed to be reset
1911      * when resetting all app preferences.  Disable reset for
1912      * app ops that are under strong control of some part of the
1913      * system (such as OP_WRITE_SMS, which should be allowed only
1914      * for whichever app is selected as the current SMS app).
1915      */
1916     private static boolean[] sOpDisableReset = new boolean[] {
1917             false, // COARSE_LOCATION
1918             false, // FINE_LOCATION
1919             false, // GPS
1920             false, // VIBRATE
1921             false, // READ_CONTACTS
1922             false, // WRITE_CONTACTS
1923             false, // READ_CALL_LOG
1924             false, // WRITE_CALL_LOG
1925             false, // READ_CALENDAR
1926             false, // WRITE_CALENDAR
1927             false, // WIFI_SCAN
1928             false, // POST_NOTIFICATION
1929             false, // NEIGHBORING_CELLS
1930             false, // CALL_PHONE
1931             true, // READ_SMS
1932             true, // WRITE_SMS
1933             true, // RECEIVE_SMS
1934             false, // RECEIVE_EMERGENCY_BROADCAST
1935             false, // RECEIVE_MMS
1936             true, // RECEIVE_WAP_PUSH
1937             true, // SEND_SMS
1938             false, // READ_ICC_SMS
1939             false, // WRITE_ICC_SMS
1940             false, // WRITE_SETTINGS
1941             false, // SYSTEM_ALERT_WINDOW
1942             false, // ACCESS_NOTIFICATIONS
1943             false, // CAMERA
1944             false, // RECORD_AUDIO
1945             false, // PLAY_AUDIO
1946             false, // READ_CLIPBOARD
1947             false, // WRITE_CLIPBOARD
1948             false, // TAKE_MEDIA_BUTTONS
1949             false, // TAKE_AUDIO_FOCUS
1950             false, // AUDIO_MASTER_VOLUME
1951             false, // AUDIO_VOICE_VOLUME
1952             false, // AUDIO_RING_VOLUME
1953             false, // AUDIO_MEDIA_VOLUME
1954             false, // AUDIO_ALARM_VOLUME
1955             false, // AUDIO_NOTIFICATION_VOLUME
1956             false, // AUDIO_BLUETOOTH_VOLUME
1957             false, // WAKE_LOCK
1958             false, // MONITOR_LOCATION
1959             false, // MONITOR_HIGH_POWER_LOCATION
1960             false, // GET_USAGE_STATS
1961             false, // MUTE_MICROPHONE
1962             false, // TOAST_WINDOW
1963             false, // PROJECT_MEDIA
1964             false, // ACTIVATE_VPN
1965             false, // WRITE_WALLPAPER
1966             false, // ASSIST_STRUCTURE
1967             false, // ASSIST_SCREENSHOT
1968             false, // READ_PHONE_STATE
1969             false, // ADD_VOICEMAIL
1970             false, // USE_SIP
1971             false, // PROCESS_OUTGOING_CALLS
1972             false, // USE_FINGERPRINT
1973             false, // BODY_SENSORS
1974             true, // READ_CELL_BROADCASTS
1975             false, // MOCK_LOCATION
1976             false, // READ_EXTERNAL_STORAGE
1977             false, // WRITE_EXTERNAL_STORAGE
1978             false, // TURN_SCREEN_ON
1979             false, // GET_ACCOUNTS
1980             false, // RUN_IN_BACKGROUND
1981             false, // AUDIO_ACCESSIBILITY_VOLUME
1982             false, // READ_PHONE_NUMBERS
1983             false, // REQUEST_INSTALL_PACKAGES
1984             false, // PICTURE_IN_PICTURE
1985             false, // INSTANT_APP_START_FOREGROUND
1986             false, // ANSWER_PHONE_CALLS
1987             false, // RUN_ANY_IN_BACKGROUND
1988             false, // CHANGE_WIFI_STATE
1989             false, // REQUEST_DELETE_PACKAGES
1990             false, // BIND_ACCESSIBILITY_SERVICE
1991             false, // ACCEPT_HANDOVER
1992             false, // MANAGE_IPSEC_TUNNELS
1993             false, // START_FOREGROUND
1994             false, // BLUETOOTH_SCAN
1995             false, // USE_BIOMETRIC
1996             false, // ACTIVITY_RECOGNITION
1997             false, // SMS_FINANCIAL_TRANSACTIONS
1998             false, // READ_MEDIA_AUDIO
1999             false, // WRITE_MEDIA_AUDIO
2000             false, // READ_MEDIA_VIDEO
2001             false, // WRITE_MEDIA_VIDEO
2002             false, // READ_MEDIA_IMAGES
2003             false, // WRITE_MEDIA_IMAGES
2004             false, // LEGACY_STORAGE
2005             false, // ACCESS_ACCESSIBILITY
2006             false, // READ_DEVICE_IDENTIFIERS
2007             false, // ACCESS_MEDIA_LOCATION
2008             false, // ACTIVATE_PLATFORM_VPN
2009     };
2010 
2011     /**
2012      * Mapping from an app op name to the app op code.
2013      */
2014     private static HashMap<String, Integer> sOpStrToOp = new HashMap<>();
2015 
2016     /**
2017      * Mapping from a permission to the corresponding app op.
2018      */
2019     private static HashMap<String, Integer> sPermToOp = new HashMap<>();
2020 
2021     static {
2022         if (sOpToSwitch.length != _NUM_OP) {
2023             throw new IllegalStateException("sOpToSwitch length " + sOpToSwitch.length
2024                     + " should be " + _NUM_OP);
2025         }
2026         if (sOpToString.length != _NUM_OP) {
2027             throw new IllegalStateException("sOpToString length " + sOpToString.length
2028                     + " should be " + _NUM_OP);
2029         }
2030         if (sOpNames.length != _NUM_OP) {
2031             throw new IllegalStateException("sOpNames length " + sOpNames.length
2032                     + " should be " + _NUM_OP);
2033         }
2034         if (sOpPerms.length != _NUM_OP) {
2035             throw new IllegalStateException("sOpPerms length " + sOpPerms.length
2036                     + " should be " + _NUM_OP);
2037         }
2038         if (sOpDefaultMode.length != _NUM_OP) {
2039             throw new IllegalStateException("sOpDefaultMode length " + sOpDefaultMode.length
2040                     + " should be " + _NUM_OP);
2041         }
2042         if (sOpDisableReset.length != _NUM_OP) {
2043             throw new IllegalStateException("sOpDisableReset length " + sOpDisableReset.length
2044                     + " should be " + _NUM_OP);
2045         }
2046         if (sOpRestrictions.length != _NUM_OP) {
2047             throw new IllegalStateException("sOpRestrictions length " + sOpRestrictions.length
2048                     + " should be " + _NUM_OP);
2049         }
2050         if (sOpAllowSystemRestrictionBypass.length != _NUM_OP) {
2051             throw new IllegalStateException("sOpAllowSYstemRestrictionsBypass length "
2052                     + sOpRestrictions.length + " should be " + _NUM_OP);
2053         }
2054         for (int i=0; i<_NUM_OP; i++) {
2055             if (sOpToString[i] != null) {
sOpStrToOp.put(sOpToString[i], i)2056                 sOpStrToOp.put(sOpToString[i], i);
2057             }
2058         }
2059         for (int op : RUNTIME_AND_APPOP_PERMISSIONS_OPS) {
2060             if (sOpPerms[op] != null) {
sPermToOp.put(sOpPerms[op], op)2061                 sPermToOp.put(sOpPerms[op], op);
2062             }
2063         }
2064     }
2065 
2066     /** @hide */
2067     public static final String KEY_HISTORICAL_OPS = "historical_ops";
2068 
2069     /** System properties for debug logging of noteOp call sites */
2070     private static final String DEBUG_LOGGING_ENABLE_PROP = "appops.logging_enabled";
2071     private static final String DEBUG_LOGGING_PACKAGES_PROP = "appops.logging_packages";
2072     private static final String DEBUG_LOGGING_OPS_PROP = "appops.logging_ops";
2073     private static final String DEBUG_LOGGING_TAG = "AppOpsManager";
2074 
2075     /**
2076      * Retrieve the op switch that controls the given operation.
2077      * @hide
2078      */
2079     @UnsupportedAppUsage
opToSwitch(int op)2080     public static int opToSwitch(int op) {
2081         return sOpToSwitch[op];
2082     }
2083 
2084     /**
2085      * Retrieve a non-localized name for the operation, for debugging output.
2086      * @hide
2087      */
2088     @UnsupportedAppUsage
opToName(int op)2089     public static String opToName(int op) {
2090         if (op == OP_NONE) return "NONE";
2091         return op < sOpNames.length ? sOpNames[op] : ("Unknown(" + op + ")");
2092     }
2093 
2094     /**
2095      * Retrieve a non-localized public name for the operation.
2096      *
2097      * @hide
2098      */
opToPublicName(int op)2099     public static @NonNull String opToPublicName(int op) {
2100         return sOpToString[op];
2101     }
2102 
2103     /**
2104      * @hide
2105      */
strDebugOpToOp(String op)2106     public static int strDebugOpToOp(String op) {
2107         for (int i=0; i<sOpNames.length; i++) {
2108             if (sOpNames[i].equals(op)) {
2109                 return i;
2110             }
2111         }
2112         throw new IllegalArgumentException("Unknown operation string: " + op);
2113     }
2114 
2115     /**
2116      * Retrieve the permission associated with an operation, or null if there is not one.
2117      * @hide
2118      */
2119     @UnsupportedAppUsage
2120     @TestApi
opToPermission(int op)2121     public static String opToPermission(int op) {
2122         return sOpPerms[op];
2123     }
2124 
2125     /**
2126      * Retrieve the permission associated with an operation, or null if there is not one.
2127      *
2128      * @param op The operation name.
2129      *
2130      * @hide
2131      */
2132     @Nullable
2133     @SystemApi
opToPermission(@onNull String op)2134     public static String opToPermission(@NonNull String op) {
2135         return opToPermission(strOpToOp(op));
2136     }
2137 
2138     /**
2139      * Retrieve the user restriction associated with an operation, or null if there is not one.
2140      * @hide
2141      */
opToRestriction(int op)2142     public static String opToRestriction(int op) {
2143         return sOpRestrictions[op];
2144     }
2145 
2146     /**
2147      * Retrieve the app op code for a permission, or null if there is not one.
2148      * This API is intended to be used for mapping runtime or appop permissions
2149      * to the corresponding app op.
2150      * @hide
2151      */
2152     @UnsupportedAppUsage
2153     @TestApi
permissionToOpCode(String permission)2154     public static int permissionToOpCode(String permission) {
2155         Integer boxedOpCode = sPermToOp.get(permission);
2156         return boxedOpCode != null ? boxedOpCode : OP_NONE;
2157     }
2158 
2159     /**
2160      * Retrieve whether the op allows the system (and system ui) to
2161      * bypass the user restriction.
2162      * @hide
2163      */
opAllowSystemBypassRestriction(int op)2164     public static boolean opAllowSystemBypassRestriction(int op) {
2165         return sOpAllowSystemRestrictionBypass[op];
2166     }
2167 
2168     /**
2169      * Retrieve the default mode for the operation.
2170      * @hide
2171      */
opToDefaultMode(int op)2172     public static @Mode int opToDefaultMode(int op) {
2173         return sOpDefaultMode[op];
2174     }
2175 
2176     /**
2177      * Retrieve the default mode for the app op.
2178      *
2179      * @param appOp The app op name
2180      *
2181      * @return the default mode for the app op
2182      *
2183      * @hide
2184      */
2185     @TestApi
2186     @SystemApi
opToDefaultMode(@onNull String appOp)2187     public static int opToDefaultMode(@NonNull String appOp) {
2188         return opToDefaultMode(strOpToOp(appOp));
2189     }
2190 
2191     /**
2192      * Retrieve the human readable mode.
2193      * @hide
2194      */
modeToName(@ode int mode)2195     public static String modeToName(@Mode int mode) {
2196         if (mode >= 0 && mode < MODE_NAMES.length) {
2197             return MODE_NAMES[mode];
2198         }
2199         return "mode=" + mode;
2200     }
2201 
2202     /**
2203      * Retrieve whether the op allows itself to be reset.
2204      * @hide
2205      */
opAllowsReset(int op)2206     public static boolean opAllowsReset(int op) {
2207         return !sOpDisableReset[op];
2208     }
2209 
2210     /**
2211      * Class holding all of the operation information associated with an app.
2212      * @hide
2213      */
2214     @SystemApi
2215     public static final class PackageOps implements Parcelable {
2216         private final String mPackageName;
2217         private final int mUid;
2218         private final List<OpEntry> mEntries;
2219 
2220         /**
2221          * @hide
2222          */
2223         @UnsupportedAppUsage
PackageOps(String packageName, int uid, List<OpEntry> entries)2224         public PackageOps(String packageName, int uid, List<OpEntry> entries) {
2225             mPackageName = packageName;
2226             mUid = uid;
2227             mEntries = entries;
2228         }
2229 
2230         /**
2231          * @return The name of the package.
2232          */
getPackageName()2233         public @NonNull String getPackageName() {
2234             return mPackageName;
2235         }
2236 
2237         /**
2238          * @return The uid of the package.
2239          */
getUid()2240         public int getUid() {
2241             return mUid;
2242         }
2243 
2244         /**
2245          * @return The ops of the package.
2246          */
getOps()2247         public @NonNull List<OpEntry> getOps() {
2248             return mEntries;
2249         }
2250 
2251         @Override
describeContents()2252         public int describeContents() {
2253             return 0;
2254         }
2255 
2256         @Override
writeToParcel(Parcel dest, int flags)2257         public void writeToParcel(Parcel dest, int flags) {
2258             dest.writeString(mPackageName);
2259             dest.writeInt(mUid);
2260             dest.writeInt(mEntries.size());
2261             for (int i=0; i<mEntries.size(); i++) {
2262                 mEntries.get(i).writeToParcel(dest, flags);
2263             }
2264         }
2265 
PackageOps(Parcel source)2266         PackageOps(Parcel source) {
2267             mPackageName = source.readString();
2268             mUid = source.readInt();
2269             mEntries = new ArrayList<OpEntry>();
2270             final int N = source.readInt();
2271             for (int i=0; i<N; i++) {
2272                 mEntries.add(OpEntry.CREATOR.createFromParcel(source));
2273             }
2274         }
2275 
2276         public static final @android.annotation.NonNull Creator<PackageOps> CREATOR = new Creator<PackageOps>() {
2277             @Override public PackageOps createFromParcel(Parcel source) {
2278                 return new PackageOps(source);
2279             }
2280 
2281             @Override public PackageOps[] newArray(int size) {
2282                 return new PackageOps[size];
2283             }
2284         };
2285     }
2286 
2287     /**
2288      * Class holding the information about one unique operation of an application.
2289      * @hide
2290      */
2291     @TestApi
2292     @Immutable
2293     @SystemApi
2294     public static final class OpEntry implements Parcelable {
2295         private final int mOp;
2296         private final boolean mRunning;
2297         private final @Mode int mMode;
2298         private final @Nullable LongSparseLongArray mAccessTimes;
2299         private final @Nullable LongSparseLongArray mRejectTimes;
2300         private final @Nullable LongSparseLongArray mDurations;
2301         private final @Nullable LongSparseLongArray mProxyUids;
2302         private final @Nullable LongSparseArray<String> mProxyPackageNames;
2303 
2304         /**
2305          * @hide
2306          */
OpEntry(int op, boolean running, @Mode int mode, @Nullable LongSparseLongArray accessTimes, @Nullable LongSparseLongArray rejectTimes, @Nullable LongSparseLongArray durations, @Nullable LongSparseLongArray proxyUids, @Nullable LongSparseArray<String> proxyPackageNames)2307         public OpEntry(int op, boolean running, @Mode int mode,
2308                 @Nullable LongSparseLongArray accessTimes, @Nullable LongSparseLongArray rejectTimes,
2309                 @Nullable LongSparseLongArray durations, @Nullable LongSparseLongArray proxyUids,
2310                 @Nullable LongSparseArray<String> proxyPackageNames) {
2311             mOp = op;
2312             mRunning = running;
2313             mMode = mode;
2314             mAccessTimes = accessTimes;
2315             mRejectTimes = rejectTimes;
2316             mDurations = durations;
2317             mProxyUids = proxyUids;
2318             mProxyPackageNames = proxyPackageNames;
2319         }
2320 
2321         /**
2322          * @hide
2323          */
OpEntry(int op, @Mode int mode)2324         public OpEntry(int op, @Mode int mode) {
2325             mOp = op;
2326             mMode = mode;
2327             mRunning = false;
2328             mAccessTimes = null;
2329             mRejectTimes = null;
2330             mDurations = null;
2331             mProxyUids = null;
2332             mProxyPackageNames = null;
2333         }
2334 
2335         /**
2336          * Returns all keys for which we have mapped state in any of the data buckets -
2337          * access time, reject time, duration.
2338          * @hide */
collectKeys()2339         public @Nullable LongSparseArray<Object> collectKeys() {
2340             LongSparseArray<Object> result = AppOpsManager.collectKeys(mAccessTimes, null);
2341             result = AppOpsManager.collectKeys(mRejectTimes, result);
2342             result = AppOpsManager.collectKeys(mDurations, result);
2343             return result;
2344         }
2345 
2346         /**
2347          * @hide
2348          */
2349         @UnsupportedAppUsage
getOp()2350         public int getOp() {
2351             return mOp;
2352         }
2353 
2354         /**
2355          * @return This entry's op string name, such as {@link #OPSTR_COARSE_LOCATION}.
2356          */
getOpStr()2357         public @NonNull String getOpStr() {
2358             return sOpToString[mOp];
2359         }
2360 
2361         /**
2362          * @return this entry's current mode, such as {@link #MODE_ALLOWED}.
2363          */
getMode()2364         public @Mode int getMode() {
2365             return mMode;
2366         }
2367 
2368         /**
2369          * @hide
2370          */
2371         @UnsupportedAppUsage
getTime()2372         public long getTime() {
2373             return getLastAccessTime(OP_FLAGS_ALL);
2374         }
2375 
2376         /**
2377          * Return the last wall clock time in milliseconds this op was accessed.
2378          *
2379          * @param flags The flags which are any combination of
2380          * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2381          * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2382          * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2383          * for any flag.
2384          * @return the last access time in milliseconds since
2385          * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2386          *
2387          * @see #getLastAccessForegroundTime(int)
2388          * @see #getLastAccessBackgroundTime(int)
2389          * @see #getLastAccessTime(int, int, int)
2390          */
getLastAccessTime(@pFlags int flags)2391         public long getLastAccessTime(@OpFlags int flags) {
2392             return maxForFlagsInStates(mAccessTimes, MAX_PRIORITY_UID_STATE,
2393                     MIN_PRIORITY_UID_STATE, flags);
2394         }
2395 
2396         /**
2397          * Return the last wall clock time in milliseconds this op was accessed
2398          * by the app while in the foreground.
2399          *
2400          * @param flags The flags which are any combination of
2401          * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2402          * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2403          * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2404          * for any flag.
2405          * @return the last foreground access time in milliseconds since
2406          * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2407          *
2408          * @see #getLastAccessBackgroundTime(int)
2409          * @see #getLastAccessTime(int)
2410          * @see #getLastAccessTime(int, int, int)
2411          */
getLastAccessForegroundTime(@pFlags int flags)2412         public long getLastAccessForegroundTime(@OpFlags int flags) {
2413             return maxForFlagsInStates(mAccessTimes, MAX_PRIORITY_UID_STATE,
2414                     resolveFirstUnrestrictedUidState(mOp), flags);
2415         }
2416 
2417         /**
2418          * Return the last wall clock time in milliseconds this op was accessed
2419          * by the app while in the background.
2420          *
2421          * @param flags The flags which are any combination of
2422          * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2423          * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2424          * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2425          * for any flag.
2426          * @return the last foreground access time in milliseconds since
2427          * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2428          *
2429          * @see #getLastAccessForegroundTime(int)
2430          * @see #getLastAccessTime(int)
2431          * @see #getLastAccessTime(int, int, int)
2432          */
getLastAccessBackgroundTime(@pFlags int flags)2433         public long getLastAccessBackgroundTime(@OpFlags int flags) {
2434             return maxForFlagsInStates(mAccessTimes, resolveLastRestrictedUidState(mOp),
2435                     MIN_PRIORITY_UID_STATE, flags);
2436         }
2437 
2438         /**
2439          * Return the last wall clock time  in milliseconds this op was accessed
2440          * by the app for a given range of UID states.
2441          *
2442          * @param fromUidState The UID state for which to query. Could be one of
2443          * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2444          * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2445          * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2446          * @param toUidState The UID state for which to query.
2447          * @param flags The flags which are any combination of
2448          * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2449          * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2450          * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2451          * for any flag.
2452          *
2453          * @return the last foreground access time in milliseconds since
2454          * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2455          *
2456          * @see #getLastAccessForegroundTime(int)
2457          * @see #getLastAccessBackgroundTime(int)
2458          * @see #getLastAccessTime(int)
2459          */
getLastAccessTime(@idState int fromUidState, @UidState int toUidState, @OpFlags int flags)2460         public long getLastAccessTime(@UidState int fromUidState, @UidState int toUidState,
2461                 @OpFlags int flags) {
2462             return maxForFlagsInStates(mAccessTimes, fromUidState, toUidState, flags);
2463         }
2464 
2465         /**
2466          * @hide
2467          */
2468         @UnsupportedAppUsage
getRejectTime()2469         public long getRejectTime() {
2470             return getLastRejectTime(OP_FLAGS_ALL);
2471         }
2472 
2473         /**
2474          * Return the last wall clock time in milliseconds the app made an attempt
2475          * to access this op but was rejected.
2476          *
2477          * @param flags The flags which are any combination of
2478          * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2479          * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2480          * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2481          * for any flag.
2482          * @return the last reject time in milliseconds since
2483          * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2484          *
2485          * @see #getLastRejectBackgroundTime(int)
2486          * @see #getLastRejectForegroundTime(int)
2487          * @see #getLastRejectTime(int, int, int)
2488          */
getLastRejectTime(@pFlags int flags)2489         public long getLastRejectTime(@OpFlags int flags) {
2490             return maxForFlagsInStates(mRejectTimes, MAX_PRIORITY_UID_STATE,
2491                     MIN_PRIORITY_UID_STATE, flags);
2492         }
2493 
2494         /**
2495          * Return the last wall clock time in milliseconds the app made an attempt
2496          * to access this op while in the foreground but was rejected.
2497          *
2498          * @param flags The flags which are any combination of
2499          * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2500          * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2501          * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2502          * for any flag.
2503          * @return the last foreground reject time in milliseconds since
2504          * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2505          *
2506          * @see #getLastRejectBackgroundTime(int)
2507          * @see #getLastRejectTime(int, int, int)
2508          * @see #getLastRejectTime(int)
2509          */
getLastRejectForegroundTime(@pFlags int flags)2510         public long getLastRejectForegroundTime(@OpFlags int flags) {
2511             return maxForFlagsInStates(mRejectTimes, MAX_PRIORITY_UID_STATE,
2512                     resolveFirstUnrestrictedUidState(mOp), flags);
2513         }
2514 
2515         /**
2516          * Return the last wall clock time in milliseconds the app made an attempt
2517          * to access this op while in the background but was rejected.
2518          *
2519          * @param flags The flags which are any combination of
2520          * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2521          * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2522          * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2523          * for any flag.
2524          * @return the last background reject time in milliseconds since
2525          * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2526          *
2527          * @see #getLastRejectForegroundTime(int)
2528          * @see #getLastRejectTime(int, int, int)
2529          * @see #getLastRejectTime(int)
2530          */
getLastRejectBackgroundTime(@pFlags int flags)2531         public long getLastRejectBackgroundTime(@OpFlags int flags) {
2532             return maxForFlagsInStates(mRejectTimes, resolveLastRestrictedUidState(mOp),
2533                     MIN_PRIORITY_UID_STATE, flags);
2534         }
2535 
2536         /**
2537          * Return the last wall clock time state in milliseconds the app made an
2538          * attempt to access this op for a given range of UID states.
2539          *
2540          * @param fromUidState The UID state from which to query. Could be one of
2541          * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2542          * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2543          * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2544          * @param toUidState The UID state to which to query.
2545          * @param flags The flags which are any combination of
2546          * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2547          * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2548          * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2549          * for any flag.
2550          * @return the last foreground access time in milliseconds since
2551          * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2552          *
2553          * @see #getLastRejectForegroundTime(int)
2554          * @see #getLastRejectBackgroundTime(int)
2555          * @see #getLastRejectTime(int)
2556          */
getLastRejectTime(@idState int fromUidState, @UidState int toUidState, @OpFlags int flags)2557         public long getLastRejectTime(@UidState int fromUidState, @UidState int toUidState,
2558                 @OpFlags int flags) {
2559             return maxForFlagsInStates(mRejectTimes, fromUidState, toUidState, flags);
2560         }
2561 
2562         /**
2563          * @return Whether the operation is running.
2564          */
isRunning()2565         public boolean isRunning() {
2566             return mRunning;
2567         }
2568 
2569         /**
2570          * @return The duration of the operation in milliseconds. The duration is in wall time.
2571          */
getDuration()2572         public long getDuration() {
2573             return getLastDuration(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
2574         }
2575 
2576         /**
2577          * Return the duration in milliseconds the app accessed this op while
2578          * in the foreground. The duration is in wall time.
2579          *
2580          * @param flags The flags which are any combination of
2581          * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2582          * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2583          * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2584          * for any flag.
2585          * @return the foreground access duration in milliseconds.
2586          *
2587          * @see #getLastBackgroundDuration(int)
2588          * @see #getLastDuration(int, int, int)
2589          */
getLastForegroundDuration(@pFlags int flags)2590         public long getLastForegroundDuration(@OpFlags int flags) {
2591             return sumForFlagsInStates(mDurations, MAX_PRIORITY_UID_STATE,
2592                     resolveFirstUnrestrictedUidState(mOp), flags);
2593         }
2594 
2595         /**
2596          * Return the duration in milliseconds the app accessed this op while
2597          * in the background. The duration is in wall time.
2598          *
2599          * @param flags The flags which are any combination of
2600          * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2601          * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2602          * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2603          * for any flag.
2604          * @return the background access duration in milliseconds.
2605          *
2606          * @see #getLastForegroundDuration(int)
2607          * @see #getLastDuration(int, int, int)
2608          */
getLastBackgroundDuration(@pFlags int flags)2609         public long getLastBackgroundDuration(@OpFlags int flags) {
2610             return sumForFlagsInStates(mDurations, resolveLastRestrictedUidState(mOp),
2611                     MIN_PRIORITY_UID_STATE, flags);
2612         }
2613 
2614         /**
2615          * Return the duration in milliseconds the app accessed this op for
2616          * a given range of UID states. The duration is in wall time.
2617          *
2618          * @param fromUidState The UID state for which to query. Could be one of
2619          * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2620          * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2621          * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2622          * @param toUidState The UID state for which to query.
2623          * @param flags The flags which are any combination of
2624          * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2625          * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2626          * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2627          * for any flag.
2628          * @return the access duration in milliseconds.
2629          */
getLastDuration(@idState int fromUidState, @UidState int toUidState, @OpFlags int flags)2630         public long getLastDuration(@UidState int fromUidState, @UidState int toUidState,
2631                 @OpFlags int flags) {
2632             return sumForFlagsInStates(mDurations, fromUidState, toUidState, flags);
2633         }
2634 
2635         /**
2636          * Gets the UID of the app that performed the op on behalf of this app and
2637          * as a result blamed the op on this app or {@link Process#INVALID_UID} if
2638          * there is no proxy.
2639          *
2640          * @return The proxy UID.
2641          */
getProxyUid()2642         public int getProxyUid() {
2643             return (int) findFirstNonNegativeForFlagsInStates(mProxyUids,
2644                     MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
2645         }
2646 
2647         /**
2648          * Gets the UID of the app that performed the op on behalf of this app and
2649          * as a result blamed the op on this app or {@link Process#INVALID_UID} if
2650          * there is no proxy.
2651          *
2652          * @param uidState The UID state for which to query. Could be one of
2653          * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2654          * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2655          * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2656          * @param flags The flags which are any combination of
2657          * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2658          * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2659          * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2660          * for any flag.
2661          *
2662          * @return The proxy UID.
2663          */
getProxyUid(@idState int uidState, @OpFlags int flags)2664         public int getProxyUid(@UidState int uidState, @OpFlags int flags) {
2665             return (int) findFirstNonNegativeForFlagsInStates(mProxyUids,
2666                     uidState, uidState, flags);
2667         }
2668 
2669         /**
2670          * Gets the package name of the app that performed the op on behalf of this
2671          * app and as a result blamed the op on this app or {@code null}
2672          * if there is no proxy.
2673          *
2674          * @return The proxy package name.
2675          */
getProxyPackageName()2676         public @Nullable String getProxyPackageName() {
2677             return findFirstNonNullForFlagsInStates(mProxyPackageNames, MAX_PRIORITY_UID_STATE,
2678                     MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
2679         }
2680 
2681         /**
2682          * Gets the package name of the app that performed the op on behalf of this
2683          * app and as a result blamed the op on this app for a UID state or
2684          * {@code null} if there is no proxy.
2685          *
2686          * @param uidState The UID state for which to query. Could be one of
2687          * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2688          * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2689          * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2690          * @param flags The flags which are any combination of
2691          * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2692          * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2693          * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2694          * for any flag.
2695          * @return The proxy package name.
2696          */
getProxyPackageName(@idState int uidState, @OpFlags int flags)2697         public @Nullable String getProxyPackageName(@UidState int uidState, @OpFlags int flags) {
2698             return findFirstNonNullForFlagsInStates(mProxyPackageNames, uidState, uidState, flags);
2699         }
2700 
2701         @Override
describeContents()2702         public int describeContents() {
2703             return 0;
2704         }
2705 
2706         @Override
writeToParcel(Parcel dest, int flags)2707         public void writeToParcel(Parcel dest, int flags) {
2708             dest.writeInt(mOp);
2709             dest.writeInt(mMode);
2710             dest.writeBoolean(mRunning);
2711             writeLongSparseLongArrayToParcel(mAccessTimes, dest);
2712             writeLongSparseLongArrayToParcel(mRejectTimes, dest);
2713             writeLongSparseLongArrayToParcel(mDurations, dest);
2714             writeLongSparseLongArrayToParcel(mProxyUids, dest);
2715             writeLongSparseStringArrayToParcel(mProxyPackageNames, dest);
2716         }
2717 
OpEntry(Parcel source)2718         OpEntry(Parcel source) {
2719             mOp = source.readInt();
2720             mMode = source.readInt();
2721             mRunning = source.readBoolean();
2722             mAccessTimes = readLongSparseLongArrayFromParcel(source);
2723             mRejectTimes = readLongSparseLongArrayFromParcel(source);
2724             mDurations = readLongSparseLongArrayFromParcel(source);
2725             mProxyUids = readLongSparseLongArrayFromParcel(source);
2726             mProxyPackageNames = readLongSparseStringArrayFromParcel(source);
2727         }
2728 
2729         public static final @android.annotation.NonNull Creator<OpEntry> CREATOR = new Creator<OpEntry>() {
2730             @Override public OpEntry createFromParcel(Parcel source) {
2731                 return new OpEntry(source);
2732             }
2733 
2734             @Override public OpEntry[] newArray(int size) {
2735                 return new OpEntry[size];
2736             }
2737         };
2738     }
2739 
2740     /** @hide */
2741     public interface HistoricalOpsVisitor {
visitHistoricalOps(@onNull HistoricalOps ops)2742         void visitHistoricalOps(@NonNull HistoricalOps ops);
visitHistoricalUidOps(@onNull HistoricalUidOps ops)2743         void visitHistoricalUidOps(@NonNull HistoricalUidOps ops);
visitHistoricalPackageOps(@onNull HistoricalPackageOps ops)2744         void visitHistoricalPackageOps(@NonNull HistoricalPackageOps ops);
visitHistoricalOp(@onNull HistoricalOp ops)2745         void visitHistoricalOp(@NonNull HistoricalOp ops);
2746     }
2747 
2748     /**
2749      * Request for getting historical app op usage. The request acts
2750      * as a filtering criteria when querying historical op usage.
2751      *
2752      * @hide
2753      */
2754     @Immutable
2755     @TestApi
2756     @SystemApi
2757     public static final class HistoricalOpsRequest {
2758         private final int mUid;
2759         private final @Nullable String mPackageName;
2760         private final @Nullable List<String> mOpNames;
2761         private final long mBeginTimeMillis;
2762         private final long mEndTimeMillis;
2763         private final @OpFlags int mFlags;
2764 
HistoricalOpsRequest(int uid, @Nullable String packageName, @Nullable List<String> opNames, long beginTimeMillis, long endTimeMillis, @OpFlags int flags)2765         private HistoricalOpsRequest(int uid, @Nullable String packageName,
2766                 @Nullable List<String> opNames, long beginTimeMillis, long endTimeMillis,
2767                 @OpFlags int flags) {
2768             mUid = uid;
2769             mPackageName = packageName;
2770             mOpNames = opNames;
2771             mBeginTimeMillis = beginTimeMillis;
2772             mEndTimeMillis = endTimeMillis;
2773             mFlags = flags;
2774         }
2775 
2776         /**
2777          * Builder for creating a {@link HistoricalOpsRequest}.
2778          *
2779          * @hide
2780          */
2781         @TestApi
2782         @SystemApi
2783         public static final class Builder {
2784             private int mUid = Process.INVALID_UID;
2785             private @Nullable String mPackageName;
2786             private @Nullable List<String> mOpNames;
2787             private final long mBeginTimeMillis;
2788             private final long mEndTimeMillis;
2789             private @OpFlags int mFlags = OP_FLAGS_ALL;
2790 
2791             /**
2792              * Creates a new builder.
2793              *
2794              * @param beginTimeMillis The beginning of the interval in milliseconds since
2795              *     epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). Must be non
2796              *     negative.
2797              * @param endTimeMillis The end of the interval in milliseconds since
2798              *     epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). Must be after
2799              *     {@code beginTimeMillis}. Pass {@link Long#MAX_VALUE} to get the most recent
2800              *     history including ops that happen while this call is in flight.
2801              */
Builder(long beginTimeMillis, long endTimeMillis)2802             public Builder(long beginTimeMillis, long endTimeMillis) {
2803                 Preconditions.checkArgument(beginTimeMillis >= 0 && beginTimeMillis < endTimeMillis,
2804                         "beginTimeMillis must be non negative and lesser than endTimeMillis");
2805                 mBeginTimeMillis = beginTimeMillis;
2806                 mEndTimeMillis = endTimeMillis;
2807             }
2808 
2809             /**
2810              * Sets the UID to query for.
2811              *
2812              * @param uid The uid. Pass {@link android.os.Process#INVALID_UID} for any uid.
2813              * @return This builder.
2814              */
setUid(int uid)2815             public @NonNull Builder setUid(int uid) {
2816                 Preconditions.checkArgument(uid == Process.INVALID_UID || uid >= 0,
2817                         "uid must be " + Process.INVALID_UID + " or non negative");
2818                 mUid = uid;
2819                 return this;
2820             }
2821 
2822             /**
2823              * Sets the package to query for.
2824              *
2825              * @param packageName The package name. <code>Null</code> for any package.
2826              * @return This builder.
2827              */
setPackageName(@ullable String packageName)2828             public @NonNull Builder setPackageName(@Nullable String packageName) {
2829                 mPackageName = packageName;
2830                 return this;
2831             }
2832 
2833             /**
2834              * Sets the op names to query for.
2835              *
2836              * @param opNames The op names. <code>Null</code> for any op.
2837              * @return This builder.
2838              */
setOpNames(@ullable List<String> opNames)2839             public @NonNull Builder setOpNames(@Nullable List<String> opNames) {
2840                 if (opNames != null) {
2841                     final int opCount = opNames.size();
2842                     for (int i = 0; i < opCount; i++) {
2843                         Preconditions.checkArgument(AppOpsManager.strOpToOp(
2844                                 opNames.get(i)) != AppOpsManager.OP_NONE);
2845                     }
2846                 }
2847                 mOpNames = opNames;
2848                 return this;
2849             }
2850 
2851             /**
2852              * Sets the op flags to query for. The flags specify the type of
2853              * op data being queried.
2854              *
2855              * @param flags The flags which are any combination of
2856              * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2857              * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2858              * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2859              * for any flag.
2860              * @return This builder.
2861              */
setFlags(@pFlags int flags)2862             public @NonNull Builder setFlags(@OpFlags int flags) {
2863                 Preconditions.checkFlagsArgument(flags, OP_FLAGS_ALL);
2864                 mFlags = flags;
2865                 return this;
2866             }
2867 
2868             /**
2869              * @return a new {@link HistoricalOpsRequest}.
2870              */
build()2871             public @NonNull HistoricalOpsRequest build() {
2872                 return new HistoricalOpsRequest(mUid, mPackageName, mOpNames,
2873                         mBeginTimeMillis, mEndTimeMillis, mFlags);
2874             }
2875         }
2876     }
2877 
2878     /**
2879      * This class represents historical app op state of all UIDs for a given time interval.
2880      *
2881      * @hide
2882      */
2883     @TestApi
2884     @SystemApi
2885     public static final class HistoricalOps implements Parcelable {
2886         private long mBeginTimeMillis;
2887         private long mEndTimeMillis;
2888         private @Nullable SparseArray<HistoricalUidOps> mHistoricalUidOps;
2889 
2890         /** @hide */
2891         @TestApi
HistoricalOps(long beginTimeMillis, long endTimeMillis)2892         public HistoricalOps(long beginTimeMillis, long endTimeMillis) {
2893             Preconditions.checkState(beginTimeMillis <= endTimeMillis);
2894             mBeginTimeMillis = beginTimeMillis;
2895             mEndTimeMillis = endTimeMillis;
2896         }
2897 
2898         /** @hide */
HistoricalOps(@onNull HistoricalOps other)2899         public HistoricalOps(@NonNull HistoricalOps other) {
2900             mBeginTimeMillis = other.mBeginTimeMillis;
2901             mEndTimeMillis = other.mEndTimeMillis;
2902             Preconditions.checkState(mBeginTimeMillis <= mEndTimeMillis);
2903             if (other.mHistoricalUidOps != null) {
2904                 final int opCount = other.getUidCount();
2905                 for (int i = 0; i < opCount; i++) {
2906                     final HistoricalUidOps origOps = other.getUidOpsAt(i);
2907                     final HistoricalUidOps clonedOps = new HistoricalUidOps(origOps);
2908                     if (mHistoricalUidOps == null) {
2909                         mHistoricalUidOps = new SparseArray<>(opCount);
2910                     }
2911                     mHistoricalUidOps.put(clonedOps.getUid(), clonedOps);
2912                 }
2913             }
2914         }
2915 
HistoricalOps(Parcel parcel)2916         private HistoricalOps(Parcel parcel) {
2917             mBeginTimeMillis = parcel.readLong();
2918             mEndTimeMillis = parcel.readLong();
2919             final int[] uids = parcel.createIntArray();
2920             if (!ArrayUtils.isEmpty(uids)) {
2921                 final ParceledListSlice<HistoricalUidOps> listSlice = parcel.readParcelable(
2922                         HistoricalOps.class.getClassLoader());
2923                 final List<HistoricalUidOps> uidOps = (listSlice != null)
2924                         ? listSlice.getList() : null;
2925                 if (uidOps == null) {
2926                     return;
2927                 }
2928                 for (int i = 0; i < uids.length; i++) {
2929                     if (mHistoricalUidOps == null) {
2930                         mHistoricalUidOps = new SparseArray<>();
2931                     }
2932                     mHistoricalUidOps.put(uids[i], uidOps.get(i));
2933                 }
2934             }
2935         }
2936 
2937         /**
2938          * Splice a piece from the beginning of these ops.
2939          *
2940          * @param splicePoint The fraction of the data to be spliced off.
2941          *
2942          * @hide
2943          */
spliceFromBeginning(double splicePoint)2944         public @NonNull HistoricalOps spliceFromBeginning(double splicePoint) {
2945             return splice(splicePoint, true);
2946         }
2947 
2948         /**
2949          * Splice a piece from the end of these ops.
2950          *
2951          * @param fractionToRemove The fraction of the data to be spliced off.
2952          *
2953          * @hide
2954          */
spliceFromEnd(double fractionToRemove)2955         public @NonNull HistoricalOps spliceFromEnd(double fractionToRemove) {
2956             return splice(fractionToRemove, false);
2957         }
2958 
2959         /**
2960          * Splice a piece from the beginning or end of these ops.
2961          *
2962          * @param fractionToRemove The fraction of the data to be spliced off.
2963          * @param beginning Whether to splice off the beginning or the end.
2964          *
2965          * @return The spliced off part.
2966          *
2967          * @hide
2968          */
splice(double fractionToRemove, boolean beginning)2969         private @Nullable HistoricalOps splice(double fractionToRemove, boolean beginning) {
2970             final long spliceBeginTimeMills;
2971             final long spliceEndTimeMills;
2972             if (beginning) {
2973                 spliceBeginTimeMills = mBeginTimeMillis;
2974                 spliceEndTimeMills = (long) (mBeginTimeMillis
2975                         + getDurationMillis() * fractionToRemove);
2976                 mBeginTimeMillis = spliceEndTimeMills;
2977             } else {
2978                 spliceBeginTimeMills = (long) (mEndTimeMillis
2979                         - getDurationMillis() * fractionToRemove);
2980                 spliceEndTimeMills = mEndTimeMillis;
2981                 mEndTimeMillis = spliceBeginTimeMills;
2982             }
2983 
2984             HistoricalOps splice = null;
2985             final int uidCount = getUidCount();
2986             for (int i = 0; i < uidCount; i++) {
2987                 final HistoricalUidOps origOps = getUidOpsAt(i);
2988                 final HistoricalUidOps spliceOps = origOps.splice(fractionToRemove);
2989                 if (spliceOps != null) {
2990                     if (splice == null) {
2991                         splice = new HistoricalOps(spliceBeginTimeMills, spliceEndTimeMills);
2992                     }
2993                     if (splice.mHistoricalUidOps == null) {
2994                         splice.mHistoricalUidOps = new SparseArray<>();
2995                     }
2996                     splice.mHistoricalUidOps.put(spliceOps.getUid(), spliceOps);
2997                 }
2998             }
2999             return splice;
3000         }
3001 
3002         /**
3003          * Merge the passed ops into the current ones. The time interval is a
3004          * union of the current and passed in one and the passed in data is
3005          * folded into the data of this instance.
3006          *
3007          * @hide
3008          */
merge(@onNull HistoricalOps other)3009         public void merge(@NonNull HistoricalOps other) {
3010             mBeginTimeMillis = Math.min(mBeginTimeMillis, other.mBeginTimeMillis);
3011             mEndTimeMillis = Math.max(mEndTimeMillis, other.mEndTimeMillis);
3012             final int uidCount = other.getUidCount();
3013             for (int i = 0; i < uidCount; i++) {
3014                 final HistoricalUidOps otherUidOps = other.getUidOpsAt(i);
3015                 final HistoricalUidOps thisUidOps = getUidOps(otherUidOps.getUid());
3016                 if (thisUidOps != null) {
3017                     thisUidOps.merge(otherUidOps);
3018                 } else {
3019                     if (mHistoricalUidOps == null) {
3020                         mHistoricalUidOps = new SparseArray<>();
3021                     }
3022                     mHistoricalUidOps.put(otherUidOps.getUid(), otherUidOps);
3023                 }
3024             }
3025         }
3026 
3027         /**
3028          * AppPermissionUsage the ops to leave only the data we filter for.
3029          *
3030          * @param uid Uid to filter for or {@link android.os.Process#INCIDENTD_UID} for all.
3031          * @param packageName Package to filter for or null for all.
3032          * @param opNames Ops to filter for or null for all.
3033          * @param beginTimeMillis The begin time to filter for or {@link Long#MIN_VALUE} for all.
3034          * @param endTimeMillis The end time to filter for or {@link Long#MAX_VALUE} for all.
3035          *
3036          * @hide
3037          */
filter(int uid, @Nullable String packageName, @Nullable String[] opNames, long beginTimeMillis, long endTimeMillis)3038         public void filter(int uid, @Nullable String packageName, @Nullable String[] opNames,
3039                 long beginTimeMillis, long endTimeMillis) {
3040             final long durationMillis = getDurationMillis();
3041             mBeginTimeMillis = Math.max(mBeginTimeMillis, beginTimeMillis);
3042             mEndTimeMillis = Math.min(mEndTimeMillis, endTimeMillis);
3043             final double scaleFactor = Math.min((double) (endTimeMillis - beginTimeMillis)
3044                     / (double) durationMillis, 1);
3045             final int uidCount = getUidCount();
3046             for (int i = uidCount - 1; i >= 0; i--) {
3047                 final HistoricalUidOps uidOp = mHistoricalUidOps.valueAt(i);
3048                 if (uid != Process.INVALID_UID && uid != uidOp.getUid()) {
3049                     mHistoricalUidOps.removeAt(i);
3050                 } else {
3051                     uidOp.filter(packageName, opNames, scaleFactor);
3052                 }
3053             }
3054         }
3055 
3056         /** @hide */
isEmpty()3057         public boolean isEmpty() {
3058             if (getBeginTimeMillis() >= getEndTimeMillis()) {
3059                 return true;
3060             }
3061             final int uidCount = getUidCount();
3062             for (int i = uidCount - 1; i >= 0; i--) {
3063                 final HistoricalUidOps uidOp = mHistoricalUidOps.valueAt(i);
3064                 if (!uidOp.isEmpty()) {
3065                     return false;
3066                 }
3067             }
3068             return true;
3069         }
3070 
3071         /** @hide */
getDurationMillis()3072         public long getDurationMillis() {
3073             return mEndTimeMillis - mBeginTimeMillis;
3074         }
3075 
3076         /** @hide */
3077         @TestApi
increaseAccessCount(int opCode, int uid, @NonNull String packageName, @UidState int uidState, @OpFlags int flags, long increment)3078         public void increaseAccessCount(int opCode, int uid, @NonNull String packageName,
3079                 @UidState int uidState,  @OpFlags int flags, long increment) {
3080             getOrCreateHistoricalUidOps(uid).increaseAccessCount(opCode,
3081                     packageName, uidState, flags, increment);
3082         }
3083 
3084         /** @hide */
3085         @TestApi
increaseRejectCount(int opCode, int uid, @NonNull String packageName, @UidState int uidState, @OpFlags int flags, long increment)3086         public void increaseRejectCount(int opCode, int uid, @NonNull String packageName,
3087                 @UidState int uidState, @OpFlags int flags, long increment) {
3088             getOrCreateHistoricalUidOps(uid).increaseRejectCount(opCode,
3089                     packageName, uidState, flags, increment);
3090         }
3091 
3092         /** @hide */
3093         @TestApi
increaseAccessDuration(int opCode, int uid, @NonNull String packageName, @UidState int uidState, @OpFlags int flags, long increment)3094         public void increaseAccessDuration(int opCode, int uid, @NonNull String packageName,
3095                 @UidState int uidState, @OpFlags int flags, long increment) {
3096             getOrCreateHistoricalUidOps(uid).increaseAccessDuration(opCode,
3097                     packageName, uidState, flags, increment);
3098         }
3099 
3100         /** @hide */
3101         @TestApi
offsetBeginAndEndTime(long offsetMillis)3102         public void offsetBeginAndEndTime(long offsetMillis) {
3103             mBeginTimeMillis += offsetMillis;
3104             mEndTimeMillis += offsetMillis;
3105         }
3106 
3107         /** @hide */
setBeginAndEndTime(long beginTimeMillis, long endTimeMillis)3108         public void setBeginAndEndTime(long beginTimeMillis, long endTimeMillis) {
3109             mBeginTimeMillis = beginTimeMillis;
3110             mEndTimeMillis = endTimeMillis;
3111         }
3112 
3113         /** @hide */
setBeginTime(long beginTimeMillis)3114         public void setBeginTime(long beginTimeMillis) {
3115             mBeginTimeMillis = beginTimeMillis;
3116         }
3117 
3118         /** @hide */
setEndTime(long endTimeMillis)3119         public void setEndTime(long endTimeMillis) {
3120             mEndTimeMillis = endTimeMillis;
3121         }
3122 
3123         /**
3124          * @return The beginning of the interval in milliseconds since
3125          *    epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
3126          */
getBeginTimeMillis()3127         public long getBeginTimeMillis() {
3128             return mBeginTimeMillis;
3129         }
3130 
3131         /**
3132          * @return The end of the interval in milliseconds since
3133          *    epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
3134          */
getEndTimeMillis()3135         public long getEndTimeMillis() {
3136             return mEndTimeMillis;
3137         }
3138 
3139         /**
3140          * Gets number of UIDs with historical ops.
3141          *
3142          * @return The number of UIDs with historical ops.
3143          *
3144          * @see #getUidOpsAt(int)
3145          */
getUidCount()3146         public @IntRange(from = 0) int getUidCount() {
3147             if (mHistoricalUidOps == null) {
3148                 return 0;
3149             }
3150             return mHistoricalUidOps.size();
3151         }
3152 
3153         /**
3154          * Gets the historical UID ops at a given index.
3155          *
3156          * @param index The index.
3157          *
3158          * @return The historical UID ops at the given index.
3159          *
3160          * @see #getUidCount()
3161          */
getUidOpsAt(@ntRangefrom = 0) int index)3162         public @NonNull HistoricalUidOps getUidOpsAt(@IntRange(from = 0) int index) {
3163             if (mHistoricalUidOps == null) {
3164                 throw new IndexOutOfBoundsException();
3165             }
3166             return mHistoricalUidOps.valueAt(index);
3167         }
3168 
3169         /**
3170          * Gets the historical UID ops for a given UID.
3171          *
3172          * @param uid The UID.
3173          *
3174          * @return The historical ops for the UID.
3175          */
getUidOps(int uid)3176         public @Nullable HistoricalUidOps getUidOps(int uid) {
3177             if (mHistoricalUidOps == null) {
3178                 return null;
3179             }
3180             return mHistoricalUidOps.get(uid);
3181         }
3182 
3183         /** @hide */
clearHistory(int uid, @NonNull String packageName)3184         public void clearHistory(int uid, @NonNull String packageName) {
3185             HistoricalUidOps historicalUidOps = getOrCreateHistoricalUidOps(uid);
3186             historicalUidOps.clearHistory(packageName);
3187             if (historicalUidOps.isEmpty()) {
3188                 mHistoricalUidOps.remove(uid);
3189             }
3190         }
3191 
3192         @Override
describeContents()3193         public int describeContents() {
3194             return 0;
3195         }
3196 
3197         @Override
writeToParcel(Parcel parcel, int flags)3198         public void writeToParcel(Parcel parcel, int flags) {
3199             parcel.writeLong(mBeginTimeMillis);
3200             parcel.writeLong(mEndTimeMillis);
3201             if (mHistoricalUidOps != null) {
3202                 final int uidCount = mHistoricalUidOps.size();
3203                 parcel.writeInt(uidCount);
3204                 for (int i = 0; i < uidCount; i++) {
3205                     parcel.writeInt(mHistoricalUidOps.keyAt(i));
3206                 }
3207                 final List<HistoricalUidOps> opsList = new ArrayList<>(uidCount);
3208                 for (int i = 0; i < uidCount; i++) {
3209                     opsList.add(mHistoricalUidOps.valueAt(i));
3210                 }
3211                 parcel.writeParcelable(new ParceledListSlice<>(opsList), flags);
3212             } else {
3213                 parcel.writeInt(-1);
3214             }
3215         }
3216 
3217         /**
3218          * Accepts a visitor to traverse the ops tree.
3219          *
3220          * @param visitor The visitor.
3221          *
3222          * @hide
3223          */
accept(@onNull HistoricalOpsVisitor visitor)3224         public void accept(@NonNull HistoricalOpsVisitor visitor) {
3225             visitor.visitHistoricalOps(this);
3226             final int uidCount = getUidCount();
3227             for (int i = 0; i < uidCount; i++) {
3228                 getUidOpsAt(i).accept(visitor);
3229             }
3230         }
3231 
getOrCreateHistoricalUidOps(int uid)3232         private @NonNull HistoricalUidOps getOrCreateHistoricalUidOps(int uid) {
3233             if (mHistoricalUidOps == null) {
3234                 mHistoricalUidOps = new SparseArray<>();
3235             }
3236             HistoricalUidOps historicalUidOp = mHistoricalUidOps.get(uid);
3237             if (historicalUidOp == null) {
3238                 historicalUidOp = new HistoricalUidOps(uid);
3239                 mHistoricalUidOps.put(uid, historicalUidOp);
3240             }
3241             return historicalUidOp;
3242         }
3243 
3244         /**
3245          * @return Rounded value up at the 0.5 boundary.
3246          *
3247          * @hide
3248          */
round(double value)3249         public static double round(double value) {
3250             final BigDecimal decimalScale = new BigDecimal(value);
3251             return decimalScale.setScale(0, RoundingMode.HALF_UP).doubleValue();
3252         }
3253 
3254         @Override
equals(@ullable Object obj)3255         public boolean equals(@Nullable Object obj) {
3256             if (this == obj) {
3257                 return true;
3258             }
3259             if (obj == null || getClass() != obj.getClass()) {
3260                 return false;
3261             }
3262             final HistoricalOps other = (HistoricalOps) obj;
3263             if (mBeginTimeMillis != other.mBeginTimeMillis) {
3264                 return false;
3265             }
3266             if (mEndTimeMillis != other.mEndTimeMillis) {
3267                 return false;
3268             }
3269             if (mHistoricalUidOps == null) {
3270                 if (other.mHistoricalUidOps != null) {
3271                     return false;
3272                 }
3273             } else if (!mHistoricalUidOps.equals(other.mHistoricalUidOps)) {
3274                 return false;
3275             }
3276             return true;
3277         }
3278 
3279         @Override
hashCode()3280         public int hashCode() {
3281             int result = (int) (mBeginTimeMillis ^ (mBeginTimeMillis >>> 32));
3282             result = 31 * result + mHistoricalUidOps.hashCode();
3283             return result;
3284         }
3285 
3286         @NonNull
3287         @Override
toString()3288         public String toString() {
3289             return getClass().getSimpleName() + "[from:"
3290                     + mBeginTimeMillis + " to:" + mEndTimeMillis + "]";
3291         }
3292 
3293         public static final @android.annotation.NonNull Creator<HistoricalOps> CREATOR = new Creator<HistoricalOps>() {
3294             @Override
3295             public @NonNull HistoricalOps createFromParcel(@NonNull Parcel parcel) {
3296                 return new HistoricalOps(parcel);
3297             }
3298 
3299             @Override
3300             public @NonNull HistoricalOps[] newArray(int size) {
3301                 return new HistoricalOps[size];
3302             }
3303         };
3304     }
3305 
3306     /**
3307      * This class represents historical app op state for a UID.
3308      *
3309      * @hide
3310      */
3311     @TestApi
3312     @SystemApi
3313     public static final class HistoricalUidOps implements Parcelable {
3314         private final int mUid;
3315         private @Nullable ArrayMap<String, HistoricalPackageOps> mHistoricalPackageOps;
3316 
3317         /** @hide */
HistoricalUidOps(int uid)3318         public HistoricalUidOps(int uid) {
3319             mUid = uid;
3320         }
3321 
HistoricalUidOps(@onNull HistoricalUidOps other)3322         private HistoricalUidOps(@NonNull HistoricalUidOps other) {
3323             mUid = other.mUid;
3324             final int opCount = other.getPackageCount();
3325             for (int i = 0; i < opCount; i++) {
3326                 final HistoricalPackageOps origOps = other.getPackageOpsAt(i);
3327                 final HistoricalPackageOps cloneOps = new HistoricalPackageOps(origOps);
3328                 if (mHistoricalPackageOps == null) {
3329                     mHistoricalPackageOps = new ArrayMap<>(opCount);
3330                 }
3331                 mHistoricalPackageOps.put(cloneOps.getPackageName(), cloneOps);
3332             }
3333         }
3334 
HistoricalUidOps(@onNull Parcel parcel)3335         private HistoricalUidOps(@NonNull Parcel parcel) {
3336             // No arg check since we always read from a trusted source.
3337             mUid = parcel.readInt();
3338             mHistoricalPackageOps = parcel.createTypedArrayMap(HistoricalPackageOps.CREATOR);
3339         }
3340 
splice(double fractionToRemove)3341         private @Nullable HistoricalUidOps splice(double fractionToRemove) {
3342             HistoricalUidOps splice = null;
3343             final int packageCount = getPackageCount();
3344             for (int i = 0; i < packageCount; i++) {
3345                 final HistoricalPackageOps origOps = getPackageOpsAt(i);
3346                 final HistoricalPackageOps spliceOps = origOps.splice(fractionToRemove);
3347                 if (spliceOps != null) {
3348                     if (splice == null) {
3349                         splice = new HistoricalUidOps(mUid);
3350                     }
3351                     if (splice.mHistoricalPackageOps == null) {
3352                         splice.mHistoricalPackageOps = new ArrayMap<>();
3353                     }
3354                     splice.mHistoricalPackageOps.put(spliceOps.getPackageName(), spliceOps);
3355                 }
3356             }
3357             return splice;
3358         }
3359 
merge(@onNull HistoricalUidOps other)3360         private void merge(@NonNull HistoricalUidOps other) {
3361             final int packageCount = other.getPackageCount();
3362             for (int i = 0; i < packageCount; i++) {
3363                 final HistoricalPackageOps otherPackageOps = other.getPackageOpsAt(i);
3364                 final HistoricalPackageOps thisPackageOps = getPackageOps(
3365                         otherPackageOps.getPackageName());
3366                 if (thisPackageOps != null) {
3367                     thisPackageOps.merge(otherPackageOps);
3368                 } else {
3369                     if (mHistoricalPackageOps == null) {
3370                         mHistoricalPackageOps = new ArrayMap<>();
3371                     }
3372                     mHistoricalPackageOps.put(otherPackageOps.getPackageName(), otherPackageOps);
3373                 }
3374             }
3375         }
3376 
filter(@ullable String packageName, @Nullable String[] opNames, double fractionToRemove)3377         private void filter(@Nullable String packageName, @Nullable String[] opNames,
3378                 double fractionToRemove) {
3379             final int packageCount = getPackageCount();
3380             for (int i = packageCount - 1; i >= 0; i--) {
3381                 final HistoricalPackageOps packageOps = getPackageOpsAt(i);
3382                 if (packageName != null && !packageName.equals(packageOps.getPackageName())) {
3383                     mHistoricalPackageOps.removeAt(i);
3384                 } else {
3385                     packageOps.filter(opNames, fractionToRemove);
3386                 }
3387             }
3388         }
3389 
isEmpty()3390         private boolean isEmpty() {
3391             final int packageCount = getPackageCount();
3392             for (int i = packageCount - 1; i >= 0; i--) {
3393                 final HistoricalPackageOps packageOps = mHistoricalPackageOps.valueAt(i);
3394                 if (!packageOps.isEmpty()) {
3395                     return false;
3396                 }
3397             }
3398             return true;
3399         }
3400 
increaseAccessCount(int opCode, @NonNull String packageName, @UidState int uidState, @OpFlags int flags, long increment)3401         private void increaseAccessCount(int opCode, @NonNull String packageName,
3402                 @UidState int uidState, @OpFlags int flags, long increment) {
3403             getOrCreateHistoricalPackageOps(packageName).increaseAccessCount(
3404                     opCode, uidState, flags, increment);
3405         }
3406 
increaseRejectCount(int opCode, @NonNull String packageName, @UidState int uidState, @OpFlags int flags, long increment)3407         private void increaseRejectCount(int opCode, @NonNull String packageName,
3408                 @UidState int uidState,  @OpFlags int flags, long increment) {
3409             getOrCreateHistoricalPackageOps(packageName).increaseRejectCount(
3410                     opCode, uidState, flags, increment);
3411         }
3412 
increaseAccessDuration(int opCode, @NonNull String packageName, @UidState int uidState, @OpFlags int flags, long increment)3413         private void increaseAccessDuration(int opCode, @NonNull String packageName,
3414                 @UidState int uidState, @OpFlags int flags, long increment) {
3415             getOrCreateHistoricalPackageOps(packageName).increaseAccessDuration(
3416                     opCode, uidState, flags, increment);
3417         }
3418 
3419         /**
3420          * @return The UID for which the data is related.
3421          */
getUid()3422         public int getUid() {
3423             return mUid;
3424         }
3425 
3426         /**
3427          * Gets number of packages with historical ops.
3428          *
3429          * @return The number of packages with historical ops.
3430          *
3431          * @see #getPackageOpsAt(int)
3432          */
getPackageCount()3433         public @IntRange(from = 0) int getPackageCount() {
3434             if (mHistoricalPackageOps == null) {
3435                 return 0;
3436             }
3437             return mHistoricalPackageOps.size();
3438         }
3439 
3440         /**
3441          * Gets the historical package ops at a given index.
3442          *
3443          * @param index The index.
3444          *
3445          * @return The historical package ops at the given index.
3446          *
3447          * @see #getPackageCount()
3448          */
getPackageOpsAt(@ntRangefrom = 0) int index)3449         public @NonNull HistoricalPackageOps getPackageOpsAt(@IntRange(from = 0) int index) {
3450             if (mHistoricalPackageOps == null) {
3451                 throw new IndexOutOfBoundsException();
3452             }
3453             return mHistoricalPackageOps.valueAt(index);
3454         }
3455 
3456         /**
3457          * Gets the historical package ops for a given package.
3458          *
3459          * @param packageName The package.
3460          *
3461          * @return The historical ops for the package.
3462          */
getPackageOps(@onNull String packageName)3463         public @Nullable HistoricalPackageOps getPackageOps(@NonNull String packageName) {
3464             if (mHistoricalPackageOps == null) {
3465                 return null;
3466             }
3467             return mHistoricalPackageOps.get(packageName);
3468         }
3469 
clearHistory(@onNull String packageName)3470         private void clearHistory(@NonNull String packageName) {
3471             if (mHistoricalPackageOps != null) {
3472                 mHistoricalPackageOps.remove(packageName);
3473             }
3474         }
3475 
3476         @Override
describeContents()3477         public int describeContents() {
3478             return 0;
3479         }
3480 
3481         @Override
writeToParcel(Parcel parcel, int flags)3482         public void writeToParcel(Parcel parcel, int flags) {
3483             parcel.writeInt(mUid);
3484             parcel.writeTypedArrayMap(mHistoricalPackageOps, flags);
3485         }
3486 
accept(@onNull HistoricalOpsVisitor visitor)3487         private void accept(@NonNull HistoricalOpsVisitor visitor) {
3488             visitor.visitHistoricalUidOps(this);
3489             final int packageCount = getPackageCount();
3490             for (int i = 0; i < packageCount; i++) {
3491                 getPackageOpsAt(i).accept(visitor);
3492             }
3493         }
3494 
getOrCreateHistoricalPackageOps( @onNull String packageName)3495         private @NonNull HistoricalPackageOps getOrCreateHistoricalPackageOps(
3496                 @NonNull String packageName) {
3497             if (mHistoricalPackageOps == null) {
3498                 mHistoricalPackageOps = new ArrayMap<>();
3499             }
3500             HistoricalPackageOps historicalPackageOp = mHistoricalPackageOps.get(packageName);
3501             if (historicalPackageOp == null) {
3502                 historicalPackageOp = new HistoricalPackageOps(packageName);
3503                 mHistoricalPackageOps.put(packageName, historicalPackageOp);
3504             }
3505             return historicalPackageOp;
3506         }
3507 
3508 
3509         public static final @android.annotation.NonNull Creator<HistoricalUidOps> CREATOR = new Creator<HistoricalUidOps>() {
3510             @Override
3511             public @NonNull HistoricalUidOps createFromParcel(@NonNull Parcel parcel) {
3512                 return new HistoricalUidOps(parcel);
3513             }
3514 
3515             @Override
3516             public @NonNull HistoricalUidOps[] newArray(int size) {
3517                 return new HistoricalUidOps[size];
3518             }
3519         };
3520 
3521         @Override
equals(@ullable Object obj)3522         public boolean equals(@Nullable Object obj) {
3523             if (this == obj) {
3524                 return true;
3525             }
3526             if (obj == null || getClass() != obj.getClass()) {
3527                 return false;
3528             }
3529             final HistoricalUidOps other = (HistoricalUidOps) obj;
3530             if (mUid != other.mUid) {
3531                 return false;
3532             }
3533             if (mHistoricalPackageOps == null) {
3534                 if (other.mHistoricalPackageOps != null) {
3535                     return false;
3536                 }
3537             } else if (!mHistoricalPackageOps.equals(other.mHistoricalPackageOps)) {
3538                 return false;
3539             }
3540             return true;
3541         }
3542 
3543         @Override
hashCode()3544         public int hashCode() {
3545             int result = mUid;
3546             result = 31 * result + (mHistoricalPackageOps != null
3547                     ? mHistoricalPackageOps.hashCode() : 0);
3548             return result;
3549         }
3550     }
3551 
3552     /**
3553      * This class represents historical app op information about a package.
3554      *
3555      * @hide
3556      */
3557     @TestApi
3558     @SystemApi
3559     public static final class HistoricalPackageOps implements Parcelable {
3560         private final @NonNull String mPackageName;
3561         private @Nullable ArrayMap<String, HistoricalOp> mHistoricalOps;
3562 
3563         /** @hide */
HistoricalPackageOps(@onNull String packageName)3564         public HistoricalPackageOps(@NonNull String packageName) {
3565             mPackageName = packageName;
3566         }
3567 
HistoricalPackageOps(@onNull HistoricalPackageOps other)3568         private HistoricalPackageOps(@NonNull HistoricalPackageOps other) {
3569             mPackageName = other.mPackageName;
3570             final int opCount = other.getOpCount();
3571             for (int i = 0; i < opCount; i++) {
3572                 final HistoricalOp origOp = other.getOpAt(i);
3573                 final HistoricalOp cloneOp = new HistoricalOp(origOp);
3574                 if (mHistoricalOps == null) {
3575                     mHistoricalOps = new ArrayMap<>(opCount);
3576                 }
3577                 mHistoricalOps.put(cloneOp.getOpName(), cloneOp);
3578             }
3579         }
3580 
HistoricalPackageOps(@onNull Parcel parcel)3581         private HistoricalPackageOps(@NonNull Parcel parcel) {
3582             mPackageName = parcel.readString();
3583             mHistoricalOps = parcel.createTypedArrayMap(HistoricalOp.CREATOR);
3584         }
3585 
splice(double fractionToRemove)3586         private @Nullable HistoricalPackageOps splice(double fractionToRemove) {
3587             HistoricalPackageOps splice = null;
3588             final int opCount = getOpCount();
3589             for (int i = 0; i < opCount; i++) {
3590                 final HistoricalOp origOps = getOpAt(i);
3591                 final HistoricalOp spliceOps = origOps.splice(fractionToRemove);
3592                 if (spliceOps != null) {
3593                     if (splice == null) {
3594                         splice = new HistoricalPackageOps(mPackageName);
3595                     }
3596                     if (splice.mHistoricalOps == null) {
3597                         splice.mHistoricalOps = new ArrayMap<>();
3598                     }
3599                     splice.mHistoricalOps.put(spliceOps.getOpName(), spliceOps);
3600                 }
3601             }
3602             return splice;
3603         }
3604 
merge(@onNull HistoricalPackageOps other)3605         private void merge(@NonNull HistoricalPackageOps other) {
3606             final int opCount = other.getOpCount();
3607             for (int i = 0; i < opCount; i++) {
3608                 final HistoricalOp otherOp = other.getOpAt(i);
3609                 final HistoricalOp thisOp = getOp(otherOp.getOpName());
3610                 if (thisOp != null) {
3611                     thisOp.merge(otherOp);
3612                 } else {
3613                     if (mHistoricalOps == null) {
3614                         mHistoricalOps = new ArrayMap<>();
3615                     }
3616                     mHistoricalOps.put(otherOp.getOpName(), otherOp);
3617                 }
3618             }
3619         }
3620 
filter(@ullable String[] opNames, double scaleFactor)3621         private void filter(@Nullable String[] opNames, double scaleFactor) {
3622             final int opCount = getOpCount();
3623             for (int i = opCount - 1; i >= 0; i--) {
3624                 final HistoricalOp op = mHistoricalOps.valueAt(i);
3625                 if (opNames != null && !ArrayUtils.contains(opNames, op.getOpName())) {
3626                     mHistoricalOps.removeAt(i);
3627                 } else {
3628                     op.filter(scaleFactor);
3629                 }
3630             }
3631         }
3632 
isEmpty()3633         private boolean isEmpty() {
3634             final int opCount = getOpCount();
3635             for (int i = opCount - 1; i >= 0; i--) {
3636                 final HistoricalOp op = mHistoricalOps.valueAt(i);
3637                 if (!op.isEmpty()) {
3638                     return false;
3639                 }
3640             }
3641             return true;
3642         }
3643 
increaseAccessCount(int opCode, @UidState int uidState, @OpFlags int flags, long increment)3644         private void increaseAccessCount(int opCode, @UidState int uidState,
3645                 @OpFlags int flags, long increment) {
3646             getOrCreateHistoricalOp(opCode).increaseAccessCount(uidState, flags, increment);
3647         }
3648 
increaseRejectCount(int opCode, @UidState int uidState, @OpFlags int flags, long increment)3649         private void increaseRejectCount(int opCode, @UidState int uidState,
3650                 @OpFlags int flags, long increment) {
3651             getOrCreateHistoricalOp(opCode).increaseRejectCount(uidState, flags, increment);
3652         }
3653 
increaseAccessDuration(int opCode, @UidState int uidState, @OpFlags int flags, long increment)3654         private void increaseAccessDuration(int opCode, @UidState int uidState,
3655                 @OpFlags int flags, long increment) {
3656             getOrCreateHistoricalOp(opCode).increaseAccessDuration(uidState, flags, increment);
3657         }
3658 
3659         /**
3660          * Gets the package name which the data represents.
3661          *
3662          * @return The package name which the data represents.
3663          */
getPackageName()3664         public @NonNull String getPackageName() {
3665             return mPackageName;
3666         }
3667 
3668         /**
3669          * Gets number historical app ops.
3670          *
3671          * @return The number historical app ops.
3672          * @see #getOpAt(int)
3673          */
getOpCount()3674         public @IntRange(from = 0) int getOpCount() {
3675             if (mHistoricalOps == null) {
3676                 return 0;
3677             }
3678             return mHistoricalOps.size();
3679         }
3680 
3681         /**
3682          * Gets the historical op at a given index.
3683          *
3684          * @param index The index to lookup.
3685          * @return The op at the given index.
3686          * @see #getOpCount()
3687          */
getOpAt(@ntRangefrom = 0) int index)3688         public @NonNull HistoricalOp getOpAt(@IntRange(from = 0) int index) {
3689             if (mHistoricalOps == null) {
3690                 throw new IndexOutOfBoundsException();
3691             }
3692             return mHistoricalOps.valueAt(index);
3693         }
3694 
3695         /**
3696          * Gets the historical entry for a given op name.
3697          *
3698          * @param opName The op name.
3699          * @return The historical entry for that op name.
3700          */
getOp(@onNull String opName)3701         public @Nullable HistoricalOp getOp(@NonNull String opName) {
3702             if (mHistoricalOps == null) {
3703                 return null;
3704             }
3705             return mHistoricalOps.get(opName);
3706         }
3707 
3708         @Override
describeContents()3709         public int describeContents() {
3710             return 0;
3711         }
3712 
3713         @Override
writeToParcel(@onNull Parcel parcel, int flags)3714         public void writeToParcel(@NonNull Parcel parcel, int flags) {
3715             parcel.writeString(mPackageName);
3716             parcel.writeTypedArrayMap(mHistoricalOps, flags);
3717         }
3718 
accept(@onNull HistoricalOpsVisitor visitor)3719         private void accept(@NonNull HistoricalOpsVisitor visitor) {
3720             visitor.visitHistoricalPackageOps(this);
3721             final int opCount = getOpCount();
3722             for (int i = 0; i < opCount; i++) {
3723                 getOpAt(i).accept(visitor);
3724             }
3725         }
3726 
getOrCreateHistoricalOp(int opCode)3727         private @NonNull HistoricalOp getOrCreateHistoricalOp(int opCode) {
3728             if (mHistoricalOps == null) {
3729                 mHistoricalOps = new ArrayMap<>();
3730             }
3731             final String opStr = sOpToString[opCode];
3732             HistoricalOp op = mHistoricalOps.get(opStr);
3733             if (op == null) {
3734                 op = new HistoricalOp(opCode);
3735                 mHistoricalOps.put(opStr, op);
3736             }
3737             return op;
3738         }
3739 
3740         public static final @android.annotation.NonNull Creator<HistoricalPackageOps> CREATOR =
3741                 new Creator<HistoricalPackageOps>() {
3742             @Override
3743             public @NonNull HistoricalPackageOps createFromParcel(@NonNull Parcel parcel) {
3744                 return new HistoricalPackageOps(parcel);
3745             }
3746 
3747             @Override
3748             public @NonNull HistoricalPackageOps[] newArray(int size) {
3749                 return new HistoricalPackageOps[size];
3750             }
3751         };
3752 
3753         @Override
equals(@ullable Object obj)3754         public boolean equals(@Nullable Object obj) {
3755             if (this == obj) {
3756                 return true;
3757             }
3758             if (obj == null || getClass() != obj.getClass()) {
3759                 return false;
3760             }
3761             final HistoricalPackageOps other = (HistoricalPackageOps) obj;
3762             if (!mPackageName.equals(other.mPackageName)) {
3763                 return false;
3764             }
3765             if (mHistoricalOps == null) {
3766                 if (other.mHistoricalOps != null) {
3767                     return false;
3768                 }
3769             } else if (!mHistoricalOps.equals(other.mHistoricalOps)) {
3770                 return false;
3771             }
3772             return true;
3773         }
3774 
3775         @Override
hashCode()3776         public int hashCode() {
3777             int result = mPackageName != null ? mPackageName.hashCode() : 0;
3778             result = 31 * result + (mHistoricalOps != null ? mHistoricalOps.hashCode() : 0);
3779             return result;
3780         }
3781     }
3782 
3783     /**
3784      * This class represents historical information about an app op.
3785      *
3786      * @hide
3787      */
3788     @TestApi
3789     @SystemApi
3790     public static final class HistoricalOp implements Parcelable {
3791         private final int mOp;
3792         private @Nullable LongSparseLongArray mAccessCount;
3793         private @Nullable LongSparseLongArray mRejectCount;
3794         private @Nullable LongSparseLongArray mAccessDuration;
3795 
3796         /** @hide */
HistoricalOp(int op)3797         public HistoricalOp(int op) {
3798             mOp = op;
3799         }
3800 
HistoricalOp(@onNull HistoricalOp other)3801         private HistoricalOp(@NonNull HistoricalOp other) {
3802             mOp = other.mOp;
3803             if (other.mAccessCount != null) {
3804                 mAccessCount = other.mAccessCount.clone();
3805             }
3806             if (other.mRejectCount != null) {
3807                 mRejectCount = other.mRejectCount.clone();
3808             }
3809             if (other.mAccessDuration != null) {
3810                 mAccessDuration = other.mAccessDuration.clone();
3811             }
3812         }
3813 
HistoricalOp(@onNull Parcel parcel)3814         private HistoricalOp(@NonNull Parcel parcel) {
3815             mOp = parcel.readInt();
3816             mAccessCount = readLongSparseLongArrayFromParcel(parcel);
3817             mRejectCount = readLongSparseLongArrayFromParcel(parcel);
3818             mAccessDuration = readLongSparseLongArrayFromParcel(parcel);
3819         }
3820 
filter(double scaleFactor)3821         private void filter(double scaleFactor) {
3822             scale(mAccessCount, scaleFactor);
3823             scale(mRejectCount, scaleFactor);
3824             scale(mAccessDuration, scaleFactor);
3825         }
3826 
isEmpty()3827         private boolean isEmpty() {
3828             return !hasData(mAccessCount)
3829                     && !hasData(mRejectCount)
3830                     && !hasData(mAccessDuration);
3831         }
3832 
hasData(@onNull LongSparseLongArray array)3833         private boolean hasData(@NonNull LongSparseLongArray array) {
3834             return (array != null && array.size() > 0);
3835         }
3836 
splice(double fractionToRemove)3837         private @Nullable HistoricalOp splice(double fractionToRemove) {
3838             final HistoricalOp splice = new HistoricalOp(mOp);
3839             splice(mAccessCount, splice::getOrCreateAccessCount, fractionToRemove);
3840             splice(mRejectCount, splice::getOrCreateRejectCount, fractionToRemove);
3841             splice(mAccessDuration, splice::getOrCreateAccessDuration, fractionToRemove);
3842             return splice;
3843         }
3844 
splice(@ullable LongSparseLongArray sourceContainer, @NonNull Supplier<LongSparseLongArray> destContainerProvider, double fractionToRemove)3845         private static void splice(@Nullable LongSparseLongArray sourceContainer,
3846                 @NonNull Supplier<LongSparseLongArray> destContainerProvider,
3847                     double fractionToRemove) {
3848             if (sourceContainer != null) {
3849                 final int size = sourceContainer.size();
3850                 for (int i = 0; i < size; i++) {
3851                     final long key = sourceContainer.keyAt(i);
3852                     final long value = sourceContainer.valueAt(i);
3853                     final long removedFraction = Math.round(value * fractionToRemove);
3854                     if (removedFraction > 0) {
3855                         destContainerProvider.get().put(key, removedFraction);
3856                         sourceContainer.put(key, value - removedFraction);
3857                     }
3858                 }
3859             }
3860         }
3861 
merge(@onNull HistoricalOp other)3862         private void merge(@NonNull HistoricalOp other) {
3863             merge(this::getOrCreateAccessCount, other.mAccessCount);
3864             merge(this::getOrCreateRejectCount, other.mRejectCount);
3865             merge(this::getOrCreateAccessDuration, other.mAccessDuration);
3866         }
3867 
increaseAccessCount(@idState int uidState, @OpFlags int flags, long increment)3868         private void increaseAccessCount(@UidState int uidState, @OpFlags int flags,
3869                 long increment) {
3870             increaseCount(getOrCreateAccessCount(), uidState, flags, increment);
3871         }
3872 
increaseRejectCount(@idState int uidState, @OpFlags int flags, long increment)3873         private void increaseRejectCount(@UidState int uidState, @OpFlags int flags,
3874                 long increment) {
3875             increaseCount(getOrCreateRejectCount(), uidState, flags, increment);
3876         }
3877 
increaseAccessDuration(@idState int uidState, @OpFlags int flags, long increment)3878         private void increaseAccessDuration(@UidState int uidState, @OpFlags int flags,
3879                 long increment) {
3880             increaseCount(getOrCreateAccessDuration(), uidState, flags, increment);
3881         }
3882 
increaseCount(@onNull LongSparseLongArray counts, @UidState int uidState, @OpFlags int flags, long increment)3883         private void increaseCount(@NonNull LongSparseLongArray counts,
3884                 @UidState int uidState, @OpFlags int flags, long increment) {
3885             while (flags != 0) {
3886                 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
3887                 flags &= ~flag;
3888                 final long key = makeKey(uidState, flag);
3889                 counts.put(key, counts.get(key) + increment);
3890             }
3891         }
3892 
3893         /**
3894          * Gets the op name.
3895          *
3896          * @return The op name.
3897          */
getOpName()3898         public @NonNull String getOpName() {
3899             return sOpToString[mOp];
3900         }
3901 
3902         /** @hide */
getOpCode()3903         public int getOpCode() {
3904             return mOp;
3905         }
3906 
3907         /**
3908          * Gets the number times the op was accessed (performed) in the foreground.
3909          *
3910          * @param flags The flags which are any combination of
3911          * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3912          * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3913          * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3914          * for any flag.
3915          * @return The times the op was accessed in the foreground.
3916          *
3917          * @see #getBackgroundAccessCount(int)
3918          * @see #getAccessCount(int, int, int)
3919          */
getForegroundAccessCount(@pFlags int flags)3920         public long getForegroundAccessCount(@OpFlags int flags) {
3921             return sumForFlagsInStates(mAccessCount, MAX_PRIORITY_UID_STATE,
3922                     resolveFirstUnrestrictedUidState(mOp), flags);
3923         }
3924 
3925         /**
3926          * Gets the number times the op was accessed (performed) in the background.
3927          *
3928          * @param flags The flags which are any combination of
3929          * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3930          * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3931          * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3932          * for any flag.
3933          * @return The times the op was accessed in the background.
3934          *
3935          * @see #getForegroundAccessCount(int)
3936          * @see #getAccessCount(int, int, int)
3937          */
getBackgroundAccessCount(@pFlags int flags)3938         public long getBackgroundAccessCount(@OpFlags int flags) {
3939             return sumForFlagsInStates(mAccessCount, resolveLastRestrictedUidState(mOp),
3940                     MIN_PRIORITY_UID_STATE, flags);
3941         }
3942 
3943         /**
3944          * Gets the number times the op was accessed (performed) for a
3945          * range of uid states.
3946          *
3947          * @param fromUidState The UID state from which to query. Could be one of
3948          * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
3949          * {@link #UID_STATE_FOREGROUND_SERVICE_LOCATION},
3950          * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
3951          * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
3952          * @param toUidState The UID state to which to query.
3953          * @param flags The flags which are any combination of
3954          * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3955          * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3956          * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3957          * for any flag.
3958          *
3959          * @return The times the op was accessed for the given UID state.
3960          *
3961          * @see #getForegroundAccessCount(int)
3962          * @see #getBackgroundAccessCount(int)
3963          */
getAccessCount(@idState int fromUidState, @UidState int toUidState, @OpFlags int flags)3964         public long getAccessCount(@UidState int fromUidState, @UidState int toUidState,
3965                 @OpFlags int flags) {
3966             return sumForFlagsInStates(mAccessCount, fromUidState, toUidState, flags);
3967         }
3968 
3969         /**
3970          * Gets the number times the op was rejected in the foreground.
3971          *
3972          * @param flags The flags which are any combination of
3973          * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3974          * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3975          * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3976          * for any flag.
3977          * @return The times the op was rejected in the foreground.
3978          *
3979          * @see #getBackgroundRejectCount(int)
3980          * @see #getRejectCount(int, int, int)
3981          */
getForegroundRejectCount(@pFlags int flags)3982         public long getForegroundRejectCount(@OpFlags int flags) {
3983             return sumForFlagsInStates(mRejectCount, MAX_PRIORITY_UID_STATE,
3984                     resolveFirstUnrestrictedUidState(mOp), flags);
3985         }
3986 
3987         /**
3988          * Gets the number times the op was rejected in the background.
3989          *
3990          * @param flags The flags which are any combination of
3991          * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3992          * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3993          * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3994          * for any flag.
3995          * @return The times the op was rejected in the background.
3996          *
3997          * @see #getForegroundRejectCount(int)
3998          * @see #getRejectCount(int, int, int)
3999          */
getBackgroundRejectCount(@pFlags int flags)4000         public long getBackgroundRejectCount(@OpFlags int flags) {
4001             return sumForFlagsInStates(mRejectCount, resolveLastRestrictedUidState(mOp),
4002                     MIN_PRIORITY_UID_STATE, flags);
4003         }
4004 
4005         /**
4006          * Gets the number times the op was rejected for a given range of UID states.
4007          *
4008          * @param fromUidState The UID state from which to query. Could be one of
4009          * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
4010          * {@link #UID_STATE_FOREGROUND_SERVICE_LOCATION},
4011          * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
4012          * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
4013          * @param toUidState The UID state to which to query.
4014          * @param flags The flags which are any combination of
4015          * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
4016          * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
4017          * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
4018          * for any flag.
4019          *
4020          * @return The times the op was rejected for the given UID state.
4021          *
4022          * @see #getForegroundRejectCount(int)
4023          * @see #getBackgroundRejectCount(int)
4024          */
getRejectCount(@idState int fromUidState, @UidState int toUidState, @OpFlags int flags)4025         public long getRejectCount(@UidState int fromUidState, @UidState int toUidState,
4026                 @OpFlags int flags) {
4027             return sumForFlagsInStates(mRejectCount, fromUidState, toUidState, flags);
4028         }
4029 
4030         /**
4031          * Gets the total duration the app op was accessed (performed) in the foreground.
4032          * The duration is in wall time.
4033          *
4034          * @param flags The flags which are any combination of
4035          * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
4036          * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
4037          * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
4038          * for any flag.
4039          * @return The total duration the app op was accessed in the foreground.
4040          *
4041          * @see #getBackgroundAccessDuration(int)
4042          * @see #getAccessDuration(int, int, int)
4043          */
getForegroundAccessDuration(@pFlags int flags)4044         public long getForegroundAccessDuration(@OpFlags int flags) {
4045             return sumForFlagsInStates(mAccessDuration, MAX_PRIORITY_UID_STATE,
4046                     resolveFirstUnrestrictedUidState(mOp), flags);
4047         }
4048 
4049         /**
4050          * Gets the total duration the app op was accessed (performed) in the background.
4051          * The duration is in wall time.
4052          *
4053          * @param flags The flags which are any combination of
4054          * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
4055          * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
4056          * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
4057          * for any flag.
4058          * @return The total duration the app op was accessed in the background.
4059          *
4060          * @see #getForegroundAccessDuration(int)
4061          * @see #getAccessDuration(int, int, int)
4062          */
getBackgroundAccessDuration(@pFlags int flags)4063         public long getBackgroundAccessDuration(@OpFlags int flags) {
4064             return sumForFlagsInStates(mAccessDuration, resolveLastRestrictedUidState(mOp),
4065                     MIN_PRIORITY_UID_STATE, flags);
4066         }
4067 
4068         /**
4069          * Gets the total duration the app op was accessed (performed) for a given
4070          * range of UID states. The duration is in wall time.
4071          *
4072          * @param fromUidState The UID state from which to query. Could be one of
4073          * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
4074          * {@link #UID_STATE_FOREGROUND_SERVICE_LOCATION},
4075          * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
4076          * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
4077          * @param toUidState The UID state from which to query.
4078          * @param flags The flags which are any combination of
4079          * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
4080          * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
4081          * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
4082          * for any flag.
4083          *
4084          * @return The total duration the app op was accessed for the given UID state.
4085          *
4086          * @see #getForegroundAccessDuration(int)
4087          * @see #getBackgroundAccessDuration(int)
4088          */
getAccessDuration(@idState int fromUidState, @UidState int toUidState, @OpFlags int flags)4089         public long getAccessDuration(@UidState int fromUidState, @UidState int toUidState,
4090                 @OpFlags int flags) {
4091             return sumForFlagsInStates(mAccessDuration, fromUidState, toUidState, flags);
4092         }
4093 
4094         @Override
describeContents()4095         public int describeContents() {
4096             return 0;
4097         }
4098 
4099         @Override
writeToParcel(Parcel parcel, int flags)4100         public void writeToParcel(Parcel parcel, int flags) {
4101             parcel.writeInt(mOp);
4102             writeLongSparseLongArrayToParcel(mAccessCount, parcel);
4103             writeLongSparseLongArrayToParcel(mRejectCount, parcel);
4104             writeLongSparseLongArrayToParcel(mAccessDuration, parcel);
4105         }
4106 
4107         @Override
equals(@ullable Object obj)4108         public boolean equals(@Nullable Object obj) {
4109             if (this == obj) {
4110                 return true;
4111             }
4112             if (obj == null || getClass() != obj.getClass()) {
4113                 return false;
4114             }
4115             final HistoricalOp other = (HistoricalOp) obj;
4116             if (mOp != other.mOp) {
4117                 return false;
4118             }
4119             if (!Objects.equals(mAccessCount, other.mAccessCount)) {
4120                 return false;
4121             }
4122             if (!Objects.equals(mRejectCount, other.mRejectCount)) {
4123                 return false;
4124             }
4125             return Objects.equals(mAccessDuration, other.mAccessDuration);
4126         }
4127 
4128         @Override
hashCode()4129         public int hashCode() {
4130             int result = mOp;
4131             result = 31 * result + Objects.hashCode(mAccessCount);
4132             result = 31 * result + Objects.hashCode(mRejectCount);
4133             result = 31 * result + Objects.hashCode(mAccessDuration);
4134             return result;
4135         }
4136 
accept(@onNull HistoricalOpsVisitor visitor)4137         private void accept(@NonNull HistoricalOpsVisitor visitor) {
4138             visitor.visitHistoricalOp(this);
4139         }
4140 
getOrCreateAccessCount()4141         private @NonNull LongSparseLongArray getOrCreateAccessCount() {
4142             if (mAccessCount == null) {
4143                 mAccessCount = new LongSparseLongArray();
4144             }
4145             return mAccessCount;
4146         }
4147 
getOrCreateRejectCount()4148         private @NonNull LongSparseLongArray getOrCreateRejectCount() {
4149             if (mRejectCount == null) {
4150                 mRejectCount = new LongSparseLongArray();
4151             }
4152             return mRejectCount;
4153         }
4154 
getOrCreateAccessDuration()4155         private @NonNull LongSparseLongArray getOrCreateAccessDuration() {
4156             if (mAccessDuration == null) {
4157                 mAccessDuration = new LongSparseLongArray();
4158             }
4159             return mAccessDuration;
4160         }
4161 
4162         /**
4163          * Multiplies the entries in the array with the passed in scale factor and
4164          * rounds the result at up 0.5 boundary.
4165          *
4166          * @param data The data to scale.
4167          * @param scaleFactor The scale factor.
4168          */
scale(@onNull LongSparseLongArray data, double scaleFactor)4169         private static void scale(@NonNull LongSparseLongArray data, double scaleFactor) {
4170             if (data != null) {
4171                 final int size = data.size();
4172                 for (int i = 0; i < size; i++) {
4173                     data.put(data.keyAt(i), (long) HistoricalOps.round(
4174                             (double) data.valueAt(i) * scaleFactor));
4175                 }
4176             }
4177         }
4178 
4179         /**
4180          * Merges two arrays while lazily acquiring the destination.
4181          *
4182          * @param thisSupplier The destination supplier.
4183          * @param other The array to merge in.
4184          */
merge(@onNull Supplier<LongSparseLongArray> thisSupplier, @Nullable LongSparseLongArray other)4185         private static void merge(@NonNull Supplier<LongSparseLongArray> thisSupplier,
4186                 @Nullable LongSparseLongArray other) {
4187             if (other != null) {
4188                 final int otherSize = other.size();
4189                 for (int i = 0; i < otherSize; i++) {
4190                     final LongSparseLongArray that = thisSupplier.get();
4191                     final long otherKey = other.keyAt(i);
4192                     final long otherValue = other.valueAt(i);
4193                     that.put(otherKey, that.get(otherKey) + otherValue);
4194                 }
4195             }
4196         }
4197 
4198         /** @hide */
collectKeys()4199         public @Nullable LongSparseArray<Object> collectKeys() {
4200             LongSparseArray<Object> result = AppOpsManager.collectKeys(mAccessCount,
4201                 null /*result*/);
4202             result = AppOpsManager.collectKeys(mRejectCount, result);
4203             result = AppOpsManager.collectKeys(mAccessDuration, result);
4204             return result;
4205         }
4206 
4207         public static final @android.annotation.NonNull Creator<HistoricalOp> CREATOR =
4208                 new Creator<HistoricalOp>() {
4209             @Override
4210             public @NonNull HistoricalOp createFromParcel(@NonNull Parcel source) {
4211                 return new HistoricalOp(source);
4212             }
4213 
4214             @Override
4215             public @NonNull HistoricalOp[] newArray(int size) {
4216                 return new HistoricalOp[size];
4217             }
4218         };
4219     }
4220 
4221     /**
4222      * Computes the sum of the counts for the given flags in between the begin and
4223      * end UID states.
4224      *
4225      * @param counts The data array.
4226      * @param beginUidState The beginning UID state (inclusive).
4227      * @param endUidState The end UID state (inclusive).
4228      * @param flags The UID flags.
4229      * @return The sum.
4230      */
sumForFlagsInStates(@ullable LongSparseLongArray counts, @UidState int beginUidState, @UidState int endUidState, @OpFlags int flags)4231     private static long sumForFlagsInStates(@Nullable LongSparseLongArray counts,
4232             @UidState int beginUidState, @UidState int endUidState, @OpFlags int flags) {
4233         if (counts == null) {
4234             return 0;
4235         }
4236         long sum = 0;
4237         while (flags != 0) {
4238             final int flag = 1 << Integer.numberOfTrailingZeros(flags);
4239             flags &= ~flag;
4240             for (int uidState : UID_STATES) {
4241                 if (uidState < beginUidState || uidState > endUidState) {
4242                     continue;
4243                 }
4244                 final long key = makeKey(uidState, flag);
4245                 sum += counts.get(key);
4246             }
4247         }
4248         return sum;
4249     }
4250 
4251     /**
4252      * Finds the first non-negative value for the given flags in between the begin and
4253      * end UID states.
4254      *
4255      * @param counts The data array.
4256      * @param beginUidState The beginning UID state (inclusive).
4257      * @param endUidState The end UID state (inclusive).
4258      * @param flags The UID flags.
4259      * @return The non-negative value or -1.
4260      */
findFirstNonNegativeForFlagsInStates(@ullable LongSparseLongArray counts, @UidState int beginUidState, @UidState int endUidState, @OpFlags int flags)4261     private static long findFirstNonNegativeForFlagsInStates(@Nullable LongSparseLongArray counts,
4262             @UidState int beginUidState, @UidState int endUidState, @OpFlags int flags) {
4263         if (counts == null) {
4264             return -1;
4265         }
4266         while (flags != 0) {
4267             final int flag = 1 << Integer.numberOfTrailingZeros(flags);
4268             flags &= ~flag;
4269             for (int uidState : UID_STATES) {
4270                 if (uidState < beginUidState || uidState > endUidState) {
4271                     continue;
4272                 }
4273                 final long key = makeKey(uidState, flag);
4274                 final long value = counts.get(key);
4275                 if (value >= 0) {
4276                     return value;
4277                 }
4278             }
4279         }
4280         return -1;
4281     }
4282 
4283     /**
4284      * Finds the first non-null value for the given flags in between the begin and
4285      * end UID states.
4286      *
4287      * @param counts The data array.
4288      * @param beginUidState The beginning UID state (inclusive).
4289      * @param endUidState The end UID state (inclusive).
4290      * @param flags The UID flags.
4291      * @return The non-negative value or -1.
4292      */
findFirstNonNullForFlagsInStates( @ullable LongSparseArray<String> counts, @UidState int beginUidState, @UidState int endUidState, @OpFlags int flags)4293     private static @Nullable String findFirstNonNullForFlagsInStates(
4294             @Nullable LongSparseArray<String> counts, @UidState int beginUidState,
4295             @UidState int endUidState, @OpFlags int flags) {
4296         if (counts == null) {
4297             return null;
4298         }
4299         while (flags != 0) {
4300             final int flag = 1 << Integer.numberOfTrailingZeros(flags);
4301             flags &= ~flag;
4302             for (int uidState : UID_STATES) {
4303                 if (uidState < beginUidState || uidState > endUidState) {
4304                     continue;
4305                 }
4306                 final long key = makeKey(uidState, flag);
4307                 final String value = counts.get(key);
4308                 if (value != null) {
4309                     return value;
4310                 }
4311             }
4312         }
4313         return null;
4314     }
4315 
4316     /**
4317      * Callback for notification of changes to operation state.
4318      */
4319     public interface OnOpChangedListener {
onOpChanged(String op, String packageName)4320         public void onOpChanged(String op, String packageName);
4321     }
4322 
4323     /**
4324      * Callback for notification of changes to operation active state.
4325      *
4326      * @hide
4327      */
4328     @TestApi
4329     public interface OnOpActiveChangedListener {
4330         /**
4331          * Called when the active state of an app op changes.
4332          *
4333          * @param code The op code.
4334          * @param uid The UID performing the operation.
4335          * @param packageName The package performing the operation.
4336          * @param active Whether the operation became active or inactive.
4337          */
onOpActiveChanged(int code, int uid, String packageName, boolean active)4338         void onOpActiveChanged(int code, int uid, String packageName, boolean active);
4339     }
4340 
4341     /**
4342      * Callback for notification of an op being noted.
4343      *
4344      * @hide
4345      */
4346     public interface OnOpNotedListener {
4347         /**
4348          * Called when an op was noted.
4349          *
4350          * @param code The op code.
4351          * @param uid The UID performing the operation.
4352          * @param packageName The package performing the operation.
4353          * @param result The result of the note.
4354          */
onOpNoted(int code, int uid, String packageName, int result)4355         void onOpNoted(int code, int uid, String packageName, int result);
4356     }
4357 
4358     /**
4359      * Callback for notification of changes to operation state.
4360      * This allows you to see the raw op codes instead of strings.
4361      * @hide
4362      */
4363     public static class OnOpChangedInternalListener implements OnOpChangedListener {
onOpChanged(String op, String packageName)4364         public void onOpChanged(String op, String packageName) { }
onOpChanged(int op, String packageName)4365         public void onOpChanged(int op, String packageName) { }
4366     }
4367 
AppOpsManager(Context context, IAppOpsService service)4368     AppOpsManager(Context context, IAppOpsService service) {
4369         mContext = context;
4370         mService = service;
4371     }
4372 
4373     /**
4374      * Retrieve current operation state for all applications.
4375      *
4376      * The mode of the ops returned are set for the package but may not reflect their effective
4377      * state due to UID policy or because it's controlled by a different master op.
4378      *
4379      * Use {@link #unsafeCheckOp(String, int, String)}} or {@link #noteOp(String, int, String)}
4380      * if the effective mode is needed.
4381      *
4382      * @param ops The set of operations you are interested in, or null if you want all of them.
4383      * @hide
4384      */
4385     @SystemApi
4386     @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
getPackagesForOps(@ullable String[] ops)4387     public @NonNull List<AppOpsManager.PackageOps> getPackagesForOps(@Nullable String[] ops) {
4388         final int opCount = ops.length;
4389         final int[] opCodes = new int[opCount];
4390         for (int i = 0; i < opCount; i++) {
4391             opCodes[i] = sOpStrToOp.get(ops[i]);
4392         }
4393         final List<AppOpsManager.PackageOps> result = getPackagesForOps(opCodes);
4394         return (result != null) ? result : Collections.emptyList();
4395     }
4396 
4397     /**
4398      * Retrieve current operation state for all applications.
4399      *
4400      * The mode of the ops returned are set for the package but may not reflect their effective
4401      * state due to UID policy or because it's controlled by a different master op.
4402      *
4403      * Use {@link #unsafeCheckOp(String, int, String)}} or {@link #noteOp(String, int, String)}
4404      * if the effective mode is needed.
4405      *
4406      * @param ops The set of operations you are interested in, or null if you want all of them.
4407      * @hide
4408      */
4409     @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
4410     @UnsupportedAppUsage
getPackagesForOps(int[] ops)4411     public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) {
4412         try {
4413             return mService.getPackagesForOps(ops);
4414         } catch (RemoteException e) {
4415             throw e.rethrowFromSystemServer();
4416         }
4417     }
4418 
4419     /**
4420      * Retrieve current operation state for one application.
4421      *
4422      * The mode of the ops returned are set for the package but may not reflect their effective
4423      * state due to UID policy or because it's controlled by a different master op.
4424      *
4425      * Use {@link #unsafeCheckOp(String, int, String)}} or {@link #noteOp(String, int, String)}
4426      * if the effective mode is needed.
4427      *
4428      * @param uid The uid of the application of interest.
4429      * @param packageName The name of the application of interest.
4430      * @param ops The set of operations you are interested in, or null if you want all of them.
4431      *
4432      * @deprecated The int op codes are not stable and you should use the string based op
4433      * names which are stable and namespaced. Use
4434      * {@link #getOpsForPackage(int, String, String...)})}.
4435      *
4436      * @hide
4437      * @removed
4438      */
4439     @Deprecated
4440     @SystemApi
4441     @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
getOpsForPackage(int uid, @NonNull String packageName, @Nullable int[] ops)4442     public @NonNull List<PackageOps> getOpsForPackage(int uid, @NonNull String packageName,
4443             @Nullable int[] ops) {
4444         try {
4445             return mService.getOpsForPackage(uid, packageName, ops);
4446         } catch (RemoteException e) {
4447             throw e.rethrowFromSystemServer();
4448         }
4449     }
4450 
4451     /**
4452      * Retrieve current operation state for one application. The UID and the
4453      * package must match.
4454      *
4455      * The mode of the ops returned are set for the package but may not reflect their effective
4456      * state due to UID policy or because it's controlled by a different master op.
4457      *
4458      * Use {@link #unsafeCheckOp(String, int, String)}} or {@link #noteOp(String, int, String)}
4459      * if the effective mode is needed.
4460      *
4461      * @param uid The uid of the application of interest.
4462      * @param packageName The name of the application of interest.
4463      * @param ops The set of operations you are interested in, or null if you want all of them.
4464      *
4465      * @hide
4466      */
4467     @SystemApi
4468     @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
getOpsForPackage(int uid, @NonNull String packageName, @Nullable String... ops)4469     public @NonNull List<AppOpsManager.PackageOps> getOpsForPackage(int uid,
4470             @NonNull String packageName, @Nullable String... ops) {
4471         int[] opCodes = null;
4472         if (ops != null) {
4473             opCodes = new int[ops.length];
4474             for (int i = 0; i < ops.length; i++) {
4475                 opCodes[i] = strOpToOp(ops[i]);
4476             }
4477         }
4478         try {
4479             final List<PackageOps> result = mService.getOpsForPackage(uid, packageName, opCodes);
4480             if (result == null) {
4481                 return Collections.emptyList();
4482             }
4483             return result;
4484         } catch (RemoteException e) {
4485             throw e.rethrowFromSystemServer();
4486         }
4487     }
4488 
4489     /**
4490      * Retrieve historical app op stats for a period.
4491      *
4492      * @param request A request object describing the data being queried for.
4493      * @param executor Executor on which to run the callback. If <code>null</code>
4494      *     the callback is executed on the default executor running on the main thread.
4495      * @param callback Callback on which to deliver the result.
4496      *
4497      * @throws IllegalArgumentException If any of the argument contracts is violated.
4498      *
4499      * @hide
4500      */
4501     @TestApi
4502     @SystemApi
4503     @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
getHistoricalOps(@onNull HistoricalOpsRequest request, @NonNull Executor executor, @NonNull Consumer<HistoricalOps> callback)4504     public void getHistoricalOps(@NonNull HistoricalOpsRequest request,
4505             @NonNull Executor executor, @NonNull Consumer<HistoricalOps> callback) {
4506         Preconditions.checkNotNull(executor, "executor cannot be null");
4507         Preconditions.checkNotNull(callback, "callback cannot be null");
4508         try {
4509             mService.getHistoricalOps(request.mUid, request.mPackageName, request.mOpNames,
4510                     request.mBeginTimeMillis, request.mEndTimeMillis, request.mFlags,
4511                     new RemoteCallback((result) -> {
4512                 final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS);
4513                 final long identity = Binder.clearCallingIdentity();
4514                 try {
4515                     executor.execute(() -> callback.accept(ops));
4516                 } finally {
4517                     Binder.restoreCallingIdentity(identity);
4518                 }
4519             }));
4520         } catch (RemoteException e) {
4521             throw e.rethrowFromSystemServer();
4522         }
4523     }
4524 
4525     /**
4526      * Retrieve historical app op stats for a period.
4527      *  <p>
4528      *  This method queries only the on disk state and the returned ops are raw,
4529      *  which is their times are relative to the history start as opposed to the
4530      *  epoch start.
4531      *
4532      * @param request A request object describing the data being queried for.
4533      * @param executor Executor on which to run the callback. If <code>null</code>
4534      *     the callback is executed on the default executor running on the main thread.
4535      * @param callback Callback on which to deliver the result.
4536      *
4537      * @throws IllegalArgumentException If any of the argument contracts is violated.
4538      *
4539      * @hide
4540      */
4541     @TestApi
4542     @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
getHistoricalOpsFromDiskRaw(@onNull HistoricalOpsRequest request, @Nullable Executor executor, @NonNull Consumer<HistoricalOps> callback)4543     public void getHistoricalOpsFromDiskRaw(@NonNull HistoricalOpsRequest request,
4544             @Nullable Executor executor, @NonNull Consumer<HistoricalOps> callback) {
4545         Preconditions.checkNotNull(executor, "executor cannot be null");
4546         Preconditions.checkNotNull(callback, "callback cannot be null");
4547         try {
4548             mService.getHistoricalOpsFromDiskRaw(request.mUid, request.mPackageName,
4549                     request.mOpNames, request.mBeginTimeMillis, request.mEndTimeMillis,
4550                     request.mFlags, new RemoteCallback((result) -> {
4551                 final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS);
4552                 final long identity = Binder.clearCallingIdentity();
4553                 try {
4554                     executor.execute(() -> callback.accept(ops));
4555                 } finally {
4556                     Binder.restoreCallingIdentity(identity);
4557                 }
4558             }));
4559         } catch (RemoteException e) {
4560             throw e.rethrowFromSystemServer();
4561         }
4562     }
4563 
4564     /**
4565      * Reloads the non historical state to allow testing the read/write path.
4566      *
4567      * @hide
4568      */
4569     @TestApi
4570     @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
reloadNonHistoricalState()4571     public void reloadNonHistoricalState() {
4572         try {
4573             mService.reloadNonHistoricalState();
4574         } catch (RemoteException e) {
4575             throw e.rethrowFromSystemServer();
4576         }
4577     }
4578 
4579     /**
4580      * Sets given app op in the specified mode for app ops in the UID.
4581      * This applies to all apps currently in the UID or installed in
4582      * this UID in the future.
4583      *
4584      * @param code The app op.
4585      * @param uid The UID for which to set the app.
4586      * @param mode The app op mode to set.
4587      * @hide
4588      */
4589     @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
setUidMode(int code, int uid, @Mode int mode)4590     public void setUidMode(int code, int uid, @Mode int mode) {
4591         try {
4592             mService.setUidMode(code, uid, mode);
4593         } catch (RemoteException e) {
4594             throw e.rethrowFromSystemServer();
4595         }
4596     }
4597 
4598     /**
4599      * Sets given app op in the specified mode for app ops in the UID.
4600      * This applies to all apps currently in the UID or installed in
4601      * this UID in the future.
4602      *
4603      * @param appOp The app op.
4604      * @param uid The UID for which to set the app.
4605      * @param mode The app op mode to set.
4606      * @hide
4607      */
4608     @SystemApi
4609     @TestApi
4610     @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
setUidMode(String appOp, int uid, @Mode int mode)4611     public void setUidMode(String appOp, int uid, @Mode int mode) {
4612         try {
4613             mService.setUidMode(AppOpsManager.strOpToOp(appOp), uid, mode);
4614         } catch (RemoteException e) {
4615             throw e.rethrowFromSystemServer();
4616         }
4617     }
4618 
4619     /** @hide */
setUserRestriction(int code, boolean restricted, IBinder token)4620     public void setUserRestriction(int code, boolean restricted, IBinder token) {
4621         setUserRestriction(code, restricted, token, /*exceptionPackages*/null);
4622     }
4623 
4624     /** @hide */
setUserRestriction(int code, boolean restricted, IBinder token, String[] exceptionPackages)4625     public void setUserRestriction(int code, boolean restricted, IBinder token,
4626             String[] exceptionPackages) {
4627         setUserRestrictionForUser(code, restricted, token, exceptionPackages, mContext.getUserId());
4628     }
4629 
4630     /** @hide */
setUserRestrictionForUser(int code, boolean restricted, IBinder token, String[] exceptionPackages, int userId)4631     public void setUserRestrictionForUser(int code, boolean restricted, IBinder token,
4632             String[] exceptionPackages, int userId) {
4633         try {
4634             mService.setUserRestriction(code, restricted, token, userId, exceptionPackages);
4635         } catch (RemoteException e) {
4636             throw e.rethrowFromSystemServer();
4637         }
4638     }
4639 
4640     /** @hide */
4641     @UnsupportedAppUsage
4642     @TestApi
4643     @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
setMode(int code, int uid, String packageName, @Mode int mode)4644     public void setMode(int code, int uid, String packageName, @Mode int mode) {
4645         try {
4646             mService.setMode(code, uid, packageName, mode);
4647         } catch (RemoteException e) {
4648             throw e.rethrowFromSystemServer();
4649         }
4650     }
4651 
4652     /**
4653      * Change the operating mode for the given op in the given app package.  You must pass
4654      * in both the uid and name of the application whose mode is being modified; if these
4655      * do not match, the modification will not be applied.
4656      *
4657      * @param op The operation to modify.  One of the OPSTR_* constants.
4658      * @param uid The user id of the application whose mode will be changed.
4659      * @param packageName The name of the application package name whose mode will
4660      * be changed.
4661      * @hide
4662      */
4663     @TestApi
4664     @SystemApi
4665     @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
setMode(String op, int uid, String packageName, @Mode int mode)4666     public void setMode(String op, int uid, String packageName, @Mode int mode) {
4667         try {
4668             mService.setMode(strOpToOp(op), uid, packageName, mode);
4669         } catch (RemoteException e) {
4670             throw e.rethrowFromSystemServer();
4671         }
4672     }
4673 
4674     /**
4675      * Set a non-persisted restriction on an audio operation at a stream-level.
4676      * Restrictions are temporary additional constraints imposed on top of the persisted rules
4677      * defined by {@link #setMode}.
4678      *
4679      * @param code The operation to restrict.
4680      * @param usage The {@link android.media.AudioAttributes} usage value.
4681      * @param mode The restriction mode (MODE_IGNORED,MODE_ERRORED) or MODE_ALLOWED to unrestrict.
4682      * @param exceptionPackages Optional list of packages to exclude from the restriction.
4683      * @hide
4684      */
4685     @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
4686     @UnsupportedAppUsage
setRestriction(int code, @AttributeUsage int usage, @Mode int mode, String[] exceptionPackages)4687     public void setRestriction(int code, @AttributeUsage int usage, @Mode int mode,
4688             String[] exceptionPackages) {
4689         try {
4690             final int uid = Binder.getCallingUid();
4691             mService.setAudioRestriction(code, usage, uid, mode, exceptionPackages);
4692         } catch (RemoteException e) {
4693             throw e.rethrowFromSystemServer();
4694         }
4695     }
4696 
4697     /** @hide */
4698     @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
4699     @UnsupportedAppUsage
resetAllModes()4700     public void resetAllModes() {
4701         try {
4702             mService.resetAllModes(mContext.getUserId(), null);
4703         } catch (RemoteException e) {
4704             throw e.rethrowFromSystemServer();
4705         }
4706     }
4707 
4708     /**
4709      * Gets the app op name associated with a given permission.
4710      * The app op name is one of the public constants defined
4711      * in this class such as {@link #OPSTR_COARSE_LOCATION}.
4712      * This API is intended to be used for mapping runtime
4713      * permissions to the corresponding app op.
4714      *
4715      * @param permission The permission.
4716      * @return The app op associated with the permission or null.
4717      */
permissionToOp(String permission)4718     public static String permissionToOp(String permission) {
4719         final Integer opCode = sPermToOp.get(permission);
4720         if (opCode == null) {
4721             return null;
4722         }
4723         return sOpToString[opCode];
4724     }
4725 
4726     /**
4727      * Monitor for changes to the operating mode for the given op in the given app package.
4728      * You can watch op changes only for your UID.
4729      *
4730      * @param op The operation to monitor, one of OPSTR_*.
4731      * @param packageName The name of the application to monitor.
4732      * @param callback Where to report changes.
4733      */
startWatchingMode(@onNull String op, @Nullable String packageName, @NonNull final OnOpChangedListener callback)4734     public void startWatchingMode(@NonNull String op, @Nullable String packageName,
4735             @NonNull final OnOpChangedListener callback) {
4736         startWatchingMode(strOpToOp(op), packageName, callback);
4737     }
4738 
4739     /**
4740      * Monitor for changes to the operating mode for the given op in the given app package.
4741      * You can watch op changes only for your UID.
4742      *
4743      * @param op The operation to monitor, one of OPSTR_*.
4744      * @param packageName The name of the application to monitor.
4745      * @param flags Option flags: any combination of {@link #WATCH_FOREGROUND_CHANGES} or 0.
4746      * @param callback Where to report changes.
4747      */
startWatchingMode(@onNull String op, @Nullable String packageName, int flags, @NonNull final OnOpChangedListener callback)4748     public void startWatchingMode(@NonNull String op, @Nullable String packageName, int flags,
4749             @NonNull final OnOpChangedListener callback) {
4750         startWatchingMode(strOpToOp(op), packageName, flags, callback);
4751     }
4752 
4753     /**
4754      * Monitor for changes to the operating mode for the given op in the given app package.
4755      *
4756      * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
4757      * you can watch changes only for your UID.
4758      *
4759      * @param op The operation to monitor, one of OP_*.
4760      * @param packageName The name of the application to monitor.
4761      * @param callback Where to report changes.
4762      * @hide
4763      */
4764     @RequiresPermission(value=android.Manifest.permission.WATCH_APPOPS, conditional=true)
startWatchingMode(int op, String packageName, final OnOpChangedListener callback)4765     public void startWatchingMode(int op, String packageName, final OnOpChangedListener callback) {
4766         startWatchingMode(op, packageName, 0, callback);
4767     }
4768 
4769     /**
4770      * Monitor for changes to the operating mode for the given op in the given app package.
4771      *
4772      * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
4773      * you can watch changes only for your UID.
4774      *
4775      * @param op The operation to monitor, one of OP_*.
4776      * @param packageName The name of the application to monitor.
4777      * @param flags Option flags: any combination of {@link #WATCH_FOREGROUND_CHANGES} or 0.
4778      * @param callback Where to report changes.
4779      * @hide
4780      */
4781     @RequiresPermission(value=android.Manifest.permission.WATCH_APPOPS, conditional=true)
startWatchingMode(int op, String packageName, int flags, final OnOpChangedListener callback)4782     public void startWatchingMode(int op, String packageName, int flags,
4783             final OnOpChangedListener callback) {
4784         synchronized (mModeWatchers) {
4785             IAppOpsCallback cb = mModeWatchers.get(callback);
4786             if (cb == null) {
4787                 cb = new IAppOpsCallback.Stub() {
4788                     public void opChanged(int op, int uid, String packageName) {
4789                         if (callback instanceof OnOpChangedInternalListener) {
4790                             ((OnOpChangedInternalListener)callback).onOpChanged(op, packageName);
4791                         }
4792                         if (sOpToString[op] != null) {
4793                             callback.onOpChanged(sOpToString[op], packageName);
4794                         }
4795                     }
4796                 };
4797                 mModeWatchers.put(callback, cb);
4798             }
4799             try {
4800                 mService.startWatchingModeWithFlags(op, packageName, flags, cb);
4801             } catch (RemoteException e) {
4802                 throw e.rethrowFromSystemServer();
4803             }
4804         }
4805     }
4806 
4807     /**
4808      * Stop monitoring that was previously started with {@link #startWatchingMode}.  All
4809      * monitoring associated with this callback will be removed.
4810      */
stopWatchingMode(@onNull OnOpChangedListener callback)4811     public void stopWatchingMode(@NonNull OnOpChangedListener callback) {
4812         synchronized (mModeWatchers) {
4813             IAppOpsCallback cb = mModeWatchers.remove(callback);
4814             if (cb != null) {
4815                 try {
4816                     mService.stopWatchingMode(cb);
4817                 } catch (RemoteException e) {
4818                     throw e.rethrowFromSystemServer();
4819                 }
4820             }
4821         }
4822     }
4823 
4824     /**
4825      * Start watching for changes to the active state of app ops. An app op may be
4826      * long running and it has a clear start and stop delimiters. If an op is being
4827      * started or stopped by any package you will get a callback. To change the
4828      * watched ops for a registered callback you need to unregister and register it
4829      * again.
4830      *
4831      * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
4832      * you can watch changes only for your UID.
4833      *
4834      * @param ops The ops to watch.
4835      * @param callback Where to report changes.
4836      *
4837      * @see #isOperationActive(int, int, String)
4838      * @see #stopWatchingActive(OnOpActiveChangedListener)
4839      * @see #startOp(int, int, String)
4840      * @see #finishOp(int, int, String)
4841      *
4842      * @hide
4843      */
4844     @TestApi
4845     // TODO: Uncomment below annotation once b/73559440 is fixed
4846     // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
startWatchingActive(@onNull int[] ops, @NonNull OnOpActiveChangedListener callback)4847     public void startWatchingActive(@NonNull int[] ops,
4848             @NonNull OnOpActiveChangedListener callback) {
4849         Preconditions.checkNotNull(ops, "ops cannot be null");
4850         Preconditions.checkNotNull(callback, "callback cannot be null");
4851         IAppOpsActiveCallback cb;
4852         synchronized (mActiveWatchers) {
4853             cb = mActiveWatchers.get(callback);
4854             if (cb != null) {
4855                 return;
4856             }
4857             cb = new IAppOpsActiveCallback.Stub() {
4858                 @Override
4859                 public void opActiveChanged(int op, int uid, String packageName, boolean active) {
4860                     callback.onOpActiveChanged(op, uid, packageName, active);
4861                 }
4862             };
4863             mActiveWatchers.put(callback, cb);
4864         }
4865         try {
4866             mService.startWatchingActive(ops, cb);
4867         } catch (RemoteException e) {
4868             throw e.rethrowFromSystemServer();
4869         }
4870     }
4871 
4872     /**
4873      * Stop watching for changes to the active state of an app op. An app op may be
4874      * long running and it has a clear start and stop delimiters. Unregistering a
4875      * non-registered callback has no effect.
4876      *
4877      * @see #isOperationActive#(int, int, String)
4878      * @see #startWatchingActive(int[], OnOpActiveChangedListener)
4879      * @see #startOp(int, int, String)
4880      * @see #finishOp(int, int, String)
4881      *
4882      * @hide
4883      */
4884     @TestApi
stopWatchingActive(@onNull OnOpActiveChangedListener callback)4885     public void stopWatchingActive(@NonNull OnOpActiveChangedListener callback) {
4886         synchronized (mActiveWatchers) {
4887             final IAppOpsActiveCallback cb = mActiveWatchers.remove(callback);
4888             if (cb != null) {
4889                 try {
4890                     mService.stopWatchingActive(cb);
4891                 } catch (RemoteException e) {
4892                     throw e.rethrowFromSystemServer();
4893                 }
4894             }
4895         }
4896     }
4897 
4898     /**
4899      * Start watching for noted app ops. An app op may be immediate or long running.
4900      * Immediate ops are noted while long running ones are started and stopped. This
4901      * method allows registering a listener to be notified when an app op is noted. If
4902      * an op is being noted by any package you will get a callback. To change the
4903      * watched ops for a registered callback you need to unregister and register it again.
4904      *
4905      * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
4906      * you can watch changes only for your UID.
4907      *
4908      * @param ops The ops to watch.
4909      * @param callback Where to report changes.
4910      *
4911      * @see #startWatchingActive(int[], OnOpActiveChangedListener)
4912      * @see #stopWatchingNoted(OnOpNotedListener)
4913      * @see #noteOp(String, int, String)
4914      *
4915      * @hide
4916      */
4917     @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
startWatchingNoted(@onNull int[] ops, @NonNull OnOpNotedListener callback)4918     public void startWatchingNoted(@NonNull int[] ops, @NonNull OnOpNotedListener callback) {
4919         IAppOpsNotedCallback cb;
4920         synchronized (mNotedWatchers) {
4921             cb = mNotedWatchers.get(callback);
4922             if (cb != null) {
4923                 return;
4924             }
4925             cb = new IAppOpsNotedCallback.Stub() {
4926                 @Override
4927                 public void opNoted(int op, int uid, String packageName, int mode) {
4928                     callback.onOpNoted(op, uid, packageName, mode);
4929                 }
4930             };
4931             mNotedWatchers.put(callback, cb);
4932         }
4933         try {
4934             mService.startWatchingNoted(ops, cb);
4935         } catch (RemoteException e) {
4936             throw e.rethrowFromSystemServer();
4937         }
4938     }
4939 
4940     /**
4941      * Stop watching for noted app ops. An app op may be immediate or long running.
4942      * Unregistering a non-registered callback has no effect.
4943      *
4944      * @see #startWatchingNoted(int[], OnOpNotedListener)
4945      * @see #noteOp(String, int, String)
4946      *
4947      * @hide
4948      */
stopWatchingNoted(@onNull OnOpNotedListener callback)4949     public void stopWatchingNoted(@NonNull OnOpNotedListener callback) {
4950         synchronized (mNotedWatchers) {
4951             final IAppOpsNotedCallback cb = mNotedWatchers.get(callback);
4952             if (cb != null) {
4953                 try {
4954                     mService.stopWatchingNoted(cb);
4955                 } catch (RemoteException e) {
4956                     throw e.rethrowFromSystemServer();
4957                 }
4958             }
4959         }
4960     }
4961 
buildSecurityExceptionMsg(int op, int uid, String packageName)4962     private String buildSecurityExceptionMsg(int op, int uid, String packageName) {
4963         return packageName + " from uid " + uid + " not allowed to perform " + sOpNames[op];
4964     }
4965 
4966     /**
4967      * {@hide}
4968      */
4969     @UnsupportedAppUsage
4970     @TestApi
strOpToOp(@onNull String op)4971     public static int strOpToOp(@NonNull String op) {
4972         Integer val = sOpStrToOp.get(op);
4973         if (val == null) {
4974             throw new IllegalArgumentException("Unknown operation string: " + op);
4975         }
4976         return val;
4977     }
4978 
4979     /**
4980      * Do a quick check for whether an application might be able to perform an operation.
4981      * This is <em>not</em> a security check; you must use {@link #noteOp(String, int, String)}
4982      * or {@link #startOp(String, int, String)} for your actual security checks, which also
4983      * ensure that the given uid and package name are consistent.  This function can just be
4984      * used for a quick check to see if an operation has been disabled for the application,
4985      * as an early reject of some work.  This does not modify the time stamp or other data
4986      * about the operation.
4987      *
4988      * <p>Important things this will not do (which you need to ultimate use
4989      * {@link #noteOp(String, int, String)} or {@link #startOp(String, int, String)} to cover):</p>
4990      * <ul>
4991      *     <li>Verifying the uid and package are consistent, so callers can't spoof
4992      *     their identity.</li>
4993      *     <li>Taking into account the current foreground/background state of the
4994      *     app; apps whose mode varies by this state will always be reported
4995      *     as {@link #MODE_ALLOWED}.</li>
4996      * </ul>
4997      *
4998      * @param op The operation to check.  One of the OPSTR_* constants.
4999      * @param uid The user id of the application attempting to perform the operation.
5000      * @param packageName The name of the application attempting to perform the operation.
5001      * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5002      * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5003      * causing the app to crash).
5004      * @throws SecurityException If the app has been configured to crash on this op.
5005      */
unsafeCheckOp(@onNull String op, int uid, @NonNull String packageName)5006     public int unsafeCheckOp(@NonNull String op, int uid, @NonNull String packageName) {
5007         return checkOp(strOpToOp(op), uid, packageName);
5008     }
5009 
5010     /**
5011      * @deprecated Renamed to {@link #unsafeCheckOp(String, int, String)}.
5012      */
5013     @Deprecated
checkOp(@onNull String op, int uid, @NonNull String packageName)5014     public int checkOp(@NonNull String op, int uid, @NonNull String packageName) {
5015         return checkOp(strOpToOp(op), uid, packageName);
5016     }
5017 
5018     /**
5019      * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
5020      * returns {@link #MODE_ERRORED}.
5021      */
unsafeCheckOpNoThrow(@onNull String op, int uid, @NonNull String packageName)5022     public int unsafeCheckOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
5023         return checkOpNoThrow(strOpToOp(op), uid, packageName);
5024     }
5025 
5026     /**
5027      * @deprecated Renamed to {@link #unsafeCheckOpNoThrow(String, int, String)}.
5028      */
5029     @Deprecated
checkOpNoThrow(@onNull String op, int uid, @NonNull String packageName)5030     public int checkOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
5031         return checkOpNoThrow(strOpToOp(op), uid, packageName);
5032     }
5033 
5034     /**
5035      * Like {@link #checkOp} but returns the <em>raw</em> mode associated with the op.
5036      * Does not throw a security exception, does not translate {@link #MODE_FOREGROUND}.
5037      */
unsafeCheckOpRaw(@onNull String op, int uid, @NonNull String packageName)5038     public int unsafeCheckOpRaw(@NonNull String op, int uid, @NonNull String packageName) {
5039         try {
5040             return mService.checkOperationRaw(strOpToOp(op), uid, packageName);
5041         } catch (RemoteException e) {
5042             throw e.rethrowFromSystemServer();
5043         }
5044     }
5045 
5046     /**
5047      * Like {@link #unsafeCheckOpNoThrow(String, int, String)} but returns the <em>raw</em>
5048      * mode associated with the op. Does not throw a security exception, does not translate
5049      * {@link #MODE_FOREGROUND}.
5050      */
unsafeCheckOpRawNoThrow(@onNull String op, int uid, @NonNull String packageName)5051     public int unsafeCheckOpRawNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
5052         try {
5053             return mService.checkOperationRaw(strOpToOp(op), uid, packageName);
5054         } catch (RemoteException e) {
5055             throw e.rethrowFromSystemServer();
5056         }
5057     }
5058 
5059     /**
5060      * Make note of an application performing an operation.  Note that you must pass
5061      * in both the uid and name of the application to be checked; this function will verify
5062      * that these two match, and if not, return {@link #MODE_IGNORED}.  If this call
5063      * succeeds, the last execution time of the operation for this app will be updated to
5064      * the current time.
5065      * @param op The operation to note.  One of the OPSTR_* constants.
5066      * @param uid The user id of the application attempting to perform the operation.
5067      * @param packageName The name of the application attempting to perform the operation.
5068      * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5069      * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5070      * causing the app to crash).
5071      * @throws SecurityException If the app has been configured to crash on this op.
5072      */
noteOp(@onNull String op, int uid, @NonNull String packageName)5073     public int noteOp(@NonNull String op, int uid, @NonNull String packageName) {
5074         return noteOp(strOpToOp(op), uid, packageName);
5075     }
5076 
5077     /**
5078      * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
5079      * returns {@link #MODE_ERRORED}.
5080      */
noteOpNoThrow(@onNull String op, int uid, @NonNull String packageName)5081     public int noteOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
5082         return noteOpNoThrow(strOpToOp(op), uid, packageName);
5083     }
5084 
5085     /**
5086      * Make note of an application performing an operation on behalf of another
5087      * application when handling an IPC. Note that you must pass the package name
5088      * of the application that is being proxied while its UID will be inferred from
5089      * the IPC state; this function will verify that the calling uid and proxied
5090      * package name match, and if not, return {@link #MODE_IGNORED}. If this call
5091      * succeeds, the last execution time of the operation for the proxied app and
5092      * your app will be updated to the current time.
5093      * @param op The operation to note.  One of the OPSTR_* constants.
5094      * @param proxiedPackageName The name of the application calling into the proxy application.
5095      * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5096      * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5097      * causing the app to crash).
5098      * @throws SecurityException If the app has been configured to crash on this op.
5099      */
noteProxyOp(@onNull String op, @NonNull String proxiedPackageName)5100     public int noteProxyOp(@NonNull String op, @NonNull String proxiedPackageName) {
5101         return noteProxyOp(strOpToOp(op), proxiedPackageName);
5102     }
5103 
5104     /**
5105      * Like {@link #noteProxyOp(String, String)} but instead
5106      * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
5107      *
5108      * <p>This API requires the package with the {@code proxiedPackageName} to belongs to
5109      * {@link Binder#getCallingUid()}.
5110      */
noteProxyOpNoThrow(@onNull String op, @NonNull String proxiedPackageName)5111     public int noteProxyOpNoThrow(@NonNull String op, @NonNull String proxiedPackageName) {
5112         return noteProxyOpNoThrow(strOpToOp(op), proxiedPackageName);
5113     }
5114 
5115     /**
5116      * Like {@link #noteProxyOpNoThrow(String, String)} but allows to specify the proxied uid.
5117      *
5118      * <p>This API requires package with the {@code proxiedPackageName} to belong to
5119      * {@code proxiedUid}.
5120      *
5121      * @param op The op to note
5122      * @param proxiedPackageName The package to note the op for or {@code null} if the op should be
5123      *                           noted for the "android" package
5124      * @param proxiedUid The uid the package belongs to
5125      */
noteProxyOpNoThrow(@onNull String op, @Nullable String proxiedPackageName, int proxiedUid)5126     public int noteProxyOpNoThrow(@NonNull String op, @Nullable String proxiedPackageName,
5127             int proxiedUid) {
5128         return noteProxyOpNoThrow(strOpToOp(op), proxiedPackageName, proxiedUid);
5129     }
5130 
5131     /**
5132      * Report that an application has started executing a long-running operation.  Note that you
5133      * must pass in both the uid and name of the application to be checked; this function will
5134      * verify that these two match, and if not, return {@link #MODE_IGNORED}.  If this call
5135      * succeeds, the last execution time of the operation for this app will be updated to
5136      * the current time and the operation will be marked as "running".  In this case you must
5137      * later call {@link #finishOp(String, int, String)} to report when the application is no
5138      * longer performing the operation.
5139      * @param op The operation to start.  One of the OPSTR_* constants.
5140      * @param uid The user id of the application attempting to perform the operation.
5141      * @param packageName The name of the application attempting to perform the operation.
5142      * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5143      * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5144      * causing the app to crash).
5145      * @throws SecurityException If the app has been configured to crash on this op.
5146      */
startOp(@onNull String op, int uid, @NonNull String packageName)5147     public int startOp(@NonNull String op, int uid, @NonNull String packageName) {
5148         return startOp(strOpToOp(op), uid, packageName);
5149     }
5150 
5151     /**
5152      * Like {@link #startOp} but instead of throwing a {@link SecurityException} it
5153      * returns {@link #MODE_ERRORED}.
5154      */
startOpNoThrow(@onNull String op, int uid, @NonNull String packageName)5155     public int startOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
5156         return startOpNoThrow(strOpToOp(op), uid, packageName);
5157     }
5158 
5159     /**
5160      * Report that an application is no longer performing an operation that had previously
5161      * been started with {@link #startOp(String, int, String)}.  There is no validation of input
5162      * or result; the parameters supplied here must be the exact same ones previously passed
5163      * in when starting the operation.
5164      */
finishOp(@onNull String op, int uid, @NonNull String packageName)5165     public void finishOp(@NonNull String op, int uid, @NonNull String packageName) {
5166         finishOp(strOpToOp(op), uid, packageName);
5167     }
5168 
5169     /**
5170      * Do a quick check for whether an application might be able to perform an operation.
5171      * This is <em>not</em> a security check; you must use {@link #noteOp(int, int, String)}
5172      * or {@link #startOp(int, int, String)} for your actual security checks, which also
5173      * ensure that the given uid and package name are consistent.  This function can just be
5174      * used for a quick check to see if an operation has been disabled for the application,
5175      * as an early reject of some work.  This does not modify the time stamp or other data
5176      * about the operation.
5177      *
5178      * <p>Important things this will not do (which you need to ultimate use
5179      * {@link #noteOp(int, int, String)} or {@link #startOp(int, int, String)} to cover):</p>
5180      * <ul>
5181      *     <li>Verifying the uid and package are consistent, so callers can't spoof
5182      *     their identity.</li>
5183      *     <li>Taking into account the current foreground/background state of the
5184      *     app; apps whose mode varies by this state will always be reported
5185      *     as {@link #MODE_ALLOWED}.</li>
5186      * </ul>
5187      *
5188      * @param op The operation to check.  One of the OP_* constants.
5189      * @param uid The user id of the application attempting to perform the operation.
5190      * @param packageName The name of the application attempting to perform the operation.
5191      * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5192      * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5193      * causing the app to crash).
5194      * @throws SecurityException If the app has been configured to crash on this op.
5195      * @hide
5196      */
5197     @UnsupportedAppUsage
checkOp(int op, int uid, String packageName)5198     public int checkOp(int op, int uid, String packageName) {
5199         try {
5200             int mode = mService.checkOperation(op, uid, packageName);
5201             if (mode == MODE_ERRORED) {
5202                 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
5203             }
5204             return mode;
5205         } catch (RemoteException e) {
5206             throw e.rethrowFromSystemServer();
5207         }
5208     }
5209 
5210     /**
5211      * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
5212      * returns {@link #MODE_ERRORED}.
5213      * @hide
5214      */
5215     @UnsupportedAppUsage
checkOpNoThrow(int op, int uid, String packageName)5216     public int checkOpNoThrow(int op, int uid, String packageName) {
5217         try {
5218             int mode = mService.checkOperation(op, uid, packageName);
5219             return mode == AppOpsManager.MODE_FOREGROUND ? AppOpsManager.MODE_ALLOWED : mode;
5220         } catch (RemoteException e) {
5221             throw e.rethrowFromSystemServer();
5222         }
5223     }
5224 
5225     /**
5226      * Do a quick check to validate if a package name belongs to a UID.
5227      *
5228      * @throws SecurityException if the package name doesn't belong to the given
5229      *             UID, or if ownership cannot be verified.
5230      */
checkPackage(int uid, @NonNull String packageName)5231     public void checkPackage(int uid, @NonNull String packageName) {
5232         try {
5233             if (mService.checkPackage(uid, packageName) != MODE_ALLOWED) {
5234                 throw new SecurityException(
5235                         "Package " + packageName + " does not belong to " + uid);
5236             }
5237         } catch (RemoteException e) {
5238             throw e.rethrowFromSystemServer();
5239         }
5240     }
5241 
5242     /**
5243      * Like {@link #checkOp} but at a stream-level for audio operations.
5244      * @hide
5245      */
checkAudioOp(int op, int stream, int uid, String packageName)5246     public int checkAudioOp(int op, int stream, int uid, String packageName) {
5247         try {
5248             final int mode = mService.checkAudioOperation(op, stream, uid, packageName);
5249             if (mode == MODE_ERRORED) {
5250                 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
5251             }
5252             return mode;
5253         } catch (RemoteException e) {
5254             throw e.rethrowFromSystemServer();
5255         }
5256     }
5257 
5258     /**
5259      * Like {@link #checkAudioOp} but instead of throwing a {@link SecurityException} it
5260      * returns {@link #MODE_ERRORED}.
5261      * @hide
5262      */
checkAudioOpNoThrow(int op, int stream, int uid, String packageName)5263     public int checkAudioOpNoThrow(int op, int stream, int uid, String packageName) {
5264         try {
5265             return mService.checkAudioOperation(op, stream, uid, packageName);
5266         } catch (RemoteException e) {
5267             throw e.rethrowFromSystemServer();
5268         }
5269     }
5270 
5271     /**
5272      * Make note of an application performing an operation.  Note that you must pass
5273      * in both the uid and name of the application to be checked; this function will verify
5274      * that these two match, and if not, return {@link #MODE_IGNORED}.  If this call
5275      * succeeds, the last execution time of the operation for this app will be updated to
5276      * the current time.
5277      * @param op The operation to note.  One of the OP_* constants.
5278      * @param uid The user id of the application attempting to perform the operation.
5279      * @param packageName The name of the application attempting to perform the operation.
5280      * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5281      * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5282      * causing the app to crash).
5283      * @throws SecurityException If the app has been configured to crash on this op.
5284      * @hide
5285      */
5286     @UnsupportedAppUsage
noteOp(int op, int uid, String packageName)5287     public int noteOp(int op, int uid, String packageName) {
5288         final int mode = noteOpNoThrow(op, uid, packageName);
5289         if (mode == MODE_ERRORED) {
5290             throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
5291         }
5292         return mode;
5293     }
5294 
5295     /**
5296      * Make note of an application performing an operation on behalf of another
5297      * application when handling an IPC. Note that you must pass the package name
5298      * of the application that is being proxied while its UID will be inferred from
5299      * the IPC state; this function will verify that the calling uid and proxied
5300      * package name match, and if not, return {@link #MODE_IGNORED}. If this call
5301      * succeeds, the last execution time of the operation for the proxied app and
5302      * your app will be updated to the current time.
5303      * @param op The operation to note. One of the OPSTR_* constants.
5304      * @param proxiedPackageName The name of the application calling into the proxy application.
5305      * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5306      * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5307      * causing the app to crash).
5308      * @throws SecurityException If the proxy or proxied app has been configured to
5309      * crash on this op.
5310      *
5311      * @hide
5312      */
5313     @UnsupportedAppUsage
noteProxyOp(int op, String proxiedPackageName)5314     public int noteProxyOp(int op, String proxiedPackageName) {
5315         int mode = noteProxyOpNoThrow(op, proxiedPackageName);
5316         if (mode == MODE_ERRORED) {
5317             throw new SecurityException("Proxy package " + mContext.getOpPackageName()
5318                     + " from uid " + Process.myUid() + " or calling package "
5319                     + proxiedPackageName + " from uid " + Binder.getCallingUid()
5320                     + " not allowed to perform " + sOpNames[op]);
5321         }
5322         return mode;
5323     }
5324 
5325     /**
5326      * Like {@link #noteProxyOp(int, String)} but instead
5327      * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
5328      * @hide
5329      */
noteProxyOpNoThrow(int op, String proxiedPackageName, int proxiedUid)5330     public int noteProxyOpNoThrow(int op, String proxiedPackageName, int proxiedUid) {
5331         try {
5332             return mService.noteProxyOperation(op, Process.myUid(), mContext.getOpPackageName(),
5333                     proxiedUid, proxiedPackageName);
5334         } catch (RemoteException e) {
5335             throw e.rethrowFromSystemServer();
5336         }
5337     }
5338 
5339     /**
5340      * Like {@link #noteProxyOp(int, String)} but instead
5341      * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
5342      *
5343      * <p>This API requires the package with {@code proxiedPackageName} to belongs to
5344      * {@link Binder#getCallingUid()}.
5345      *
5346      * @hide
5347      */
noteProxyOpNoThrow(int op, String proxiedPackageName)5348     public int noteProxyOpNoThrow(int op, String proxiedPackageName) {
5349         return noteProxyOpNoThrow(op, proxiedPackageName, Binder.getCallingUid());
5350     }
5351 
5352     /**
5353      * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
5354      * returns {@link #MODE_ERRORED}.
5355      * @hide
5356      */
5357     @UnsupportedAppUsage
noteOpNoThrow(int op, int uid, String packageName)5358     public int noteOpNoThrow(int op, int uid, String packageName) {
5359         try {
5360             return mService.noteOperation(op, uid, packageName);
5361         } catch (RemoteException e) {
5362             throw e.rethrowFromSystemServer();
5363         }
5364     }
5365 
5366     /** @hide */
5367     @UnsupportedAppUsage
noteOp(int op)5368     public int noteOp(int op) {
5369         return noteOp(op, Process.myUid(), mContext.getOpPackageName());
5370     }
5371 
5372     /** @hide */
5373     @UnsupportedAppUsage
getToken(IAppOpsService service)5374     public static IBinder getToken(IAppOpsService service) {
5375         synchronized (AppOpsManager.class) {
5376             if (sToken != null) {
5377                 return sToken;
5378             }
5379             try {
5380                 sToken = service.getToken(new Binder());
5381             } catch (RemoteException e) {
5382                 throw e.rethrowFromSystemServer();
5383             }
5384             return sToken;
5385         }
5386     }
5387 
5388     /** @hide */
startOp(int op)5389     public int startOp(int op) {
5390         return startOp(op, Process.myUid(), mContext.getOpPackageName());
5391     }
5392 
5393     /**
5394      * Report that an application has started executing a long-running operation.  Note that you
5395      * must pass in both the uid and name of the application to be checked; this function will
5396      * verify that these two match, and if not, return {@link #MODE_IGNORED}.  If this call
5397      * succeeds, the last execution time of the operation for this app will be updated to
5398      * the current time and the operation will be marked as "running".  In this case you must
5399      * later call {@link #finishOp(int, int, String)} to report when the application is no
5400      * longer performing the operation.
5401      *
5402      * @param op The operation to start.  One of the OP_* constants.
5403      * @param uid The user id of the application attempting to perform the operation.
5404      * @param packageName The name of the application attempting to perform the operation.
5405      * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5406      * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5407      * causing the app to crash).
5408      * @throws SecurityException If the app has been configured to crash on this op.
5409      * @hide
5410      */
startOp(int op, int uid, String packageName)5411     public int startOp(int op, int uid, String packageName) {
5412         return startOp(op, uid, packageName, false);
5413     }
5414 
5415     /**
5416      * Report that an application has started executing a long-running operation. Similar
5417      * to {@link #startOp(String, int, String) except that if the mode is {@link #MODE_DEFAULT}
5418      * the operation should succeed since the caller has performed its standard permission
5419      * checks which passed and would perform the protected operation for this mode.
5420      *
5421      * @param op The operation to start.  One of the OP_* constants.
5422      * @param uid The user id of the application attempting to perform the operation.
5423      * @param packageName The name of the application attempting to perform the operation.
5424      * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5425      * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5426      * causing the app to crash).
5427      * @param startIfModeDefault Whether to start if mode is {@link #MODE_DEFAULT}.
5428      *
5429      * @throws SecurityException If the app has been configured to crash on this op or
5430      * the package is not in the passed in UID.
5431      *
5432      * @hide
5433      */
startOp(int op, int uid, String packageName, boolean startIfModeDefault)5434     public int startOp(int op, int uid, String packageName, boolean startIfModeDefault) {
5435         final int mode = startOpNoThrow(op, uid, packageName, startIfModeDefault);
5436         if (mode == MODE_ERRORED) {
5437             throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
5438         }
5439         return mode;
5440     }
5441 
5442     /**
5443      * Like {@link #startOp} but instead of throwing a {@link SecurityException} it
5444      * returns {@link #MODE_ERRORED}.
5445      * @hide
5446      */
startOpNoThrow(int op, int uid, String packageName)5447     public int startOpNoThrow(int op, int uid, String packageName) {
5448         return startOpNoThrow(op, uid, packageName, false);
5449     }
5450 
5451     /**
5452      * Like {@link #startOp(int, int, String, boolean)} but instead of throwing a
5453      * {@link SecurityException} it returns {@link #MODE_ERRORED}.
5454      *
5455      * @param op The operation to start.  One of the OP_* constants.
5456      * @param uid The user id of the application attempting to perform the operation.
5457      * @param packageName The name of the application attempting to perform the operation.
5458      * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5459      * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5460      * causing the app to crash).
5461      * @param startIfModeDefault Whether to start if mode is {@link #MODE_DEFAULT}.
5462      *
5463      * @hide
5464      */
startOpNoThrow(int op, int uid, String packageName, boolean startIfModeDefault)5465     public int startOpNoThrow(int op, int uid, String packageName, boolean startIfModeDefault) {
5466         try {
5467             return mService.startOperation(getToken(mService), op, uid, packageName,
5468                     startIfModeDefault);
5469         } catch (RemoteException e) {
5470             throw e.rethrowFromSystemServer();
5471         }
5472     }
5473 
5474     /**
5475      * Report that an application is no longer performing an operation that had previously
5476      * been started with {@link #startOp(int, int, String)}.  There is no validation of input
5477      * or result; the parameters supplied here must be the exact same ones previously passed
5478      * in when starting the operation.
5479      * @hide
5480      */
finishOp(int op, int uid, String packageName)5481     public void finishOp(int op, int uid, String packageName) {
5482         try {
5483             mService.finishOperation(getToken(mService), op, uid, packageName);
5484         } catch (RemoteException e) {
5485             throw e.rethrowFromSystemServer();
5486         }
5487     }
5488 
5489     /** @hide */
finishOp(int op)5490     public void finishOp(int op) {
5491         finishOp(op, Process.myUid(), mContext.getOpPackageName());
5492     }
5493 
5494     /**
5495      * Checks whether the given op for a UID and package is active.
5496      *
5497      * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
5498      * you can query only for your UID.
5499      *
5500      * @see #startWatchingActive(int[], OnOpActiveChangedListener)
5501      * @see #stopWatchingMode(OnOpChangedListener)
5502      * @see #finishOp(int)
5503      * @see #startOp(int)
5504      *
5505      * @hide */
5506     @TestApi
5507     // TODO: Uncomment below annotation once b/73559440 is fixed
5508     // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
isOperationActive(int code, int uid, String packageName)5509     public boolean isOperationActive(int code, int uid, String packageName) {
5510         try {
5511             return mService.isOperationActive(code, uid, packageName);
5512         } catch (RemoteException e) {
5513             throw e.rethrowFromSystemServer();
5514         }
5515     }
5516 
5517     /**
5518      * Configures the app ops persistence for testing.
5519      *
5520      * @param mode The mode in which the historical registry operates.
5521      * @param baseSnapshotInterval The base interval on which we would be persisting a snapshot of
5522      *   the historical data. The history is recursive where every subsequent step encompasses
5523      *   {@code compressionStep} longer interval with {@code compressionStep} distance between
5524      *    snapshots.
5525      * @param compressionStep The compression step in every iteration.
5526      *
5527      * @see #HISTORICAL_MODE_DISABLED
5528      * @see #HISTORICAL_MODE_ENABLED_ACTIVE
5529      * @see #HISTORICAL_MODE_ENABLED_PASSIVE
5530      *
5531      * @hide
5532      */
5533     @TestApi
5534     @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
setHistoryParameters(@istoricalMode int mode, long baseSnapshotInterval, int compressionStep)5535     public void setHistoryParameters(@HistoricalMode int mode, long baseSnapshotInterval,
5536             int compressionStep) {
5537         try {
5538             mService.setHistoryParameters(mode, baseSnapshotInterval, compressionStep);
5539         } catch (RemoteException e) {
5540             throw e.rethrowFromSystemServer();
5541         }
5542     }
5543 
5544     /**
5545      * Offsets the history by the given duration.
5546      *
5547      * @param offsetMillis The offset duration.
5548      *
5549      * @hide
5550      */
5551     @TestApi
5552     @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
offsetHistory(long offsetMillis)5553     public void offsetHistory(long offsetMillis) {
5554         try {
5555             mService.offsetHistory(offsetMillis);
5556         } catch (RemoteException e) {
5557             throw e.rethrowFromSystemServer();
5558         }
5559     }
5560 
5561     /**
5562      * Adds ops to the history directly. This could be useful for testing especially
5563      * when the historical registry operates in {@link #HISTORICAL_MODE_ENABLED_PASSIVE}
5564      * mode.
5565      *
5566      * @param ops The ops to add to the history.
5567      *
5568      * @see #setHistoryParameters(int, long, int)
5569      * @see #HISTORICAL_MODE_ENABLED_PASSIVE
5570      *
5571      * @hide
5572      */
5573     @TestApi
5574     @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
addHistoricalOps(@onNull HistoricalOps ops)5575     public void addHistoricalOps(@NonNull HistoricalOps ops) {
5576         try {
5577             mService.addHistoricalOps(ops);
5578         } catch (RemoteException e) {
5579             throw e.rethrowFromSystemServer();
5580         }
5581     }
5582 
5583     /**
5584      * Resets the app ops persistence for testing.
5585      *
5586      * @see #setHistoryParameters(int, long, int)
5587      *
5588      * @hide
5589      */
5590     @TestApi
5591     @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
resetHistoryParameters()5592     public void resetHistoryParameters() {
5593         try {
5594             mService.resetHistoryParameters();
5595         } catch (RemoteException e) {
5596             throw e.rethrowFromSystemServer();
5597         }
5598     }
5599 
5600     /**
5601      * Clears all app ops history.
5602      *
5603      * @hide
5604      */
5605     @TestApi
5606     @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
clearHistory()5607     public void clearHistory() {
5608         try {
5609             mService.clearHistory();
5610         } catch (RemoteException e) {
5611             throw e.rethrowFromSystemServer();
5612         }
5613     }
5614 
5615     /**
5616      * Returns all supported operation names.
5617      * @hide
5618      */
5619     @SystemApi
5620     @TestApi
getOpStrs()5621     public static String[] getOpStrs() {
5622         return Arrays.copyOf(sOpToString, sOpToString.length);
5623     }
5624 
5625 
5626     /**
5627      * @return number of App ops
5628      * @hide
5629      */
5630     @TestApi
getNumOps()5631     public static int getNumOps() {
5632         return _NUM_OP;
5633     }
5634 
5635     /**
5636      * Computes the max for the given flags in between the begin and
5637      * end UID states.
5638      *
5639      * @param counts The data array.
5640      * @param flags The UID flags.
5641      * @param beginUidState The beginning UID state (exclusive).
5642      * @param endUidState The end UID state.
5643      * @return The sum.
5644      */
maxForFlagsInStates(@ullable LongSparseLongArray counts, @UidState int beginUidState, @UidState int endUidState, @OpFlags int flags)5645     private static long maxForFlagsInStates(@Nullable LongSparseLongArray counts,
5646             @UidState int beginUidState, @UidState int endUidState,
5647             @OpFlags int flags) {
5648         if (counts == null) {
5649             return 0;
5650         }
5651         long max = 0;
5652         while (flags != 0) {
5653             final int flag = 1 << Integer.numberOfTrailingZeros(flags);
5654             flags &= ~flag;
5655             for (int uidState : UID_STATES) {
5656                 if (uidState < beginUidState || uidState > endUidState) {
5657                     continue;
5658                 }
5659                 final long key = makeKey(uidState, flag);
5660                 max = Math.max(max, counts.get(key));
5661             }
5662         }
5663         return max;
5664     }
5665 
5666 
writeLongSparseLongArrayToParcel( @ullable LongSparseLongArray array, @NonNull Parcel parcel)5667     private static void writeLongSparseLongArrayToParcel(
5668             @Nullable LongSparseLongArray array, @NonNull Parcel parcel) {
5669         if (array != null) {
5670             final int size = array.size();
5671             parcel.writeInt(size);
5672             for (int i = 0; i < size; i++) {
5673                 parcel.writeLong(array.keyAt(i));
5674                 parcel.writeLong(array.valueAt(i));
5675             }
5676         } else {
5677             parcel.writeInt(-1);
5678         }
5679     }
5680 
readLongSparseLongArrayFromParcel( @onNull Parcel parcel)5681     private static @Nullable LongSparseLongArray readLongSparseLongArrayFromParcel(
5682             @NonNull Parcel parcel) {
5683         final int size = parcel.readInt();
5684         if (size < 0) {
5685             return null;
5686         }
5687         final LongSparseLongArray array = new LongSparseLongArray(size);
5688         for (int i = 0; i < size; i++) {
5689             array.append(parcel.readLong(), parcel.readLong());
5690         }
5691         return array;
5692     }
5693 
writeLongSparseStringArrayToParcel( @ullable LongSparseArray<String> array, @NonNull Parcel parcel)5694     private static void writeLongSparseStringArrayToParcel(
5695             @Nullable LongSparseArray<String> array, @NonNull Parcel parcel) {
5696         if (array != null) {
5697             final int size = array.size();
5698             parcel.writeInt(size);
5699             for (int i = 0; i < size; i++) {
5700                 parcel.writeLong(array.keyAt(i));
5701                 parcel.writeString(array.valueAt(i));
5702             }
5703         } else {
5704             parcel.writeInt(-1);
5705         }
5706     }
5707 
readLongSparseStringArrayFromParcel( @onNull Parcel parcel)5708     private static @Nullable LongSparseArray<String> readLongSparseStringArrayFromParcel(
5709             @NonNull Parcel parcel) {
5710         final int size = parcel.readInt();
5711         if (size < 0) {
5712             return null;
5713         }
5714         final LongSparseArray<String> array = new LongSparseArray<>(size);
5715         for (int i = 0; i < size; i++) {
5716             array.append(parcel.readLong(), parcel.readString());
5717         }
5718         return array;
5719     }
5720 
5721     /**
5722      * Collects the keys from an array to the result creating the result if needed.
5723      *
5724      * @param array The array whose keys to collect.
5725      * @param result The optional result store collected keys.
5726      * @return The result collected keys array.
5727      */
collectKeys(@ullable LongSparseLongArray array, @Nullable LongSparseArray<Object> result)5728     private static LongSparseArray<Object> collectKeys(@Nullable LongSparseLongArray array,
5729             @Nullable LongSparseArray<Object> result) {
5730         if (array != null) {
5731             if (result == null) {
5732                 result = new LongSparseArray<>();
5733             }
5734             final int accessSize = array.size();
5735             for (int i = 0; i < accessSize; i++) {
5736                 result.put(array.keyAt(i), null);
5737             }
5738         }
5739         return result;
5740     }
5741 
5742     /** @hide */
uidStateToString(@idState int uidState)5743     public static String uidStateToString(@UidState int uidState) {
5744         switch (uidState) {
5745             case UID_STATE_PERSISTENT: {
5746                 return "UID_STATE_PERSISTENT";
5747             }
5748             case UID_STATE_TOP: {
5749                 return "UID_STATE_TOP";
5750             }
5751             case UID_STATE_FOREGROUND_SERVICE_LOCATION: {
5752                 return "UID_STATE_FOREGROUND_SERVICE_LOCATION";
5753             }
5754             case UID_STATE_FOREGROUND_SERVICE: {
5755                 return "UID_STATE_FOREGROUND_SERVICE";
5756             }
5757             case UID_STATE_FOREGROUND: {
5758                 return "UID_STATE_FOREGROUND";
5759             }
5760             case UID_STATE_BACKGROUND: {
5761                 return "UID_STATE_BACKGROUND";
5762             }
5763             case UID_STATE_CACHED: {
5764                 return "UID_STATE_CACHED";
5765             }
5766             default: {
5767                 return "UNKNOWN";
5768             }
5769         }
5770     }
5771 
5772     /** @hide */
parseHistoricalMode(@onNull String mode)5773     public static int parseHistoricalMode(@NonNull String mode) {
5774         switch (mode) {
5775             case "HISTORICAL_MODE_ENABLED_ACTIVE": {
5776                 return HISTORICAL_MODE_ENABLED_ACTIVE;
5777             }
5778             case "HISTORICAL_MODE_ENABLED_PASSIVE": {
5779                 return HISTORICAL_MODE_ENABLED_PASSIVE;
5780             }
5781             default: {
5782                 return HISTORICAL_MODE_DISABLED;
5783             }
5784         }
5785     }
5786 
5787     /** @hide */
historicalModeToString(@istoricalMode int mode)5788     public static String historicalModeToString(@HistoricalMode int mode) {
5789         switch (mode) {
5790             case HISTORICAL_MODE_DISABLED: {
5791                 return "HISTORICAL_MODE_DISABLED";
5792             }
5793             case HISTORICAL_MODE_ENABLED_ACTIVE: {
5794                 return "HISTORICAL_MODE_ENABLED_ACTIVE";
5795             }
5796             case HISTORICAL_MODE_ENABLED_PASSIVE: {
5797                 return "HISTORICAL_MODE_ENABLED_PASSIVE";
5798             }
5799             default: {
5800                 return "UNKNOWN";
5801             }
5802         }
5803     }
5804 
getSystemAlertWindowDefault()5805     private static int getSystemAlertWindowDefault() {
5806         final Context context = ActivityThread.currentApplication();
5807         if (context == null) {
5808             return AppOpsManager.MODE_DEFAULT;
5809         }
5810 
5811         // system alert window is disable on low ram phones starting from Q
5812         final PackageManager pm = context.getPackageManager();
5813         // TVs are constantly plugged in and has less concern for memory/power
5814         if (ActivityManager.isLowRamDeviceStatic()
5815                 && !pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK, 0)) {
5816             return AppOpsManager.MODE_IGNORED;
5817         }
5818 
5819         return AppOpsManager.MODE_DEFAULT;
5820     }
5821 }
5822