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