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