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.RequiresPermission;
     21 import android.annotation.SystemApi;
     22 import android.annotation.SystemService;
     23 import android.app.usage.UsageStatsManager;
     24 import android.content.Context;
     25 import android.media.AudioAttributes.AttributeUsage;
     26 import android.os.Binder;
     27 import android.os.IBinder;
     28 import android.os.Parcel;
     29 import android.os.Parcelable;
     30 import android.os.Process;
     31 import android.os.RemoteException;
     32 import android.os.UserHandle;
     33 import android.os.UserManager;
     34 import android.util.ArrayMap;
     35 
     36 import com.android.internal.app.IAppOpsCallback;
     37 import com.android.internal.app.IAppOpsService;
     38 
     39 import java.util.ArrayList;
     40 import java.util.HashMap;
     41 import java.util.List;
     42 
     43 /**
     44  * API for interacting with "application operation" tracking.
     45  *
     46  * <p>This API is not generally intended for third party application developers; most
     47  * features are only available to system applications.
     48  */
     49 @SystemService(Context.APP_OPS_SERVICE)
     50 public class AppOpsManager {
     51     /**
     52      * <p>App ops allows callers to:</p>
     53      *
     54      * <ul>
     55      * <li> Note when operations are happening, and find out if they are allowed for the current
     56      * caller.</li>
     57      * <li> Disallow specific apps from doing specific operations.</li>
     58      * <li> Collect all of the current information about operations that have been executed or
     59      * are not being allowed.</li>
     60      * <li> Monitor for changes in whether an operation is allowed.</li>
     61      * </ul>
     62      *
     63      * <p>Each operation is identified by a single integer; these integers are a fixed set of
     64      * operations, enumerated by the OP_* constants.
     65      *
     66      * <p></p>When checking operations, the result is a "mode" integer indicating the current
     67      * setting for the operation under that caller: MODE_ALLOWED, MODE_IGNORED (don't execute
     68      * the operation but fake its behavior enough so that the caller doesn't crash),
     69      * MODE_ERRORED (throw a SecurityException back to the caller; the normal operation calls
     70      * will do this for you).
     71      */
     72 
     73     final Context mContext;
     74     final IAppOpsService mService;
     75     final ArrayMap<OnOpChangedListener, IAppOpsCallback> mModeWatchers
     76             = new ArrayMap<OnOpChangedListener, IAppOpsCallback>();
     77 
     78     static IBinder sToken;
     79 
     80     /**
     81      * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is
     82      * allowed to perform the given operation.
     83      */
     84     public static final int MODE_ALLOWED = 0;
     85 
     86     /**
     87      * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is
     88      * not allowed to perform the given operation, and this attempt should
     89      * <em>silently fail</em> (it should not cause the app to crash).
     90      */
     91     public static final int MODE_IGNORED = 1;
     92 
     93     /**
     94      * Result from {@link #checkOpNoThrow}, {@link #noteOpNoThrow}, {@link #startOpNoThrow}: the
     95      * given caller is not allowed to perform the given operation, and this attempt should
     96      * cause it to have a fatal error, typically a {@link SecurityException}.
     97      */
     98     public static final int MODE_ERRORED = 2;
     99 
    100     /**
    101      * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller should
    102      * use its default security check.  This mode is not normally used; it should only be used
    103      * with appop permissions, and callers must explicitly check for it and deal with it.
    104      */
    105     public static final int MODE_DEFAULT = 3;
    106 
    107     // when adding one of these:
    108     //  - increment _NUM_OP
    109     //  - add rows to sOpToSwitch, sOpToString, sOpNames, sOpToPerms, sOpDefault
    110     //  - add descriptive strings to Settings/res/values/arrays.xml
    111     //  - add the op to the appropriate template in AppOpsState.OpsTemplate (settings app)
    112 
    113     /** @hide No operation specified. */
    114     public static final int OP_NONE = -1;
    115     /** @hide Access to coarse location information. */
    116     public static final int OP_COARSE_LOCATION = 0;
    117     /** @hide Access to fine location information. */
    118     public static final int OP_FINE_LOCATION = 1;
    119     /** @hide Causing GPS to run. */
    120     public static final int OP_GPS = 2;
    121     /** @hide */
    122     public static final int OP_VIBRATE = 3;
    123     /** @hide */
    124     public static final int OP_READ_CONTACTS = 4;
    125     /** @hide */
    126     public static final int OP_WRITE_CONTACTS = 5;
    127     /** @hide */
    128     public static final int OP_READ_CALL_LOG = 6;
    129     /** @hide */
    130     public static final int OP_WRITE_CALL_LOG = 7;
    131     /** @hide */
    132     public static final int OP_READ_CALENDAR = 8;
    133     /** @hide */
    134     public static final int OP_WRITE_CALENDAR = 9;
    135     /** @hide */
    136     public static final int OP_WIFI_SCAN = 10;
    137     /** @hide */
    138     public static final int OP_POST_NOTIFICATION = 11;
    139     /** @hide */
    140     public static final int OP_NEIGHBORING_CELLS = 12;
    141     /** @hide */
    142     public static final int OP_CALL_PHONE = 13;
    143     /** @hide */
    144     public static final int OP_READ_SMS = 14;
    145     /** @hide */
    146     public static final int OP_WRITE_SMS = 15;
    147     /** @hide */
    148     public static final int OP_RECEIVE_SMS = 16;
    149     /** @hide */
    150     public static final int OP_RECEIVE_EMERGECY_SMS = 17;
    151     /** @hide */
    152     public static final int OP_RECEIVE_MMS = 18;
    153     /** @hide */
    154     public static final int OP_RECEIVE_WAP_PUSH = 19;
    155     /** @hide */
    156     public static final int OP_SEND_SMS = 20;
    157     /** @hide */
    158     public static final int OP_READ_ICC_SMS = 21;
    159     /** @hide */
    160     public static final int OP_WRITE_ICC_SMS = 22;
    161     /** @hide */
    162     public static final int OP_WRITE_SETTINGS = 23;
    163     /** @hide */
    164     public static final int OP_SYSTEM_ALERT_WINDOW = 24;
    165     /** @hide */
    166     public static final int OP_ACCESS_NOTIFICATIONS = 25;
    167     /** @hide */
    168     public static final int OP_CAMERA = 26;
    169     /** @hide */
    170     public static final int OP_RECORD_AUDIO = 27;
    171     /** @hide */
    172     public static final int OP_PLAY_AUDIO = 28;
    173     /** @hide */
    174     public static final int OP_READ_CLIPBOARD = 29;
    175     /** @hide */
    176     public static final int OP_WRITE_CLIPBOARD = 30;
    177     /** @hide */
    178     public static final int OP_TAKE_MEDIA_BUTTONS = 31;
    179     /** @hide */
    180     public static final int OP_TAKE_AUDIO_FOCUS = 32;
    181     /** @hide */
    182     public static final int OP_AUDIO_MASTER_VOLUME = 33;
    183     /** @hide */
    184     public static final int OP_AUDIO_VOICE_VOLUME = 34;
    185     /** @hide */
    186     public static final int OP_AUDIO_RING_VOLUME = 35;
    187     /** @hide */
    188     public static final int OP_AUDIO_MEDIA_VOLUME = 36;
    189     /** @hide */
    190     public static final int OP_AUDIO_ALARM_VOLUME = 37;
    191     /** @hide */
    192     public static final int OP_AUDIO_NOTIFICATION_VOLUME = 38;
    193     /** @hide */
    194     public static final int OP_AUDIO_BLUETOOTH_VOLUME = 39;
    195     /** @hide */
    196     public static final int OP_WAKE_LOCK = 40;
    197     /** @hide Continually monitoring location data. */
    198     public static final int OP_MONITOR_LOCATION = 41;
    199     /** @hide Continually monitoring location data with a relatively high power request. */
    200     public static final int OP_MONITOR_HIGH_POWER_LOCATION = 42;
    201     /** @hide Retrieve current usage stats via {@link UsageStatsManager}. */
    202     public static final int OP_GET_USAGE_STATS = 43;
    203     /** @hide */
    204     public static final int OP_MUTE_MICROPHONE = 44;
    205     /** @hide */
    206     public static final int OP_TOAST_WINDOW = 45;
    207     /** @hide Capture the device's display contents and/or audio */
    208     public static final int OP_PROJECT_MEDIA = 46;
    209     /** @hide Activate a VPN connection without user intervention. */
    210     public static final int OP_ACTIVATE_VPN = 47;
    211     /** @hide Access the WallpaperManagerAPI to write wallpapers. */
    212     public static final int OP_WRITE_WALLPAPER = 48;
    213     /** @hide Received the assist structure from an app. */
    214     public static final int OP_ASSIST_STRUCTURE = 49;
    215     /** @hide Received a screenshot from assist. */
    216     public static final int OP_ASSIST_SCREENSHOT = 50;
    217     /** @hide Read the phone state. */
    218     public static final int OP_READ_PHONE_STATE = 51;
    219     /** @hide Add voicemail messages to the voicemail content provider. */
    220     public static final int OP_ADD_VOICEMAIL = 52;
    221     /** @hide Access APIs for SIP calling over VOIP or WiFi. */
    222     public static final int OP_USE_SIP = 53;
    223     /** @hide Intercept outgoing calls. */
    224     public static final int OP_PROCESS_OUTGOING_CALLS = 54;
    225     /** @hide User the fingerprint API. */
    226     public static final int OP_USE_FINGERPRINT = 55;
    227     /** @hide Access to body sensors such as heart rate, etc. */
    228     public static final int OP_BODY_SENSORS = 56;
    229     /** @hide Read previously received cell broadcast messages. */
    230     public static final int OP_READ_CELL_BROADCASTS = 57;
    231     /** @hide Inject mock location into the system. */
    232     public static final int OP_MOCK_LOCATION = 58;
    233     /** @hide Read external storage. */
    234     public static final int OP_READ_EXTERNAL_STORAGE = 59;
    235     /** @hide Write external storage. */
    236     public static final int OP_WRITE_EXTERNAL_STORAGE = 60;
    237     /** @hide Turned on the screen. */
    238     public static final int OP_TURN_SCREEN_ON = 61;
    239     /** @hide Get device accounts. */
    240     public static final int OP_GET_ACCOUNTS = 62;
    241     /** @hide Control whether an application is allowed to run in the background. */
    242     public static final int OP_RUN_IN_BACKGROUND = 63;
    243     /** @hide */
    244     public static final int OP_AUDIO_ACCESSIBILITY_VOLUME = 64;
    245     /** @hide Read the phone number. */
    246     public static final int OP_READ_PHONE_NUMBERS = 65;
    247     /** @hide Request package installs through package installer */
    248     public static final int OP_REQUEST_INSTALL_PACKAGES = 66;
    249     /** @hide Enter picture-in-picture. */
    250     public static final int OP_PICTURE_IN_PICTURE = 67;
    251     /** @hide Instant app start foreground service. */
    252     public static final int OP_INSTANT_APP_START_FOREGROUND = 68;
    253     /** @hide Answer incoming phone calls */
    254     public static final int OP_ANSWER_PHONE_CALLS = 69;
    255     /** @hide */
    256     public static final int _NUM_OP = 70;
    257 
    258     /** Access to coarse location information. */
    259     public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
    260     /** Access to fine location information. */
    261     public static final String OPSTR_FINE_LOCATION =
    262             "android:fine_location";
    263     /** Continually monitoring location data. */
    264     public static final String OPSTR_MONITOR_LOCATION
    265             = "android:monitor_location";
    266     /** Continually monitoring location data with a relatively high power request. */
    267     public static final String OPSTR_MONITOR_HIGH_POWER_LOCATION
    268             = "android:monitor_location_high_power";
    269     /** Access to {@link android.app.usage.UsageStatsManager}. */
    270     public static final String OPSTR_GET_USAGE_STATS
    271             = "android:get_usage_stats";
    272     /** Activate a VPN connection without user intervention. @hide */
    273     @SystemApi
    274     public static final String OPSTR_ACTIVATE_VPN
    275             = "android:activate_vpn";
    276     /** Allows an application to read the user's contacts data. */
    277     public static final String OPSTR_READ_CONTACTS
    278             = "android:read_contacts";
    279     /** Allows an application to write to the user's contacts data. */
    280     public static final String OPSTR_WRITE_CONTACTS
    281             = "android:write_contacts";
    282     /** Allows an application to read the user's call log. */
    283     public static final String OPSTR_READ_CALL_LOG
    284             = "android:read_call_log";
    285     /** Allows an application to write to the user's call log. */
    286     public static final String OPSTR_WRITE_CALL_LOG
    287             = "android:write_call_log";
    288     /** Allows an application to read the user's calendar data. */
    289     public static final String OPSTR_READ_CALENDAR
    290             = "android:read_calendar";
    291     /** Allows an application to write to the user's calendar data. */
    292     public static final String OPSTR_WRITE_CALENDAR
    293             = "android:write_calendar";
    294     /** Allows an application to initiate a phone call. */
    295     public static final String OPSTR_CALL_PHONE
    296             = "android:call_phone";
    297     /** Allows an application to read SMS messages. */
    298     public static final String OPSTR_READ_SMS
    299             = "android:read_sms";
    300     /** Allows an application to receive SMS messages. */
    301     public static final String OPSTR_RECEIVE_SMS
    302             = "android:receive_sms";
    303     /** Allows an application to receive MMS messages. */
    304     public static final String OPSTR_RECEIVE_MMS
    305             = "android:receive_mms";
    306     /** Allows an application to receive WAP push messages. */
    307     public static final String OPSTR_RECEIVE_WAP_PUSH
    308             = "android:receive_wap_push";
    309     /** Allows an application to send SMS messages. */
    310     public static final String OPSTR_SEND_SMS
    311             = "android:send_sms";
    312     /** Required to be able to access the camera device. */
    313     public static final String OPSTR_CAMERA
    314             = "android:camera";
    315     /** Required to be able to access the microphone device. */
    316     public static final String OPSTR_RECORD_AUDIO
    317             = "android:record_audio";
    318     /** Required to access phone state related information. */
    319     public static final String OPSTR_READ_PHONE_STATE
    320             = "android:read_phone_state";
    321     /** Required to access phone state related information. */
    322     public static final String OPSTR_ADD_VOICEMAIL
    323             = "android:add_voicemail";
    324     /** Access APIs for SIP calling over VOIP or WiFi */
    325     public static final String OPSTR_USE_SIP
    326             = "android:use_sip";
    327     /** Access APIs for diverting outgoing calls */
    328     public static final String OPSTR_PROCESS_OUTGOING_CALLS
    329             = "android:process_outgoing_calls";
    330     /** Use the fingerprint API. */
    331     public static final String OPSTR_USE_FINGERPRINT
    332             = "android:use_fingerprint";
    333     /** Access to body sensors such as heart rate, etc. */
    334     public static final String OPSTR_BODY_SENSORS
    335             = "android:body_sensors";
    336     /** Read previously received cell broadcast messages. */
    337     public static final String OPSTR_READ_CELL_BROADCASTS
    338             = "android:read_cell_broadcasts";
    339     /** Inject mock location into the system. */
    340     public static final String OPSTR_MOCK_LOCATION
    341             = "android:mock_location";
    342     /** Read external storage. */
    343     public static final String OPSTR_READ_EXTERNAL_STORAGE
    344             = "android:read_external_storage";
    345     /** Write external storage. */
    346     public static final String OPSTR_WRITE_EXTERNAL_STORAGE
    347             = "android:write_external_storage";
    348     /** Required to draw on top of other apps. */
    349     public static final String OPSTR_SYSTEM_ALERT_WINDOW
    350             = "android:system_alert_window";
    351     /** Required to write/modify/update system settingss. */
    352     public static final String OPSTR_WRITE_SETTINGS
    353             = "android:write_settings";
    354     /** @hide Get device accounts. */
    355     public static final String OPSTR_GET_ACCOUNTS
    356             = "android:get_accounts";
    357     public static final String OPSTR_READ_PHONE_NUMBERS
    358             = "android:read_phone_numbers";
    359     /** Access to picture-in-picture. */
    360     public static final String OPSTR_PICTURE_IN_PICTURE
    361             = "android:picture_in_picture";
    362     /** @hide */
    363     public static final String OPSTR_INSTANT_APP_START_FOREGROUND
    364             = "android:instant_app_start_foreground";
    365     /** Answer incoming phone calls */
    366     public static final String OPSTR_ANSWER_PHONE_CALLS
    367             = "android:answer_phone_calls";
    368 
    369     // Warning: If an permission is added here it also has to be added to
    370     // com.android.packageinstaller.permission.utils.EventLogger
    371     private static final int[] RUNTIME_AND_APPOP_PERMISSIONS_OPS = {
    372             // RUNTIME PERMISSIONS
    373             // Contacts
    374             OP_READ_CONTACTS,
    375             OP_WRITE_CONTACTS,
    376             OP_GET_ACCOUNTS,
    377             // Calendar
    378             OP_READ_CALENDAR,
    379             OP_WRITE_CALENDAR,
    380             // SMS
    381             OP_SEND_SMS,
    382             OP_RECEIVE_SMS,
    383             OP_READ_SMS,
    384             OP_RECEIVE_WAP_PUSH,
    385             OP_RECEIVE_MMS,
    386             OP_READ_CELL_BROADCASTS,
    387             // Storage
    388             OP_READ_EXTERNAL_STORAGE,
    389             OP_WRITE_EXTERNAL_STORAGE,
    390             // Location
    391             OP_COARSE_LOCATION,
    392             OP_FINE_LOCATION,
    393             // Phone
    394             OP_READ_PHONE_STATE,
    395             OP_READ_PHONE_NUMBERS,
    396             OP_CALL_PHONE,
    397             OP_READ_CALL_LOG,
    398             OP_WRITE_CALL_LOG,
    399             OP_ADD_VOICEMAIL,
    400             OP_USE_SIP,
    401             OP_PROCESS_OUTGOING_CALLS,
    402             OP_ANSWER_PHONE_CALLS,
    403             // Microphone
    404             OP_RECORD_AUDIO,
    405             // Camera
    406             OP_CAMERA,
    407             // Body sensors
    408             OP_BODY_SENSORS,
    409 
    410             // APPOP PERMISSIONS
    411             OP_ACCESS_NOTIFICATIONS,
    412             OP_SYSTEM_ALERT_WINDOW,
    413             OP_WRITE_SETTINGS,
    414             OP_REQUEST_INSTALL_PACKAGES,
    415     };
    416 
    417     /**
    418      * This maps each operation to the operation that serves as the
    419      * switch to determine whether it is allowed.  Generally this is
    420      * a 1:1 mapping, but for some things (like location) that have
    421      * multiple low-level operations being tracked that should be
    422      * presented to the user as one switch then this can be used to
    423      * make them all controlled by the same single operation.
    424      */
    425     private static int[] sOpToSwitch = new int[] {
    426             OP_COARSE_LOCATION,
    427             OP_COARSE_LOCATION,
    428             OP_COARSE_LOCATION,
    429             OP_VIBRATE,
    430             OP_READ_CONTACTS,
    431             OP_WRITE_CONTACTS,
    432             OP_READ_CALL_LOG,
    433             OP_WRITE_CALL_LOG,
    434             OP_READ_CALENDAR,
    435             OP_WRITE_CALENDAR,
    436             OP_COARSE_LOCATION,
    437             OP_POST_NOTIFICATION,
    438             OP_COARSE_LOCATION,
    439             OP_CALL_PHONE,
    440             OP_READ_SMS,
    441             OP_WRITE_SMS,
    442             OP_RECEIVE_SMS,
    443             OP_RECEIVE_SMS,
    444             OP_RECEIVE_MMS,
    445             OP_RECEIVE_WAP_PUSH,
    446             OP_SEND_SMS,
    447             OP_READ_SMS,
    448             OP_WRITE_SMS,
    449             OP_WRITE_SETTINGS,
    450             OP_SYSTEM_ALERT_WINDOW,
    451             OP_ACCESS_NOTIFICATIONS,
    452             OP_CAMERA,
    453             OP_RECORD_AUDIO,
    454             OP_PLAY_AUDIO,
    455             OP_READ_CLIPBOARD,
    456             OP_WRITE_CLIPBOARD,
    457             OP_TAKE_MEDIA_BUTTONS,
    458             OP_TAKE_AUDIO_FOCUS,
    459             OP_AUDIO_MASTER_VOLUME,
    460             OP_AUDIO_VOICE_VOLUME,
    461             OP_AUDIO_RING_VOLUME,
    462             OP_AUDIO_MEDIA_VOLUME,
    463             OP_AUDIO_ALARM_VOLUME,
    464             OP_AUDIO_NOTIFICATION_VOLUME,
    465             OP_AUDIO_BLUETOOTH_VOLUME,
    466             OP_WAKE_LOCK,
    467             OP_COARSE_LOCATION,
    468             OP_COARSE_LOCATION,
    469             OP_GET_USAGE_STATS,
    470             OP_MUTE_MICROPHONE,
    471             OP_TOAST_WINDOW,
    472             OP_PROJECT_MEDIA,
    473             OP_ACTIVATE_VPN,
    474             OP_WRITE_WALLPAPER,
    475             OP_ASSIST_STRUCTURE,
    476             OP_ASSIST_SCREENSHOT,
    477             OP_READ_PHONE_STATE,
    478             OP_ADD_VOICEMAIL,
    479             OP_USE_SIP,
    480             OP_PROCESS_OUTGOING_CALLS,
    481             OP_USE_FINGERPRINT,
    482             OP_BODY_SENSORS,
    483             OP_READ_CELL_BROADCASTS,
    484             OP_MOCK_LOCATION,
    485             OP_READ_EXTERNAL_STORAGE,
    486             OP_WRITE_EXTERNAL_STORAGE,
    487             OP_TURN_SCREEN_ON,
    488             OP_GET_ACCOUNTS,
    489             OP_RUN_IN_BACKGROUND,
    490             OP_AUDIO_ACCESSIBILITY_VOLUME,
    491             OP_READ_PHONE_NUMBERS,
    492             OP_REQUEST_INSTALL_PACKAGES,
    493             OP_PICTURE_IN_PICTURE,
    494             OP_INSTANT_APP_START_FOREGROUND,
    495             OP_ANSWER_PHONE_CALLS
    496     };
    497 
    498     /**
    499      * This maps each operation to the public string constant for it.
    500      * If it doesn't have a public string constant, it maps to null.
    501      */
    502     private static String[] sOpToString = new String[] {
    503             OPSTR_COARSE_LOCATION,
    504             OPSTR_FINE_LOCATION,
    505             null,
    506             null,
    507             OPSTR_READ_CONTACTS,
    508             OPSTR_WRITE_CONTACTS,
    509             OPSTR_READ_CALL_LOG,
    510             OPSTR_WRITE_CALL_LOG,
    511             OPSTR_READ_CALENDAR,
    512             OPSTR_WRITE_CALENDAR,
    513             null,
    514             null,
    515             null,
    516             OPSTR_CALL_PHONE,
    517             OPSTR_READ_SMS,
    518             null,
    519             OPSTR_RECEIVE_SMS,
    520             null,
    521             OPSTR_RECEIVE_MMS,
    522             OPSTR_RECEIVE_WAP_PUSH,
    523             OPSTR_SEND_SMS,
    524             null,
    525             null,
    526             OPSTR_WRITE_SETTINGS,
    527             OPSTR_SYSTEM_ALERT_WINDOW,
    528             null,
    529             OPSTR_CAMERA,
    530             OPSTR_RECORD_AUDIO,
    531             null,
    532             null,
    533             null,
    534             null,
    535             null,
    536             null,
    537             null,
    538             null,
    539             null,
    540             null,
    541             null,
    542             null,
    543             null,
    544             OPSTR_MONITOR_LOCATION,
    545             OPSTR_MONITOR_HIGH_POWER_LOCATION,
    546             OPSTR_GET_USAGE_STATS,
    547             null,
    548             null,
    549             null,
    550             OPSTR_ACTIVATE_VPN,
    551             null,
    552             null,
    553             null,
    554             OPSTR_READ_PHONE_STATE,
    555             OPSTR_ADD_VOICEMAIL,
    556             OPSTR_USE_SIP,
    557             OPSTR_PROCESS_OUTGOING_CALLS,
    558             OPSTR_USE_FINGERPRINT,
    559             OPSTR_BODY_SENSORS,
    560             OPSTR_READ_CELL_BROADCASTS,
    561             OPSTR_MOCK_LOCATION,
    562             OPSTR_READ_EXTERNAL_STORAGE,
    563             OPSTR_WRITE_EXTERNAL_STORAGE,
    564             null,
    565             OPSTR_GET_ACCOUNTS,
    566             null,
    567             null, // OP_AUDIO_ACCESSIBILITY_VOLUME
    568             OPSTR_READ_PHONE_NUMBERS,
    569             null, // OP_REQUEST_INSTALL_PACKAGES
    570             OPSTR_PICTURE_IN_PICTURE,
    571             OPSTR_INSTANT_APP_START_FOREGROUND,
    572             OPSTR_ANSWER_PHONE_CALLS,
    573     };
    574 
    575     /**
    576      * This provides a simple name for each operation to be used
    577      * in debug output.
    578      */
    579     private static String[] sOpNames = new String[] {
    580             "COARSE_LOCATION",
    581             "FINE_LOCATION",
    582             "GPS",
    583             "VIBRATE",
    584             "READ_CONTACTS",
    585             "WRITE_CONTACTS",
    586             "READ_CALL_LOG",
    587             "WRITE_CALL_LOG",
    588             "READ_CALENDAR",
    589             "WRITE_CALENDAR",
    590             "WIFI_SCAN",
    591             "POST_NOTIFICATION",
    592             "NEIGHBORING_CELLS",
    593             "CALL_PHONE",
    594             "READ_SMS",
    595             "WRITE_SMS",
    596             "RECEIVE_SMS",
    597             "RECEIVE_EMERGECY_SMS",
    598             "RECEIVE_MMS",
    599             "RECEIVE_WAP_PUSH",
    600             "SEND_SMS",
    601             "READ_ICC_SMS",
    602             "WRITE_ICC_SMS",
    603             "WRITE_SETTINGS",
    604             "SYSTEM_ALERT_WINDOW",
    605             "ACCESS_NOTIFICATIONS",
    606             "CAMERA",
    607             "RECORD_AUDIO",
    608             "PLAY_AUDIO",
    609             "READ_CLIPBOARD",
    610             "WRITE_CLIPBOARD",
    611             "TAKE_MEDIA_BUTTONS",
    612             "TAKE_AUDIO_FOCUS",
    613             "AUDIO_MASTER_VOLUME",
    614             "AUDIO_VOICE_VOLUME",
    615             "AUDIO_RING_VOLUME",
    616             "AUDIO_MEDIA_VOLUME",
    617             "AUDIO_ALARM_VOLUME",
    618             "AUDIO_NOTIFICATION_VOLUME",
    619             "AUDIO_BLUETOOTH_VOLUME",
    620             "WAKE_LOCK",
    621             "MONITOR_LOCATION",
    622             "MONITOR_HIGH_POWER_LOCATION",
    623             "GET_USAGE_STATS",
    624             "MUTE_MICROPHONE",
    625             "TOAST_WINDOW",
    626             "PROJECT_MEDIA",
    627             "ACTIVATE_VPN",
    628             "WRITE_WALLPAPER",
    629             "ASSIST_STRUCTURE",
    630             "ASSIST_SCREENSHOT",
    631             "OP_READ_PHONE_STATE",
    632             "ADD_VOICEMAIL",
    633             "USE_SIP",
    634             "PROCESS_OUTGOING_CALLS",
    635             "USE_FINGERPRINT",
    636             "BODY_SENSORS",
    637             "READ_CELL_BROADCASTS",
    638             "MOCK_LOCATION",
    639             "READ_EXTERNAL_STORAGE",
    640             "WRITE_EXTERNAL_STORAGE",
    641             "TURN_ON_SCREEN",
    642             "GET_ACCOUNTS",
    643             "RUN_IN_BACKGROUND",
    644             "AUDIO_ACCESSIBILITY_VOLUME",
    645             "READ_PHONE_NUMBERS",
    646             "REQUEST_INSTALL_PACKAGES",
    647             "PICTURE_IN_PICTURE",
    648             "INSTANT_APP_START_FOREGROUND",
    649             "ANSWER_PHONE_CALLS",
    650     };
    651 
    652     /**
    653      * This optionally maps a permission to an operation.  If there
    654      * is no permission associated with an operation, it is null.
    655      */
    656     private static String[] sOpPerms = new String[] {
    657             android.Manifest.permission.ACCESS_COARSE_LOCATION,
    658             android.Manifest.permission.ACCESS_FINE_LOCATION,
    659             null,
    660             android.Manifest.permission.VIBRATE,
    661             android.Manifest.permission.READ_CONTACTS,
    662             android.Manifest.permission.WRITE_CONTACTS,
    663             android.Manifest.permission.READ_CALL_LOG,
    664             android.Manifest.permission.WRITE_CALL_LOG,
    665             android.Manifest.permission.READ_CALENDAR,
    666             android.Manifest.permission.WRITE_CALENDAR,
    667             android.Manifest.permission.ACCESS_WIFI_STATE,
    668             null, // no permission required for notifications
    669             null, // neighboring cells shares the coarse location perm
    670             android.Manifest.permission.CALL_PHONE,
    671             android.Manifest.permission.READ_SMS,
    672             null, // no permission required for writing sms
    673             android.Manifest.permission.RECEIVE_SMS,
    674             android.Manifest.permission.RECEIVE_EMERGENCY_BROADCAST,
    675             android.Manifest.permission.RECEIVE_MMS,
    676             android.Manifest.permission.RECEIVE_WAP_PUSH,
    677             android.Manifest.permission.SEND_SMS,
    678             android.Manifest.permission.READ_SMS,
    679             null, // no permission required for writing icc sms
    680             android.Manifest.permission.WRITE_SETTINGS,
    681             android.Manifest.permission.SYSTEM_ALERT_WINDOW,
    682             android.Manifest.permission.ACCESS_NOTIFICATIONS,
    683             android.Manifest.permission.CAMERA,
    684             android.Manifest.permission.RECORD_AUDIO,
    685             null, // no permission for playing audio
    686             null, // no permission for reading clipboard
    687             null, // no permission for writing clipboard
    688             null, // no permission for taking media buttons
    689             null, // no permission for taking audio focus
    690             null, // no permission for changing master volume
    691             null, // no permission for changing voice volume
    692             null, // no permission for changing ring volume
    693             null, // no permission for changing media volume
    694             null, // no permission for changing alarm volume
    695             null, // no permission for changing notification volume
    696             null, // no permission for changing bluetooth volume
    697             android.Manifest.permission.WAKE_LOCK,
    698             null, // no permission for generic location monitoring
    699             null, // no permission for high power location monitoring
    700             android.Manifest.permission.PACKAGE_USAGE_STATS,
    701             null, // no permission for muting/unmuting microphone
    702             null, // no permission for displaying toasts
    703             null, // no permission for projecting media
    704             null, // no permission for activating vpn
    705             null, // no permission for supporting wallpaper
    706             null, // no permission for receiving assist structure
    707             null, // no permission for receiving assist screenshot
    708             Manifest.permission.READ_PHONE_STATE,
    709             Manifest.permission.ADD_VOICEMAIL,
    710             Manifest.permission.USE_SIP,
    711             Manifest.permission.PROCESS_OUTGOING_CALLS,
    712             Manifest.permission.USE_FINGERPRINT,
    713             Manifest.permission.BODY_SENSORS,
    714             Manifest.permission.READ_CELL_BROADCASTS,
    715             null,
    716             Manifest.permission.READ_EXTERNAL_STORAGE,
    717             Manifest.permission.WRITE_EXTERNAL_STORAGE,
    718             null, // no permission for turning the screen on
    719             Manifest.permission.GET_ACCOUNTS,
    720             null, // no permission for running in background
    721             null, // no permission for changing accessibility volume
    722             Manifest.permission.READ_PHONE_NUMBERS,
    723             Manifest.permission.REQUEST_INSTALL_PACKAGES,
    724             null, // no permission for entering picture-in-picture on hide
    725             Manifest.permission.INSTANT_APP_FOREGROUND_SERVICE,
    726             Manifest.permission.ANSWER_PHONE_CALLS,
    727     };
    728 
    729     /**
    730      * Specifies whether an Op should be restricted by a user restriction.
    731      * Each Op should be filled with a restriction string from UserManager or
    732      * null to specify it is not affected by any user restriction.
    733      */
    734     private static String[] sOpRestrictions = new String[] {
    735             UserManager.DISALLOW_SHARE_LOCATION, //COARSE_LOCATION
    736             UserManager.DISALLOW_SHARE_LOCATION, //FINE_LOCATION
    737             UserManager.DISALLOW_SHARE_LOCATION, //GPS
    738             null, //VIBRATE
    739             null, //READ_CONTACTS
    740             null, //WRITE_CONTACTS
    741             UserManager.DISALLOW_OUTGOING_CALLS, //READ_CALL_LOG
    742             UserManager.DISALLOW_OUTGOING_CALLS, //WRITE_CALL_LOG
    743             null, //READ_CALENDAR
    744             null, //WRITE_CALENDAR
    745             UserManager.DISALLOW_SHARE_LOCATION, //WIFI_SCAN
    746             null, //POST_NOTIFICATION
    747             null, //NEIGHBORING_CELLS
    748             null, //CALL_PHONE
    749             UserManager.DISALLOW_SMS, //READ_SMS
    750             UserManager.DISALLOW_SMS, //WRITE_SMS
    751             UserManager.DISALLOW_SMS, //RECEIVE_SMS
    752             null, //RECEIVE_EMERGENCY_SMS
    753             UserManager.DISALLOW_SMS, //RECEIVE_MMS
    754             null, //RECEIVE_WAP_PUSH
    755             UserManager.DISALLOW_SMS, //SEND_SMS
    756             UserManager.DISALLOW_SMS, //READ_ICC_SMS
    757             UserManager.DISALLOW_SMS, //WRITE_ICC_SMS
    758             null, //WRITE_SETTINGS
    759             UserManager.DISALLOW_CREATE_WINDOWS, //SYSTEM_ALERT_WINDOW
    760             null, //ACCESS_NOTIFICATIONS
    761             UserManager.DISALLOW_CAMERA, //CAMERA
    762             UserManager.DISALLOW_RECORD_AUDIO, //RECORD_AUDIO
    763             null, //PLAY_AUDIO
    764             null, //READ_CLIPBOARD
    765             null, //WRITE_CLIPBOARD
    766             null, //TAKE_MEDIA_BUTTONS
    767             null, //TAKE_AUDIO_FOCUS
    768             UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MASTER_VOLUME
    769             UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_VOICE_VOLUME
    770             UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_RING_VOLUME
    771             UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MEDIA_VOLUME
    772             UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ALARM_VOLUME
    773             UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_NOTIFICATION_VOLUME
    774             UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_BLUETOOTH_VOLUME
    775             null, //WAKE_LOCK
    776             UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_LOCATION
    777             UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_HIGH_POWER_LOCATION
    778             null, //GET_USAGE_STATS
    779             UserManager.DISALLOW_UNMUTE_MICROPHONE, // MUTE_MICROPHONE
    780             UserManager.DISALLOW_CREATE_WINDOWS, // TOAST_WINDOW
    781             null, //PROJECT_MEDIA
    782             null, // ACTIVATE_VPN
    783             UserManager.DISALLOW_WALLPAPER, // WRITE_WALLPAPER
    784             null, // ASSIST_STRUCTURE
    785             null, // ASSIST_SCREENSHOT
    786             null, // READ_PHONE_STATE
    787             null, // ADD_VOICEMAIL
    788             null, // USE_SIP
    789             null, // PROCESS_OUTGOING_CALLS
    790             null, // USE_FINGERPRINT
    791             null, // BODY_SENSORS
    792             null, // READ_CELL_BROADCASTS
    793             null, // MOCK_LOCATION
    794             null, // READ_EXTERNAL_STORAGE
    795             null, // WRITE_EXTERNAL_STORAGE
    796             null, // TURN_ON_SCREEN
    797             null, // GET_ACCOUNTS
    798             null, // RUN_IN_BACKGROUND
    799             UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ACCESSIBILITY_VOLUME
    800             null, // READ_PHONE_NUMBERS
    801             null, // REQUEST_INSTALL_PACKAGES
    802             null, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
    803             null, // INSTANT_APP_START_FOREGROUND
    804             null, // ANSWER_PHONE_CALLS
    805     };
    806 
    807     /**
    808      * This specifies whether each option should allow the system
    809      * (and system ui) to bypass the user restriction when active.
    810      */
    811     private static boolean[] sOpAllowSystemRestrictionBypass = new boolean[] {
    812             true, //COARSE_LOCATION
    813             true, //FINE_LOCATION
    814             false, //GPS
    815             false, //VIBRATE
    816             false, //READ_CONTACTS
    817             false, //WRITE_CONTACTS
    818             false, //READ_CALL_LOG
    819             false, //WRITE_CALL_LOG
    820             false, //READ_CALENDAR
    821             false, //WRITE_CALENDAR
    822             true, //WIFI_SCAN
    823             false, //POST_NOTIFICATION
    824             false, //NEIGHBORING_CELLS
    825             false, //CALL_PHONE
    826             false, //READ_SMS
    827             false, //WRITE_SMS
    828             false, //RECEIVE_SMS
    829             false, //RECEIVE_EMERGECY_SMS
    830             false, //RECEIVE_MMS
    831             false, //RECEIVE_WAP_PUSH
    832             false, //SEND_SMS
    833             false, //READ_ICC_SMS
    834             false, //WRITE_ICC_SMS
    835             false, //WRITE_SETTINGS
    836             true, //SYSTEM_ALERT_WINDOW
    837             false, //ACCESS_NOTIFICATIONS
    838             false, //CAMERA
    839             false, //RECORD_AUDIO
    840             false, //PLAY_AUDIO
    841             false, //READ_CLIPBOARD
    842             false, //WRITE_CLIPBOARD
    843             false, //TAKE_MEDIA_BUTTONS
    844             false, //TAKE_AUDIO_FOCUS
    845             false, //AUDIO_MASTER_VOLUME
    846             false, //AUDIO_VOICE_VOLUME
    847             false, //AUDIO_RING_VOLUME
    848             false, //AUDIO_MEDIA_VOLUME
    849             false, //AUDIO_ALARM_VOLUME
    850             false, //AUDIO_NOTIFICATION_VOLUME
    851             false, //AUDIO_BLUETOOTH_VOLUME
    852             false, //WAKE_LOCK
    853             false, //MONITOR_LOCATION
    854             false, //MONITOR_HIGH_POWER_LOCATION
    855             false, //GET_USAGE_STATS
    856             false, //MUTE_MICROPHONE
    857             true, //TOAST_WINDOW
    858             false, //PROJECT_MEDIA
    859             false, //ACTIVATE_VPN
    860             false, //WALLPAPER
    861             false, //ASSIST_STRUCTURE
    862             false, //ASSIST_SCREENSHOT
    863             false, //READ_PHONE_STATE
    864             false, //ADD_VOICEMAIL
    865             false, // USE_SIP
    866             false, // PROCESS_OUTGOING_CALLS
    867             false, // USE_FINGERPRINT
    868             false, // BODY_SENSORS
    869             false, // READ_CELL_BROADCASTS
    870             false, // MOCK_LOCATION
    871             false, // READ_EXTERNAL_STORAGE
    872             false, // WRITE_EXTERNAL_STORAGE
    873             false, // TURN_ON_SCREEN
    874             false, // GET_ACCOUNTS
    875             false, // RUN_IN_BACKGROUND
    876             false, // AUDIO_ACCESSIBILITY_VOLUME
    877             false, // READ_PHONE_NUMBERS
    878             false, // REQUEST_INSTALL_PACKAGES
    879             false, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
    880             false, // INSTANT_APP_START_FOREGROUND
    881             false, // ANSWER_PHONE_CALLS
    882     };
    883 
    884     /**
    885      * This specifies the default mode for each operation.
    886      */
    887     private static int[] sOpDefaultMode = new int[] {
    888             AppOpsManager.MODE_ALLOWED,
    889             AppOpsManager.MODE_ALLOWED,
    890             AppOpsManager.MODE_ALLOWED,
    891             AppOpsManager.MODE_ALLOWED,
    892             AppOpsManager.MODE_ALLOWED,
    893             AppOpsManager.MODE_ALLOWED,
    894             AppOpsManager.MODE_ALLOWED,
    895             AppOpsManager.MODE_ALLOWED,
    896             AppOpsManager.MODE_ALLOWED,
    897             AppOpsManager.MODE_ALLOWED,
    898             AppOpsManager.MODE_ALLOWED,
    899             AppOpsManager.MODE_ALLOWED,
    900             AppOpsManager.MODE_ALLOWED,
    901             AppOpsManager.MODE_ALLOWED,
    902             AppOpsManager.MODE_ALLOWED,
    903             AppOpsManager.MODE_IGNORED, // OP_WRITE_SMS
    904             AppOpsManager.MODE_ALLOWED,
    905             AppOpsManager.MODE_ALLOWED,
    906             AppOpsManager.MODE_ALLOWED,
    907             AppOpsManager.MODE_ALLOWED,
    908             AppOpsManager.MODE_ALLOWED,
    909             AppOpsManager.MODE_ALLOWED,
    910             AppOpsManager.MODE_ALLOWED,
    911             AppOpsManager.MODE_DEFAULT, // OP_WRITE_SETTINGS
    912             AppOpsManager.MODE_DEFAULT, // OP_SYSTEM_ALERT_WINDOW
    913             AppOpsManager.MODE_ALLOWED,
    914             AppOpsManager.MODE_ALLOWED,
    915             AppOpsManager.MODE_ALLOWED,
    916             AppOpsManager.MODE_ALLOWED,
    917             AppOpsManager.MODE_ALLOWED,
    918             AppOpsManager.MODE_ALLOWED,
    919             AppOpsManager.MODE_ALLOWED,
    920             AppOpsManager.MODE_ALLOWED,
    921             AppOpsManager.MODE_ALLOWED,
    922             AppOpsManager.MODE_ALLOWED,
    923             AppOpsManager.MODE_ALLOWED,
    924             AppOpsManager.MODE_ALLOWED,
    925             AppOpsManager.MODE_ALLOWED,
    926             AppOpsManager.MODE_ALLOWED,
    927             AppOpsManager.MODE_ALLOWED,
    928             AppOpsManager.MODE_ALLOWED,
    929             AppOpsManager.MODE_ALLOWED,
    930             AppOpsManager.MODE_ALLOWED,
    931             AppOpsManager.MODE_DEFAULT, // OP_GET_USAGE_STATS
    932             AppOpsManager.MODE_ALLOWED,
    933             AppOpsManager.MODE_ALLOWED,
    934             AppOpsManager.MODE_IGNORED, // OP_PROJECT_MEDIA
    935             AppOpsManager.MODE_IGNORED, // OP_ACTIVATE_VPN
    936             AppOpsManager.MODE_ALLOWED,
    937             AppOpsManager.MODE_ALLOWED,
    938             AppOpsManager.MODE_ALLOWED,
    939             AppOpsManager.MODE_ALLOWED,
    940             AppOpsManager.MODE_ALLOWED,
    941             AppOpsManager.MODE_ALLOWED,
    942             AppOpsManager.MODE_ALLOWED,
    943             AppOpsManager.MODE_ALLOWED,
    944             AppOpsManager.MODE_ALLOWED,
    945             AppOpsManager.MODE_ALLOWED,
    946             AppOpsManager.MODE_ERRORED,  // OP_MOCK_LOCATION
    947             AppOpsManager.MODE_ALLOWED,
    948             AppOpsManager.MODE_ALLOWED,
    949             AppOpsManager.MODE_ALLOWED,  // OP_TURN_ON_SCREEN
    950             AppOpsManager.MODE_ALLOWED,
    951             AppOpsManager.MODE_ALLOWED,  // OP_RUN_IN_BACKGROUND
    952             AppOpsManager.MODE_ALLOWED,  // OP_AUDIO_ACCESSIBILITY_VOLUME
    953             AppOpsManager.MODE_ALLOWED,
    954             AppOpsManager.MODE_DEFAULT,  // OP_REQUEST_INSTALL_PACKAGES
    955             AppOpsManager.MODE_ALLOWED,  // OP_PICTURE_IN_PICTURE
    956             AppOpsManager.MODE_DEFAULT,  // OP_INSTANT_APP_START_FOREGROUND
    957             AppOpsManager.MODE_ALLOWED, // ANSWER_PHONE_CALLS
    958     };
    959 
    960     /**
    961      * This specifies whether each option is allowed to be reset
    962      * when resetting all app preferences.  Disable reset for
    963      * app ops that are under strong control of some part of the
    964      * system (such as OP_WRITE_SMS, which should be allowed only
    965      * for whichever app is selected as the current SMS app).
    966      */
    967     private static boolean[] sOpDisableReset = new boolean[] {
    968             false,
    969             false,
    970             false,
    971             false,
    972             false,
    973             false,
    974             false,
    975             false,
    976             false,
    977             false,
    978             false,
    979             false,
    980             false,
    981             false,
    982             false,
    983             true,      // OP_WRITE_SMS
    984             false,
    985             false,
    986             false,
    987             false,
    988             false,
    989             false,
    990             false,
    991             false,
    992             false,
    993             false,
    994             false,
    995             false,
    996             false,
    997             false,
    998             false,
    999             false,
   1000             false,
   1001             false,
   1002             false,
   1003             false,
   1004             false,
   1005             false,
   1006             false,
   1007             false,
   1008             false,
   1009             false,
   1010             false,
   1011             false,
   1012             false,
   1013             false,
   1014             false,
   1015             false,
   1016             false,
   1017             false,
   1018             false,
   1019             false,
   1020             false,
   1021             false,
   1022             false,
   1023             false,
   1024             false,
   1025             false,
   1026             false,
   1027             false,
   1028             false,
   1029             false,
   1030             false,
   1031             false,
   1032             false, // OP_AUDIO_ACCESSIBILITY_VOLUME
   1033             false,
   1034             false, // OP_REQUEST_INSTALL_PACKAGES
   1035             false, // OP_PICTURE_IN_PICTURE
   1036             false,
   1037             false, // ANSWER_PHONE_CALLS
   1038     };
   1039 
   1040     /**
   1041      * Mapping from an app op name to the app op code.
   1042      */
   1043     private static HashMap<String, Integer> sOpStrToOp = new HashMap<>();
   1044 
   1045     /**
   1046      * Mapping from a permission to the corresponding app op.
   1047      */
   1048     private static HashMap<String, Integer> sPermToOp = new HashMap<>();
   1049 
   1050     static {
   1051         if (sOpToSwitch.length != _NUM_OP) {
   1052             throw new IllegalStateException("sOpToSwitch length " + sOpToSwitch.length
   1053                     + " should be " + _NUM_OP);
   1054         }
   1055         if (sOpToString.length != _NUM_OP) {
   1056             throw new IllegalStateException("sOpToString length " + sOpToString.length
   1057                     + " should be " + _NUM_OP);
   1058         }
   1059         if (sOpNames.length != _NUM_OP) {
   1060             throw new IllegalStateException("sOpNames length " + sOpNames.length
   1061                     + " should be " + _NUM_OP);
   1062         }
   1063         if (sOpPerms.length != _NUM_OP) {
   1064             throw new IllegalStateException("sOpPerms length " + sOpPerms.length
   1065                     + " should be " + _NUM_OP);
   1066         }
   1067         if (sOpDefaultMode.length != _NUM_OP) {
   1068             throw new IllegalStateException("sOpDefaultMode length " + sOpDefaultMode.length
   1069                     + " should be " + _NUM_OP);
   1070         }
   1071         if (sOpDisableReset.length != _NUM_OP) {
   1072             throw new IllegalStateException("sOpDisableReset length " + sOpDisableReset.length
   1073                     + " should be " + _NUM_OP);
   1074         }
   1075         if (sOpRestrictions.length != _NUM_OP) {
   1076             throw new IllegalStateException("sOpRestrictions length " + sOpRestrictions.length
   1077                     + " should be " + _NUM_OP);
   1078         }
   1079         if (sOpAllowSystemRestrictionBypass.length != _NUM_OP) {
   1080             throw new IllegalStateException("sOpAllowSYstemRestrictionsBypass length "
   1081                     + sOpRestrictions.length + " should be " + _NUM_OP);
   1082         }
   1083         for (int i=0; i<_NUM_OP; i++) {
   1084             if (sOpToString[i] != null) {
   1085                 sOpStrToOp.put(sOpToString[i], i);
   1086             }
   1087         }
   1088         for (int op : RUNTIME_AND_APPOP_PERMISSIONS_OPS) {
   1089             if (sOpPerms[op] != null) {
   1090                 sPermToOp.put(sOpPerms[op], op);
   1091             }
   1092         }
   1093     }
   1094 
   1095     /**
   1096      * Retrieve the op switch that controls the given operation.
   1097      * @hide
   1098      */
   1099     public static int opToSwitch(int op) {
   1100         return sOpToSwitch[op];
   1101     }
   1102 
   1103     /**
   1104      * Retrieve a non-localized name for the operation, for debugging output.
   1105      * @hide
   1106      */
   1107     public static String opToName(int op) {
   1108         if (op == OP_NONE) return "NONE";
   1109         return op < sOpNames.length ? sOpNames[op] : ("Unknown(" + op + ")");
   1110     }
   1111 
   1112     /**
   1113      * @hide
   1114      */
   1115     public static int strDebugOpToOp(String op) {
   1116         for (int i=0; i<sOpNames.length; i++) {
   1117             if (sOpNames[i].equals(op)) {
   1118                 return i;
   1119             }
   1120         }
   1121         throw new IllegalArgumentException("Unknown operation string: " + op);
   1122     }
   1123 
   1124     /**
   1125      * Retrieve the permission associated with an operation, or null if there is not one.
   1126      * @hide
   1127      */
   1128     public static String opToPermission(int op) {
   1129         return sOpPerms[op];
   1130     }
   1131 
   1132     /**
   1133      * Retrieve the user restriction associated with an operation, or null if there is not one.
   1134      * @hide
   1135      */
   1136     public static String opToRestriction(int op) {
   1137         return sOpRestrictions[op];
   1138     }
   1139 
   1140     /**
   1141      * Retrieve the app op code for a permission, or null if there is not one.
   1142      * This API is intended to be used for mapping runtime or appop permissions
   1143      * to the corresponding app op.
   1144      * @hide
   1145      */
   1146     public static int permissionToOpCode(String permission) {
   1147         Integer boxedOpCode = sPermToOp.get(permission);
   1148         return boxedOpCode != null ? boxedOpCode : OP_NONE;
   1149     }
   1150 
   1151     /**
   1152      * Retrieve whether the op allows the system (and system ui) to
   1153      * bypass the user restriction.
   1154      * @hide
   1155      */
   1156     public static boolean opAllowSystemBypassRestriction(int op) {
   1157         return sOpAllowSystemRestrictionBypass[op];
   1158     }
   1159 
   1160     /**
   1161      * Retrieve the default mode for the operation.
   1162      * @hide
   1163      */
   1164     public static int opToDefaultMode(int op) {
   1165         return sOpDefaultMode[op];
   1166     }
   1167 
   1168     /**
   1169      * Retrieve whether the op allows itself to be reset.
   1170      * @hide
   1171      */
   1172     public static boolean opAllowsReset(int op) {
   1173         return !sOpDisableReset[op];
   1174     }
   1175 
   1176     /**
   1177      * Class holding all of the operation information associated with an app.
   1178      * @hide
   1179      */
   1180     public static class PackageOps implements Parcelable {
   1181         private final String mPackageName;
   1182         private final int mUid;
   1183         private final List<OpEntry> mEntries;
   1184 
   1185         public PackageOps(String packageName, int uid, List<OpEntry> entries) {
   1186             mPackageName = packageName;
   1187             mUid = uid;
   1188             mEntries = entries;
   1189         }
   1190 
   1191         public String getPackageName() {
   1192             return mPackageName;
   1193         }
   1194 
   1195         public int getUid() {
   1196             return mUid;
   1197         }
   1198 
   1199         public List<OpEntry> getOps() {
   1200             return mEntries;
   1201         }
   1202 
   1203         @Override
   1204         public int describeContents() {
   1205             return 0;
   1206         }
   1207 
   1208         @Override
   1209         public void writeToParcel(Parcel dest, int flags) {
   1210             dest.writeString(mPackageName);
   1211             dest.writeInt(mUid);
   1212             dest.writeInt(mEntries.size());
   1213             for (int i=0; i<mEntries.size(); i++) {
   1214                 mEntries.get(i).writeToParcel(dest, flags);
   1215             }
   1216         }
   1217 
   1218         PackageOps(Parcel source) {
   1219             mPackageName = source.readString();
   1220             mUid = source.readInt();
   1221             mEntries = new ArrayList<OpEntry>();
   1222             final int N = source.readInt();
   1223             for (int i=0; i<N; i++) {
   1224                 mEntries.add(OpEntry.CREATOR.createFromParcel(source));
   1225             }
   1226         }
   1227 
   1228         public static final Creator<PackageOps> CREATOR = new Creator<PackageOps>() {
   1229             @Override public PackageOps createFromParcel(Parcel source) {
   1230                 return new PackageOps(source);
   1231             }
   1232 
   1233             @Override public PackageOps[] newArray(int size) {
   1234                 return new PackageOps[size];
   1235             }
   1236         };
   1237     }
   1238 
   1239     /**
   1240      * Class holding the information about one unique operation of an application.
   1241      * @hide
   1242      */
   1243     public static class OpEntry implements Parcelable {
   1244         private final int mOp;
   1245         private final int mMode;
   1246         private final long mTime;
   1247         private final long mRejectTime;
   1248         private final int mDuration;
   1249         private final int mProxyUid;
   1250         private final String mProxyPackageName;
   1251 
   1252         public OpEntry(int op, int mode, long time, long rejectTime, int duration,
   1253                 int proxyUid, String proxyPackage) {
   1254             mOp = op;
   1255             mMode = mode;
   1256             mTime = time;
   1257             mRejectTime = rejectTime;
   1258             mDuration = duration;
   1259             mProxyUid = proxyUid;
   1260             mProxyPackageName = proxyPackage;
   1261         }
   1262 
   1263         public int getOp() {
   1264             return mOp;
   1265         }
   1266 
   1267         public int getMode() {
   1268             return mMode;
   1269         }
   1270 
   1271         public long getTime() {
   1272             return mTime;
   1273         }
   1274 
   1275         public long getRejectTime() {
   1276             return mRejectTime;
   1277         }
   1278 
   1279         public boolean isRunning() {
   1280             return mDuration == -1;
   1281         }
   1282 
   1283         public int getDuration() {
   1284             return mDuration == -1 ? (int)(System.currentTimeMillis()-mTime) : mDuration;
   1285         }
   1286 
   1287         public int getProxyUid() {
   1288             return  mProxyUid;
   1289         }
   1290 
   1291         public String getProxyPackageName() {
   1292             return mProxyPackageName;
   1293         }
   1294 
   1295         @Override
   1296         public int describeContents() {
   1297             return 0;
   1298         }
   1299 
   1300         @Override
   1301         public void writeToParcel(Parcel dest, int flags) {
   1302             dest.writeInt(mOp);
   1303             dest.writeInt(mMode);
   1304             dest.writeLong(mTime);
   1305             dest.writeLong(mRejectTime);
   1306             dest.writeInt(mDuration);
   1307             dest.writeInt(mProxyUid);
   1308             dest.writeString(mProxyPackageName);
   1309         }
   1310 
   1311         OpEntry(Parcel source) {
   1312             mOp = source.readInt();
   1313             mMode = source.readInt();
   1314             mTime = source.readLong();
   1315             mRejectTime = source.readLong();
   1316             mDuration = source.readInt();
   1317             mProxyUid = source.readInt();
   1318             mProxyPackageName = source.readString();
   1319         }
   1320 
   1321         public static final Creator<OpEntry> CREATOR = new Creator<OpEntry>() {
   1322             @Override public OpEntry createFromParcel(Parcel source) {
   1323                 return new OpEntry(source);
   1324             }
   1325 
   1326             @Override public OpEntry[] newArray(int size) {
   1327                 return new OpEntry[size];
   1328             }
   1329         };
   1330     }
   1331 
   1332     /**
   1333      * Callback for notification of changes to operation state.
   1334      */
   1335     public interface OnOpChangedListener {
   1336         public void onOpChanged(String op, String packageName);
   1337     }
   1338 
   1339     /**
   1340      * Callback for notification of changes to operation state.
   1341      * This allows you to see the raw op codes instead of strings.
   1342      * @hide
   1343      */
   1344     public static class OnOpChangedInternalListener implements OnOpChangedListener {
   1345         public void onOpChanged(String op, String packageName) { }
   1346         public void onOpChanged(int op, String packageName) { }
   1347     }
   1348 
   1349     AppOpsManager(Context context, IAppOpsService service) {
   1350         mContext = context;
   1351         mService = service;
   1352     }
   1353 
   1354     /**
   1355      * Retrieve current operation state for all applications.
   1356      *
   1357      * @param ops The set of operations you are interested in, or null if you want all of them.
   1358      * @hide
   1359      */
   1360     public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) {
   1361         try {
   1362             return mService.getPackagesForOps(ops);
   1363         } catch (RemoteException e) {
   1364             throw e.rethrowFromSystemServer();
   1365         }
   1366     }
   1367 
   1368     /**
   1369      * Retrieve current operation state for one application.
   1370      *
   1371      * @param uid The uid of the application of interest.
   1372      * @param packageName The name of the application of interest.
   1373      * @param ops The set of operations you are interested in, or null if you want all of them.
   1374      * @hide
   1375      */
   1376     public List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, int[] ops) {
   1377         try {
   1378             return mService.getOpsForPackage(uid, packageName, ops);
   1379         } catch (RemoteException e) {
   1380             throw e.rethrowFromSystemServer();
   1381         }
   1382     }
   1383 
   1384     /**
   1385      * Sets given app op in the specified mode for app ops in the UID.
   1386      * This applies to all apps currently in the UID or installed in
   1387      * this UID in the future.
   1388      *
   1389      * @param code The app op.
   1390      * @param uid The UID for which to set the app.
   1391      * @param mode The app op mode to set.
   1392      * @hide
   1393      */
   1394     public void setUidMode(int code, int uid, int mode) {
   1395         try {
   1396             mService.setUidMode(code, uid, mode);
   1397         } catch (RemoteException e) {
   1398             throw e.rethrowFromSystemServer();
   1399         }
   1400     }
   1401 
   1402     /**
   1403      * Sets given app op in the specified mode for app ops in the UID.
   1404      * This applies to all apps currently in the UID or installed in
   1405      * this UID in the future.
   1406      *
   1407      * @param appOp The app op.
   1408      * @param uid The UID for which to set the app.
   1409      * @param mode The app op mode to set.
   1410      * @hide
   1411      */
   1412     @SystemApi
   1413     @RequiresPermission(android.Manifest.permission.UPDATE_APP_OPS_STATS)
   1414     public void setUidMode(String appOp, int uid, int mode) {
   1415         try {
   1416             mService.setUidMode(AppOpsManager.strOpToOp(appOp), uid, mode);
   1417         } catch (RemoteException e) {
   1418             throw e.rethrowFromSystemServer();
   1419         }
   1420     }
   1421 
   1422     /** @hide */
   1423     public void setUserRestriction(int code, boolean restricted, IBinder token) {
   1424         setUserRestriction(code, restricted, token, /*exceptionPackages*/null);
   1425     }
   1426 
   1427     /** @hide */
   1428     public void setUserRestriction(int code, boolean restricted, IBinder token,
   1429             String[] exceptionPackages) {
   1430         setUserRestrictionForUser(code, restricted, token, exceptionPackages, mContext.getUserId());
   1431     }
   1432 
   1433     /** @hide */
   1434     public void setUserRestrictionForUser(int code, boolean restricted, IBinder token,
   1435             String[] exceptionPackages, int userId) {
   1436         try {
   1437             mService.setUserRestriction(code, restricted, token, userId, exceptionPackages);
   1438         } catch (RemoteException e) {
   1439             throw e.rethrowFromSystemServer();
   1440         }
   1441     }
   1442 
   1443     /** @hide */
   1444     public void setMode(int code, int uid, String packageName, int mode) {
   1445         try {
   1446             mService.setMode(code, uid, packageName, mode);
   1447         } catch (RemoteException e) {
   1448             throw e.rethrowFromSystemServer();
   1449         }
   1450     }
   1451 
   1452     /**
   1453      * Set a non-persisted restriction on an audio operation at a stream-level.
   1454      * Restrictions are temporary additional constraints imposed on top of the persisted rules
   1455      * defined by {@link #setMode}.
   1456      *
   1457      * @param code The operation to restrict.
   1458      * @param usage The {@link android.media.AudioAttributes} usage value.
   1459      * @param mode The restriction mode (MODE_IGNORED,MODE_ERRORED) or MODE_ALLOWED to unrestrict.
   1460      * @param exceptionPackages Optional list of packages to exclude from the restriction.
   1461      * @hide
   1462      */
   1463     public void setRestriction(int code, @AttributeUsage int usage, int mode,
   1464             String[] exceptionPackages) {
   1465         try {
   1466             final int uid = Binder.getCallingUid();
   1467             mService.setAudioRestriction(code, usage, uid, mode, exceptionPackages);
   1468         } catch (RemoteException e) {
   1469             throw e.rethrowFromSystemServer();
   1470         }
   1471     }
   1472 
   1473     /** @hide */
   1474     public void resetAllModes() {
   1475         try {
   1476             mService.resetAllModes(UserHandle.myUserId(), null);
   1477         } catch (RemoteException e) {
   1478             throw e.rethrowFromSystemServer();
   1479         }
   1480     }
   1481 
   1482     /**
   1483      * Gets the app op name associated with a given permission.
   1484      * The app op name is one of the public constants defined
   1485      * in this class such as {@link #OPSTR_COARSE_LOCATION}.
   1486      * This API is intended to be used for mapping runtime
   1487      * permissions to the corresponding app op.
   1488      *
   1489      * @param permission The permission.
   1490      * @return The app op associated with the permission or null.
   1491      */
   1492     public static String permissionToOp(String permission) {
   1493         final Integer opCode = sPermToOp.get(permission);
   1494         if (opCode == null) {
   1495             return null;
   1496         }
   1497         return sOpToString[opCode];
   1498     }
   1499 
   1500     /**
   1501      * Monitor for changes to the operating mode for the given op in the given app package.
   1502      * @param op The operation to monitor, one of OPSTR_*.
   1503      * @param packageName The name of the application to monitor.
   1504      * @param callback Where to report changes.
   1505      */
   1506     public void startWatchingMode(String op, String packageName,
   1507             final OnOpChangedListener callback) {
   1508         startWatchingMode(strOpToOp(op), packageName, callback);
   1509     }
   1510 
   1511     /**
   1512      * Monitor for changes to the operating mode for the given op in the given app package.
   1513      * @param op The operation to monitor, one of OP_*.
   1514      * @param packageName The name of the application to monitor.
   1515      * @param callback Where to report changes.
   1516      * @hide
   1517      */
   1518     public void startWatchingMode(int op, String packageName, final OnOpChangedListener callback) {
   1519         synchronized (mModeWatchers) {
   1520             IAppOpsCallback cb = mModeWatchers.get(callback);
   1521             if (cb == null) {
   1522                 cb = new IAppOpsCallback.Stub() {
   1523                     public void opChanged(int op, int uid, String packageName) {
   1524                         if (callback instanceof OnOpChangedInternalListener) {
   1525                             ((OnOpChangedInternalListener)callback).onOpChanged(op, packageName);
   1526                         }
   1527                         if (sOpToString[op] != null) {
   1528                             callback.onOpChanged(sOpToString[op], packageName);
   1529                         }
   1530                     }
   1531                 };
   1532                 mModeWatchers.put(callback, cb);
   1533             }
   1534             try {
   1535                 mService.startWatchingMode(op, packageName, cb);
   1536             } catch (RemoteException e) {
   1537                 throw e.rethrowFromSystemServer();
   1538             }
   1539         }
   1540     }
   1541 
   1542     /**
   1543      * Stop monitoring that was previously started with {@link #startWatchingMode}.  All
   1544      * monitoring associated with this callback will be removed.
   1545      */
   1546     public void stopWatchingMode(OnOpChangedListener callback) {
   1547         synchronized (mModeWatchers) {
   1548             IAppOpsCallback cb = mModeWatchers.get(callback);
   1549             if (cb != null) {
   1550                 try {
   1551                     mService.stopWatchingMode(cb);
   1552                 } catch (RemoteException e) {
   1553                     throw e.rethrowFromSystemServer();
   1554                 }
   1555             }
   1556         }
   1557     }
   1558 
   1559     private String buildSecurityExceptionMsg(int op, int uid, String packageName) {
   1560         return packageName + " from uid " + uid + " not allowed to perform " + sOpNames[op];
   1561     }
   1562 
   1563     /**
   1564      * {@hide}
   1565      */
   1566     public static int strOpToOp(String op) {
   1567         Integer val = sOpStrToOp.get(op);
   1568         if (val == null) {
   1569             throw new IllegalArgumentException("Unknown operation string: " + op);
   1570         }
   1571         return val;
   1572     }
   1573 
   1574     /**
   1575      * Do a quick check for whether an application might be able to perform an operation.
   1576      * This is <em>not</em> a security check; you must use {@link #noteOp(String, int, String)}
   1577      * or {@link #startOp(String, int, String)} for your actual security checks, which also
   1578      * ensure that the given uid and package name are consistent.  This function can just be
   1579      * used for a quick check to see if an operation has been disabled for the application,
   1580      * as an early reject of some work.  This does not modify the time stamp or other data
   1581      * about the operation.
   1582      * @param op The operation to check.  One of the OPSTR_* constants.
   1583      * @param uid The user id of the application attempting to perform the operation.
   1584      * @param packageName The name of the application attempting to perform the operation.
   1585      * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
   1586      * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
   1587      * causing the app to crash).
   1588      * @throws SecurityException If the app has been configured to crash on this op.
   1589      */
   1590     public int checkOp(String op, int uid, String packageName) {
   1591         return checkOp(strOpToOp(op), uid, packageName);
   1592     }
   1593 
   1594     /**
   1595      * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
   1596      * returns {@link #MODE_ERRORED}.
   1597      */
   1598     public int checkOpNoThrow(String op, int uid, String packageName) {
   1599         return checkOpNoThrow(strOpToOp(op), uid, packageName);
   1600     }
   1601 
   1602     /**
   1603      * Make note of an application performing an operation.  Note that you must pass
   1604      * in both the uid and name of the application to be checked; this function will verify
   1605      * that these two match, and if not, return {@link #MODE_IGNORED}.  If this call
   1606      * succeeds, the last execution time of the operation for this app will be updated to
   1607      * the current time.
   1608      * @param op The operation to note.  One of the OPSTR_* constants.
   1609      * @param uid The user id of the application attempting to perform the operation.
   1610      * @param packageName The name of the application attempting to perform the operation.
   1611      * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
   1612      * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
   1613      * causing the app to crash).
   1614      * @throws SecurityException If the app has been configured to crash on this op.
   1615      */
   1616     public int noteOp(String op, int uid, String packageName) {
   1617         return noteOp(strOpToOp(op), uid, packageName);
   1618     }
   1619 
   1620     /**
   1621      * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
   1622      * returns {@link #MODE_ERRORED}.
   1623      */
   1624     public int noteOpNoThrow(String op, int uid, String packageName) {
   1625         return noteOpNoThrow(strOpToOp(op), uid, packageName);
   1626     }
   1627 
   1628     /**
   1629      * Make note of an application performing an operation on behalf of another
   1630      * application when handling an IPC. Note that you must pass the package name
   1631      * of the application that is being proxied while its UID will be inferred from
   1632      * the IPC state; this function will verify that the calling uid and proxied
   1633      * package name match, and if not, return {@link #MODE_IGNORED}. If this call
   1634      * succeeds, the last execution time of the operation for the proxied app and
   1635      * your app will be updated to the current time.
   1636      * @param op The operation to note.  One of the OPSTR_* constants.
   1637      * @param proxiedPackageName The name of the application calling into the proxy application.
   1638      * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
   1639      * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
   1640      * causing the app to crash).
   1641      * @throws SecurityException If the app has been configured to crash on this op.
   1642      */
   1643     public int noteProxyOp(String op, String proxiedPackageName) {
   1644         return noteProxyOp(strOpToOp(op), proxiedPackageName);
   1645     }
   1646 
   1647     /**
   1648      * Like {@link #noteProxyOp(String, String)} but instead
   1649      * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
   1650      */
   1651     public int noteProxyOpNoThrow(String op, String proxiedPackageName) {
   1652         return noteProxyOpNoThrow(strOpToOp(op), proxiedPackageName);
   1653     }
   1654 
   1655     /**
   1656      * Report that an application has started executing a long-running operation.  Note that you
   1657      * must pass in both the uid and name of the application to be checked; this function will
   1658      * verify that these two match, and if not, return {@link #MODE_IGNORED}.  If this call
   1659      * succeeds, the last execution time of the operation for this app will be updated to
   1660      * the current time and the operation will be marked as "running".  In this case you must
   1661      * later call {@link #finishOp(String, int, String)} to report when the application is no
   1662      * longer performing the operation.
   1663      * @param op The operation to start.  One of the OPSTR_* constants.
   1664      * @param uid The user id of the application attempting to perform the operation.
   1665      * @param packageName The name of the application attempting to perform the operation.
   1666      * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
   1667      * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
   1668      * causing the app to crash).
   1669      * @throws SecurityException If the app has been configured to crash on this op.
   1670      */
   1671     public int startOp(String op, int uid, String packageName) {
   1672         return startOp(strOpToOp(op), uid, packageName);
   1673     }
   1674 
   1675     /**
   1676      * Like {@link #startOp} but instead of throwing a {@link SecurityException} it
   1677      * returns {@link #MODE_ERRORED}.
   1678      */
   1679     public int startOpNoThrow(String op, int uid, String packageName) {
   1680         return startOpNoThrow(strOpToOp(op), uid, packageName);
   1681     }
   1682 
   1683     /**
   1684      * Report that an application is no longer performing an operation that had previously
   1685      * been started with {@link #startOp(String, int, String)}.  There is no validation of input
   1686      * or result; the parameters supplied here must be the exact same ones previously passed
   1687      * in when starting the operation.
   1688      */
   1689     public void finishOp(String op, int uid, String packageName) {
   1690         finishOp(strOpToOp(op), uid, packageName);
   1691     }
   1692 
   1693     /**
   1694      * Do a quick check for whether an application might be able to perform an operation.
   1695      * This is <em>not</em> a security check; you must use {@link #noteOp(int, int, String)}
   1696      * or {@link #startOp(int, int, String)} for your actual security checks, which also
   1697      * ensure that the given uid and package name are consistent.  This function can just be
   1698      * used for a quick check to see if an operation has been disabled for the application,
   1699      * as an early reject of some work.  This does not modify the time stamp or other data
   1700      * about the operation.
   1701      * @param op The operation to check.  One of the OP_* constants.
   1702      * @param uid The user id of the application attempting to perform the operation.
   1703      * @param packageName The name of the application attempting to perform the operation.
   1704      * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
   1705      * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
   1706      * causing the app to crash).
   1707      * @throws SecurityException If the app has been configured to crash on this op.
   1708      * @hide
   1709      */
   1710     public int checkOp(int op, int uid, String packageName) {
   1711         try {
   1712             int mode = mService.checkOperation(op, uid, packageName);
   1713             if (mode == MODE_ERRORED) {
   1714                 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
   1715             }
   1716             return mode;
   1717         } catch (RemoteException e) {
   1718             throw e.rethrowFromSystemServer();
   1719         }
   1720     }
   1721 
   1722     /**
   1723      * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
   1724      * returns {@link #MODE_ERRORED}.
   1725      * @hide
   1726      */
   1727     public int checkOpNoThrow(int op, int uid, String packageName) {
   1728         try {
   1729             return mService.checkOperation(op, uid, packageName);
   1730         } catch (RemoteException e) {
   1731             throw e.rethrowFromSystemServer();
   1732         }
   1733     }
   1734 
   1735     /**
   1736      * Do a quick check to validate if a package name belongs to a UID.
   1737      *
   1738      * @throws SecurityException if the package name doesn't belong to the given
   1739      *             UID, or if ownership cannot be verified.
   1740      */
   1741     public void checkPackage(int uid, String packageName) {
   1742         try {
   1743             if (mService.checkPackage(uid, packageName) != MODE_ALLOWED) {
   1744                 throw new SecurityException(
   1745                         "Package " + packageName + " does not belong to " + uid);
   1746             }
   1747         } catch (RemoteException e) {
   1748             throw e.rethrowFromSystemServer();
   1749         }
   1750     }
   1751 
   1752     /**
   1753      * Like {@link #checkOp} but at a stream-level for audio operations.
   1754      * @hide
   1755      */
   1756     public int checkAudioOp(int op, int stream, int uid, String packageName) {
   1757         try {
   1758             final int mode = mService.checkAudioOperation(op, stream, uid, packageName);
   1759             if (mode == MODE_ERRORED) {
   1760                 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
   1761             }
   1762             return mode;
   1763         } catch (RemoteException e) {
   1764             throw e.rethrowFromSystemServer();
   1765         }
   1766     }
   1767 
   1768     /**
   1769      * Like {@link #checkAudioOp} but instead of throwing a {@link SecurityException} it
   1770      * returns {@link #MODE_ERRORED}.
   1771      * @hide
   1772      */
   1773     public int checkAudioOpNoThrow(int op, int stream, int uid, String packageName) {
   1774         try {
   1775             return mService.checkAudioOperation(op, stream, uid, packageName);
   1776         } catch (RemoteException e) {
   1777             throw e.rethrowFromSystemServer();
   1778         }
   1779     }
   1780 
   1781     /**
   1782      * Make note of an application performing an operation.  Note that you must pass
   1783      * in both the uid and name of the application to be checked; this function will verify
   1784      * that these two match, and if not, return {@link #MODE_IGNORED}.  If this call
   1785      * succeeds, the last execution time of the operation for this app will be updated to
   1786      * the current time.
   1787      * @param op The operation to note.  One of the OP_* constants.
   1788      * @param uid The user id of the application attempting to perform the operation.
   1789      * @param packageName The name of the application attempting to perform the operation.
   1790      * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
   1791      * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
   1792      * causing the app to crash).
   1793      * @throws SecurityException If the app has been configured to crash on this op.
   1794      * @hide
   1795      */
   1796     public int noteOp(int op, int uid, String packageName) {
   1797         try {
   1798             int mode = mService.noteOperation(op, uid, packageName);
   1799             if (mode == MODE_ERRORED) {
   1800                 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
   1801             }
   1802             return mode;
   1803         } catch (RemoteException e) {
   1804             throw e.rethrowFromSystemServer();
   1805         }
   1806     }
   1807 
   1808     /**
   1809      * Make note of an application performing an operation on behalf of another
   1810      * application when handling an IPC. Note that you must pass the package name
   1811      * of the application that is being proxied while its UID will be inferred from
   1812      * the IPC state; this function will verify that the calling uid and proxied
   1813      * package name match, and if not, return {@link #MODE_IGNORED}. If this call
   1814      * succeeds, the last execution time of the operation for the proxied app and
   1815      * your app will be updated to the current time.
   1816      * @param op The operation to note. One of the OPSTR_* constants.
   1817      * @param proxiedPackageName The name of the application calling into the proxy application.
   1818      * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
   1819      * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
   1820      * causing the app to crash).
   1821      * @throws SecurityException If the proxy or proxied app has been configured to
   1822      * crash on this op.
   1823      *
   1824      * @hide
   1825      */
   1826     public int noteProxyOp(int op, String proxiedPackageName) {
   1827         int mode = noteProxyOpNoThrow(op, proxiedPackageName);
   1828         if (mode == MODE_ERRORED) {
   1829             throw new SecurityException("Proxy package " + mContext.getOpPackageName()
   1830                     + " from uid " + Process.myUid() + " or calling package "
   1831                     + proxiedPackageName + " from uid " + Binder.getCallingUid()
   1832                     + " not allowed to perform " + sOpNames[op]);
   1833         }
   1834         return mode;
   1835     }
   1836 
   1837     /**
   1838      * Like {@link #noteProxyOp(int, String)} but instead
   1839      * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
   1840      * @hide
   1841      */
   1842     public int noteProxyOpNoThrow(int op, String proxiedPackageName) {
   1843         try {
   1844             return mService.noteProxyOperation(op, mContext.getOpPackageName(),
   1845                     Binder.getCallingUid(), proxiedPackageName);
   1846         } catch (RemoteException e) {
   1847             throw e.rethrowFromSystemServer();
   1848         }
   1849     }
   1850 
   1851     /**
   1852      * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
   1853      * returns {@link #MODE_ERRORED}.
   1854      * @hide
   1855      */
   1856     public int noteOpNoThrow(int op, int uid, String packageName) {
   1857         try {
   1858             return mService.noteOperation(op, uid, packageName);
   1859         } catch (RemoteException e) {
   1860             throw e.rethrowFromSystemServer();
   1861         }
   1862     }
   1863 
   1864     /** @hide */
   1865     public int noteOp(int op) {
   1866         return noteOp(op, Process.myUid(), mContext.getOpPackageName());
   1867     }
   1868 
   1869     /** @hide */
   1870     public static IBinder getToken(IAppOpsService service) {
   1871         synchronized (AppOpsManager.class) {
   1872             if (sToken != null) {
   1873                 return sToken;
   1874             }
   1875             try {
   1876                 sToken = service.getToken(new Binder());
   1877             } catch (RemoteException e) {
   1878                 throw e.rethrowFromSystemServer();
   1879             }
   1880             return sToken;
   1881         }
   1882     }
   1883 
   1884     /**
   1885      * Report that an application has started executing a long-running operation.  Note that you
   1886      * must pass in both the uid and name of the application to be checked; this function will
   1887      * verify that these two match, and if not, return {@link #MODE_IGNORED}.  If this call
   1888      * succeeds, the last execution time of the operation for this app will be updated to
   1889      * the current time and the operation will be marked as "running".  In this case you must
   1890      * later call {@link #finishOp(int, int, String)} to report when the application is no
   1891      * longer performing the operation.
   1892      * @param op The operation to start.  One of the OP_* constants.
   1893      * @param uid The user id of the application attempting to perform the operation.
   1894      * @param packageName The name of the application attempting to perform the operation.
   1895      * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
   1896      * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
   1897      * causing the app to crash).
   1898      * @throws SecurityException If the app has been configured to crash on this op.
   1899      * @hide
   1900      */
   1901     public int startOp(int op, int uid, String packageName) {
   1902         try {
   1903             int mode = mService.startOperation(getToken(mService), op, uid, packageName);
   1904             if (mode == MODE_ERRORED) {
   1905                 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
   1906             }
   1907             return mode;
   1908         } catch (RemoteException e) {
   1909             throw e.rethrowFromSystemServer();
   1910         }
   1911     }
   1912 
   1913     /**
   1914      * Like {@link #startOp} but instead of throwing a {@link SecurityException} it
   1915      * returns {@link #MODE_ERRORED}.
   1916      * @hide
   1917      */
   1918     public int startOpNoThrow(int op, int uid, String packageName) {
   1919         try {
   1920             return mService.startOperation(getToken(mService), op, uid, packageName);
   1921         } catch (RemoteException e) {
   1922             throw e.rethrowFromSystemServer();
   1923         }
   1924     }
   1925 
   1926     /** @hide */
   1927     public int startOp(int op) {
   1928         return startOp(op, Process.myUid(), mContext.getOpPackageName());
   1929     }
   1930 
   1931     /**
   1932      * Report that an application is no longer performing an operation that had previously
   1933      * been started with {@link #startOp(int, int, String)}.  There is no validation of input
   1934      * or result; the parameters supplied here must be the exact same ones previously passed
   1935      * in when starting the operation.
   1936      * @hide
   1937      */
   1938     public void finishOp(int op, int uid, String packageName) {
   1939         try {
   1940             mService.finishOperation(getToken(mService), op, uid, packageName);
   1941         } catch (RemoteException e) {
   1942             throw e.rethrowFromSystemServer();
   1943         }
   1944     }
   1945 
   1946     /** @hide */
   1947     public void finishOp(int op) {
   1948         finishOp(op, Process.myUid(), mContext.getOpPackageName());
   1949     }
   1950 }
   1951