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