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