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