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.annotation.SystemApi;
     20 import android.app.usage.UsageStatsManager;
     21 import android.content.Context;
     22 import android.media.AudioAttributes.AttributeUsage;
     23 import android.os.Binder;
     24 import android.os.IBinder;
     25 import android.os.Parcel;
     26 import android.os.Parcelable;
     27 import android.os.Process;
     28 import android.os.RemoteException;
     29 import android.os.UserManager;
     30 import android.util.ArrayMap;
     31 
     32 import com.android.internal.app.IAppOpsCallback;
     33 import com.android.internal.app.IAppOpsService;
     34 
     35 import java.util.ArrayList;
     36 import java.util.HashMap;
     37 import java.util.List;
     38 
     39 /**
     40  * API for interacting with "application operation" tracking.
     41  *
     42  * <p>This API is not generally intended for third party application developers; most
     43  * features are only available to system applications.  Obtain an instance of it through
     44  * {@link Context#getSystemService(String) Context.getSystemService} with
     45  * {@link Context#APP_OPS_SERVICE Context.APP_OPS_SERVICE}.</p>
     46  */
     47 public class AppOpsManager {
     48     /**
     49      * <p>App ops allows callers to:</p>
     50      *
     51      * <ul>
     52      * <li> Note when operations are happening, and find out if they are allowed for the current
     53      * caller.</li>
     54      * <li> Disallow specific apps from doing specific operations.</li>
     55      * <li> Collect all of the current information about operations that have been executed or
     56      * are not being allowed.</li>
     57      * <li> Monitor for changes in whether an operation is allowed.</li>
     58      * </ul>
     59      *
     60      * <p>Each operation is identified by a single integer; these integers are a fixed set of
     61      * operations, enumerated by the OP_* constants.
     62      *
     63      * <p></p>When checking operations, the result is a "mode" integer indicating the current
     64      * setting for the operation under that caller: MODE_ALLOWED, MODE_IGNORED (don't execute
     65      * the operation but fake its behavior enough so that the caller doesn't crash),
     66      * MODE_ERRORED (throw a SecurityException back to the caller; the normal operation calls
     67      * will do this for you).
     68      */
     69 
     70     final Context mContext;
     71     final IAppOpsService mService;
     72     final ArrayMap<OnOpChangedListener, IAppOpsCallback> mModeWatchers
     73             = new ArrayMap<OnOpChangedListener, IAppOpsCallback>();
     74 
     75     static IBinder sToken;
     76 
     77     /**
     78      * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is
     79      * allowed to perform the given operation.
     80      */
     81     public static final int MODE_ALLOWED = 0;
     82 
     83     /**
     84      * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is
     85      * not allowed to perform the given operation, and this attempt should
     86      * <em>silently fail</em> (it should not cause the app to crash).
     87      */
     88     public static final int MODE_IGNORED = 1;
     89 
     90     /**
     91      * Result from {@link #checkOpNoThrow}, {@link #noteOpNoThrow}, {@link #startOpNoThrow}: the
     92      * given caller is not allowed to perform the given operation, and this attempt should
     93      * cause it to have a fatal error, typically a {@link SecurityException}.
     94      */
     95     public static final int MODE_ERRORED = 2;
     96 
     97     /**
     98      * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller should
     99      * use its default security check.  This mode is not normally used; it should only be used
    100      * with appop permissions, and callers must explicitly check for it and deal with it.
    101      */
    102     public static final int MODE_DEFAULT = 3;
    103 
    104     // when adding one of these:
    105     //  - increment _NUM_OP
    106     //  - add rows to sOpToSwitch, sOpToString, sOpNames, sOpPerms, sOpDefaultMode
    107     //  - add descriptive strings to Settings/res/values/arrays.xml
    108     //  - add the op to the appropriate template in AppOpsState.OpsTemplate (settings app)
    109 
    110     /** @hide No operation specified. */
    111     public static final int OP_NONE = -1;
    112     /** @hide Access to coarse location information. */
    113     public static final int OP_COARSE_LOCATION = 0;
    114     /** @hide Access to fine location information. */
    115     public static final int OP_FINE_LOCATION = 1;
    116     /** @hide Causing GPS to run. */
    117     public static final int OP_GPS = 2;
    118     /** @hide */
    119     public static final int OP_VIBRATE = 3;
    120     /** @hide */
    121     public static final int OP_READ_CONTACTS = 4;
    122     /** @hide */
    123     public static final int OP_WRITE_CONTACTS = 5;
    124     /** @hide */
    125     public static final int OP_READ_CALL_LOG = 6;
    126     /** @hide */
    127     public static final int OP_WRITE_CALL_LOG = 7;
    128     /** @hide */
    129     public static final int OP_READ_CALENDAR = 8;
    130     /** @hide */
    131     public static final int OP_WRITE_CALENDAR = 9;
    132     /** @hide */
    133     public static final int OP_WIFI_SCAN = 10;
    134     /** @hide */
    135     public static final int OP_POST_NOTIFICATION = 11;
    136     /** @hide */
    137     public static final int OP_NEIGHBORING_CELLS = 12;
    138     /** @hide */
    139     public static final int OP_CALL_PHONE = 13;
    140     /** @hide */
    141     public static final int OP_READ_SMS = 14;
    142     /** @hide */
    143     public static final int OP_WRITE_SMS = 15;
    144     /** @hide */
    145     public static final int OP_RECEIVE_SMS = 16;
    146     /** @hide */
    147     public static final int OP_RECEIVE_EMERGECY_SMS = 17;
    148     /** @hide */
    149     public static final int OP_RECEIVE_MMS = 18;
    150     /** @hide */
    151     public static final int OP_RECEIVE_WAP_PUSH = 19;
    152     /** @hide */
    153     public static final int OP_SEND_SMS = 20;
    154     /** @hide */
    155     public static final int OP_READ_ICC_SMS = 21;
    156     /** @hide */
    157     public static final int OP_WRITE_ICC_SMS = 22;
    158     /** @hide */
    159     public static final int OP_WRITE_SETTINGS = 23;
    160     /** @hide */
    161     public static final int OP_SYSTEM_ALERT_WINDOW = 24;
    162     /** @hide */
    163     public static final int OP_ACCESS_NOTIFICATIONS = 25;
    164     /** @hide */
    165     public static final int OP_CAMERA = 26;
    166     /** @hide */
    167     public static final int OP_RECORD_AUDIO = 27;
    168     /** @hide */
    169     public static final int OP_PLAY_AUDIO = 28;
    170     /** @hide */
    171     public static final int OP_READ_CLIPBOARD = 29;
    172     /** @hide */
    173     public static final int OP_WRITE_CLIPBOARD = 30;
    174     /** @hide */
    175     public static final int OP_TAKE_MEDIA_BUTTONS = 31;
    176     /** @hide */
    177     public static final int OP_TAKE_AUDIO_FOCUS = 32;
    178     /** @hide */
    179     public static final int OP_AUDIO_MASTER_VOLUME = 33;
    180     /** @hide */
    181     public static final int OP_AUDIO_VOICE_VOLUME = 34;
    182     /** @hide */
    183     public static final int OP_AUDIO_RING_VOLUME = 35;
    184     /** @hide */
    185     public static final int OP_AUDIO_MEDIA_VOLUME = 36;
    186     /** @hide */
    187     public static final int OP_AUDIO_ALARM_VOLUME = 37;
    188     /** @hide */
    189     public static final int OP_AUDIO_NOTIFICATION_VOLUME = 38;
    190     /** @hide */
    191     public static final int OP_AUDIO_BLUETOOTH_VOLUME = 39;
    192     /** @hide */
    193     public static final int OP_WAKE_LOCK = 40;
    194     /** @hide Continually monitoring location data. */
    195     public static final int OP_MONITOR_LOCATION = 41;
    196     /** @hide Continually monitoring location data with a relatively high power request. */
    197     public static final int OP_MONITOR_HIGH_POWER_LOCATION = 42;
    198     /** @hide Retrieve current usage stats via {@link UsageStatsManager}. */
    199     public static final int OP_GET_USAGE_STATS = 43;
    200     /** @hide */
    201     public static final int OP_MUTE_MICROPHONE = 44;
    202     /** @hide */
    203     public static final int OP_TOAST_WINDOW = 45;
    204     /** @hide Capture the device's display contents and/or audio */
    205     public static final int OP_PROJECT_MEDIA = 46;
    206     /** @hide Activate a VPN connection without user intervention. */
    207     public static final int OP_ACTIVATE_VPN = 47;
    208     /** @hide */
    209     public static final int _NUM_OP = 48;
    210 
    211     /** Access to coarse location information. */
    212     public static final String OPSTR_COARSE_LOCATION =
    213             "android:coarse_location";
    214     /** Access to fine location information. */
    215     public static final String OPSTR_FINE_LOCATION =
    216             "android:fine_location";
    217     /** Continually monitoring location data. */
    218     public static final String OPSTR_MONITOR_LOCATION
    219             = "android:monitor_location";
    220     /** Continually monitoring location data with a relatively high power request. */
    221     public static final String OPSTR_MONITOR_HIGH_POWER_LOCATION
    222             = "android:monitor_location_high_power";
    223     /** Access to {@link android.app.usage.UsageStatsManager}. */
    224     public static final String OPSTR_GET_USAGE_STATS
    225             = "android:get_usage_stats";
    226     /** Activate a VPN connection without user intervention. @hide */
    227     @SystemApi
    228     public static final String OPSTR_ACTIVATE_VPN = "android:activate_vpn";
    229 
    230     /**
    231      * This maps each operation to the operation that serves as the
    232      * switch to determine whether it is allowed.  Generally this is
    233      * a 1:1 mapping, but for some things (like location) that have
    234      * multiple low-level operations being tracked that should be
    235      * presented to the user as one switch then this can be used to
    236      * make them all controlled by the same single operation.
    237      */
    238     private static int[] sOpToSwitch = new int[] {
    239             OP_COARSE_LOCATION,
    240             OP_COARSE_LOCATION,
    241             OP_COARSE_LOCATION,
    242             OP_VIBRATE,
    243             OP_READ_CONTACTS,
    244             OP_WRITE_CONTACTS,
    245             OP_READ_CALL_LOG,
    246             OP_WRITE_CALL_LOG,
    247             OP_READ_CALENDAR,
    248             OP_WRITE_CALENDAR,
    249             OP_COARSE_LOCATION,
    250             OP_POST_NOTIFICATION,
    251             OP_COARSE_LOCATION,
    252             OP_CALL_PHONE,
    253             OP_READ_SMS,
    254             OP_WRITE_SMS,
    255             OP_RECEIVE_SMS,
    256             OP_RECEIVE_SMS,
    257             OP_RECEIVE_SMS,
    258             OP_RECEIVE_SMS,
    259             OP_SEND_SMS,
    260             OP_READ_SMS,
    261             OP_WRITE_SMS,
    262             OP_WRITE_SETTINGS,
    263             OP_SYSTEM_ALERT_WINDOW,
    264             OP_ACCESS_NOTIFICATIONS,
    265             OP_CAMERA,
    266             OP_RECORD_AUDIO,
    267             OP_PLAY_AUDIO,
    268             OP_READ_CLIPBOARD,
    269             OP_WRITE_CLIPBOARD,
    270             OP_TAKE_MEDIA_BUTTONS,
    271             OP_TAKE_AUDIO_FOCUS,
    272             OP_AUDIO_MASTER_VOLUME,
    273             OP_AUDIO_VOICE_VOLUME,
    274             OP_AUDIO_RING_VOLUME,
    275             OP_AUDIO_MEDIA_VOLUME,
    276             OP_AUDIO_ALARM_VOLUME,
    277             OP_AUDIO_NOTIFICATION_VOLUME,
    278             OP_AUDIO_BLUETOOTH_VOLUME,
    279             OP_WAKE_LOCK,
    280             OP_COARSE_LOCATION,
    281             OP_COARSE_LOCATION,
    282             OP_GET_USAGE_STATS,
    283             OP_MUTE_MICROPHONE,
    284             OP_TOAST_WINDOW,
    285             OP_PROJECT_MEDIA,
    286             OP_ACTIVATE_VPN,
    287     };
    288 
    289     /**
    290      * This maps each operation to the public string constant for it.
    291      * If it doesn't have a public string constant, it maps to null.
    292      */
    293     private static String[] sOpToString = new String[] {
    294             OPSTR_COARSE_LOCATION,
    295             OPSTR_FINE_LOCATION,
    296             null,
    297             null,
    298             null,
    299             null,
    300             null,
    301             null,
    302             null,
    303             null,
    304             null,
    305             null,
    306             null,
    307             null,
    308             null,
    309             null,
    310             null,
    311             null,
    312             null,
    313             null,
    314             null,
    315             null,
    316             null,
    317             null,
    318             null,
    319             null,
    320             null,
    321             null,
    322             null,
    323             null,
    324             null,
    325             null,
    326             null,
    327             null,
    328             null,
    329             null,
    330             null,
    331             null,
    332             null,
    333             null,
    334             null,
    335             OPSTR_MONITOR_LOCATION,
    336             OPSTR_MONITOR_HIGH_POWER_LOCATION,
    337             OPSTR_GET_USAGE_STATS,
    338             null,
    339             null,
    340             null,
    341             OPSTR_ACTIVATE_VPN,
    342     };
    343 
    344     /**
    345      * This provides a simple name for each operation to be used
    346      * in debug output.
    347      */
    348     private static String[] sOpNames = new String[] {
    349             "COARSE_LOCATION",
    350             "FINE_LOCATION",
    351             "GPS",
    352             "VIBRATE",
    353             "READ_CONTACTS",
    354             "WRITE_CONTACTS",
    355             "READ_CALL_LOG",
    356             "WRITE_CALL_LOG",
    357             "READ_CALENDAR",
    358             "WRITE_CALENDAR",
    359             "WIFI_SCAN",
    360             "POST_NOTIFICATION",
    361             "NEIGHBORING_CELLS",
    362             "CALL_PHONE",
    363             "READ_SMS",
    364             "WRITE_SMS",
    365             "RECEIVE_SMS",
    366             "RECEIVE_EMERGECY_SMS",
    367             "RECEIVE_MMS",
    368             "RECEIVE_WAP_PUSH",
    369             "SEND_SMS",
    370             "READ_ICC_SMS",
    371             "WRITE_ICC_SMS",
    372             "WRITE_SETTINGS",
    373             "SYSTEM_ALERT_WINDOW",
    374             "ACCESS_NOTIFICATIONS",
    375             "CAMERA",
    376             "RECORD_AUDIO",
    377             "PLAY_AUDIO",
    378             "READ_CLIPBOARD",
    379             "WRITE_CLIPBOARD",
    380             "TAKE_MEDIA_BUTTONS",
    381             "TAKE_AUDIO_FOCUS",
    382             "AUDIO_MASTER_VOLUME",
    383             "AUDIO_VOICE_VOLUME",
    384             "AUDIO_RING_VOLUME",
    385             "AUDIO_MEDIA_VOLUME",
    386             "AUDIO_ALARM_VOLUME",
    387             "AUDIO_NOTIFICATION_VOLUME",
    388             "AUDIO_BLUETOOTH_VOLUME",
    389             "WAKE_LOCK",
    390             "MONITOR_LOCATION",
    391             "MONITOR_HIGH_POWER_LOCATION",
    392             "GET_USAGE_STATS",
    393             "MUTE_MICROPHONE",
    394             "TOAST_WINDOW",
    395             "PROJECT_MEDIA",
    396             "ACTIVATE_VPN",
    397     };
    398 
    399     /**
    400      * This optionally maps a permission to an operation.  If there
    401      * is no permission associated with an operation, it is null.
    402      */
    403     private static String[] sOpPerms = new String[] {
    404             android.Manifest.permission.ACCESS_COARSE_LOCATION,
    405             android.Manifest.permission.ACCESS_FINE_LOCATION,
    406             null,
    407             android.Manifest.permission.VIBRATE,
    408             android.Manifest.permission.READ_CONTACTS,
    409             android.Manifest.permission.WRITE_CONTACTS,
    410             android.Manifest.permission.READ_CALL_LOG,
    411             android.Manifest.permission.WRITE_CALL_LOG,
    412             android.Manifest.permission.READ_CALENDAR,
    413             android.Manifest.permission.WRITE_CALENDAR,
    414             android.Manifest.permission.ACCESS_WIFI_STATE,
    415             null, // no permission required for notifications
    416             null, // neighboring cells shares the coarse location perm
    417             android.Manifest.permission.CALL_PHONE,
    418             android.Manifest.permission.READ_SMS,
    419             android.Manifest.permission.WRITE_SMS,
    420             android.Manifest.permission.RECEIVE_SMS,
    421             android.Manifest.permission.RECEIVE_EMERGENCY_BROADCAST,
    422             android.Manifest.permission.RECEIVE_MMS,
    423             android.Manifest.permission.RECEIVE_WAP_PUSH,
    424             android.Manifest.permission.SEND_SMS,
    425             android.Manifest.permission.READ_SMS,
    426             android.Manifest.permission.WRITE_SMS,
    427             android.Manifest.permission.WRITE_SETTINGS,
    428             android.Manifest.permission.SYSTEM_ALERT_WINDOW,
    429             android.Manifest.permission.ACCESS_NOTIFICATIONS,
    430             android.Manifest.permission.CAMERA,
    431             android.Manifest.permission.RECORD_AUDIO,
    432             null, // no permission for playing audio
    433             null, // no permission for reading clipboard
    434             null, // no permission for writing clipboard
    435             null, // no permission for taking media buttons
    436             null, // no permission for taking audio focus
    437             null, // no permission for changing master volume
    438             null, // no permission for changing voice volume
    439             null, // no permission for changing ring volume
    440             null, // no permission for changing media volume
    441             null, // no permission for changing alarm volume
    442             null, // no permission for changing notification volume
    443             null, // no permission for changing bluetooth volume
    444             android.Manifest.permission.WAKE_LOCK,
    445             null, // no permission for generic location monitoring
    446             null, // no permission for high power location monitoring
    447             android.Manifest.permission.PACKAGE_USAGE_STATS,
    448             null, // no permission for muting/unmuting microphone
    449             null, // no permission for displaying toasts
    450             null, // no permission for projecting media
    451             null, // no permission for activating vpn
    452     };
    453 
    454     /**
    455      * Specifies whether an Op should be restricted by a user restriction.
    456      * Each Op should be filled with a restriction string from UserManager or
    457      * null to specify it is not affected by any user restriction.
    458      */
    459     private static String[] sOpRestrictions = new String[] {
    460             UserManager.DISALLOW_SHARE_LOCATION, //COARSE_LOCATION
    461             UserManager.DISALLOW_SHARE_LOCATION, //FINE_LOCATION
    462             UserManager.DISALLOW_SHARE_LOCATION, //GPS
    463             null, //VIBRATE
    464             null, //READ_CONTACTS
    465             null, //WRITE_CONTACTS
    466             UserManager.DISALLOW_OUTGOING_CALLS, //READ_CALL_LOG
    467             UserManager.DISALLOW_OUTGOING_CALLS, //WRITE_CALL_LOG
    468             null, //READ_CALENDAR
    469             null, //WRITE_CALENDAR
    470             UserManager.DISALLOW_SHARE_LOCATION, //WIFI_SCAN
    471             null, //POST_NOTIFICATION
    472             null, //NEIGHBORING_CELLS
    473             null, //CALL_PHONE
    474             UserManager.DISALLOW_SMS, //READ_SMS
    475             UserManager.DISALLOW_SMS, //WRITE_SMS
    476             UserManager.DISALLOW_SMS, //RECEIVE_SMS
    477             null, //RECEIVE_EMERGENCY_SMS
    478             UserManager.DISALLOW_SMS, //RECEIVE_MMS
    479             null, //RECEIVE_WAP_PUSH
    480             UserManager.DISALLOW_SMS, //SEND_SMS
    481             UserManager.DISALLOW_SMS, //READ_ICC_SMS
    482             UserManager.DISALLOW_SMS, //WRITE_ICC_SMS
    483             null, //WRITE_SETTINGS
    484             UserManager.DISALLOW_CREATE_WINDOWS, //SYSTEM_ALERT_WINDOW
    485             null, //ACCESS_NOTIFICATIONS
    486             null, //CAMERA
    487             null, //RECORD_AUDIO
    488             null, //PLAY_AUDIO
    489             null, //READ_CLIPBOARD
    490             null, //WRITE_CLIPBOARD
    491             null, //TAKE_MEDIA_BUTTONS
    492             null, //TAKE_AUDIO_FOCUS
    493             UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MASTER_VOLUME
    494             UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_VOICE_VOLUME
    495             UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_RING_VOLUME
    496             UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MEDIA_VOLUME
    497             UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ALARM_VOLUME
    498             UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_NOTIFICATION_VOLUME
    499             UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_BLUETOOTH_VOLUME
    500             null, //WAKE_LOCK
    501             UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_LOCATION
    502             UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_HIGH_POWER_LOCATION
    503             null, //GET_USAGE_STATS
    504             UserManager.DISALLOW_UNMUTE_MICROPHONE, // MUTE_MICROPHONE
    505             UserManager.DISALLOW_CREATE_WINDOWS, // TOAST_WINDOW
    506             null, //PROJECT_MEDIA
    507             UserManager.DISALLOW_CONFIG_VPN, // ACTIVATE_VPN
    508     };
    509 
    510     /**
    511      * This specifies whether each option should allow the system
    512      * (and system ui) to bypass the user restriction when active.
    513      */
    514     private static boolean[] sOpAllowSystemRestrictionBypass = new boolean[] {
    515             false, //COARSE_LOCATION
    516             false, //FINE_LOCATION
    517             false, //GPS
    518             false, //VIBRATE
    519             false, //READ_CONTACTS
    520             false, //WRITE_CONTACTS
    521             false, //READ_CALL_LOG
    522             false, //WRITE_CALL_LOG
    523             false, //READ_CALENDAR
    524             false, //WRITE_CALENDAR
    525             true, //WIFI_SCAN
    526             false, //POST_NOTIFICATION
    527             false, //NEIGHBORING_CELLS
    528             false, //CALL_PHONE
    529             false, //READ_SMS
    530             false, //WRITE_SMS
    531             false, //RECEIVE_SMS
    532             false, //RECEIVE_EMERGECY_SMS
    533             false, //RECEIVE_MMS
    534             false, //RECEIVE_WAP_PUSH
    535             false, //SEND_SMS
    536             false, //READ_ICC_SMS
    537             false, //WRITE_ICC_SMS
    538             false, //WRITE_SETTINGS
    539             true, //SYSTEM_ALERT_WINDOW
    540             false, //ACCESS_NOTIFICATIONS
    541             false, //CAMERA
    542             false, //RECORD_AUDIO
    543             false, //PLAY_AUDIO
    544             false, //READ_CLIPBOARD
    545             false, //WRITE_CLIPBOARD
    546             false, //TAKE_MEDIA_BUTTONS
    547             false, //TAKE_AUDIO_FOCUS
    548             false, //AUDIO_MASTER_VOLUME
    549             false, //AUDIO_VOICE_VOLUME
    550             false, //AUDIO_RING_VOLUME
    551             false, //AUDIO_MEDIA_VOLUME
    552             false, //AUDIO_ALARM_VOLUME
    553             false, //AUDIO_NOTIFICATION_VOLUME
    554             false, //AUDIO_BLUETOOTH_VOLUME
    555             false, //WAKE_LOCK
    556             false, //MONITOR_LOCATION
    557             false, //MONITOR_HIGH_POWER_LOCATION
    558             false, //GET_USAGE_STATS
    559             false, //MUTE_MICROPHONE
    560             true, //TOAST_WINDOW
    561             false, //PROJECT_MEDIA
    562             false, //ACTIVATE_VPN
    563     };
    564 
    565     /**
    566      * This specifies the default mode for each operation.
    567      */
    568     private static int[] sOpDefaultMode = new int[] {
    569             AppOpsManager.MODE_ALLOWED,
    570             AppOpsManager.MODE_ALLOWED,
    571             AppOpsManager.MODE_ALLOWED,
    572             AppOpsManager.MODE_ALLOWED,
    573             AppOpsManager.MODE_ALLOWED,
    574             AppOpsManager.MODE_ALLOWED,
    575             AppOpsManager.MODE_ALLOWED,
    576             AppOpsManager.MODE_ALLOWED,
    577             AppOpsManager.MODE_ALLOWED,
    578             AppOpsManager.MODE_ALLOWED,
    579             AppOpsManager.MODE_ALLOWED,
    580             AppOpsManager.MODE_ALLOWED,
    581             AppOpsManager.MODE_ALLOWED,
    582             AppOpsManager.MODE_ALLOWED,
    583             AppOpsManager.MODE_ALLOWED,
    584             AppOpsManager.MODE_IGNORED, // OP_WRITE_SMS
    585             AppOpsManager.MODE_ALLOWED,
    586             AppOpsManager.MODE_ALLOWED,
    587             AppOpsManager.MODE_ALLOWED,
    588             AppOpsManager.MODE_ALLOWED,
    589             AppOpsManager.MODE_ALLOWED,
    590             AppOpsManager.MODE_ALLOWED,
    591             AppOpsManager.MODE_ALLOWED,
    592             AppOpsManager.MODE_ALLOWED,
    593             AppOpsManager.MODE_ALLOWED,
    594             AppOpsManager.MODE_ALLOWED,
    595             AppOpsManager.MODE_ALLOWED,
    596             AppOpsManager.MODE_ALLOWED,
    597             AppOpsManager.MODE_ALLOWED,
    598             AppOpsManager.MODE_ALLOWED,
    599             AppOpsManager.MODE_ALLOWED,
    600             AppOpsManager.MODE_ALLOWED,
    601             AppOpsManager.MODE_ALLOWED,
    602             AppOpsManager.MODE_ALLOWED,
    603             AppOpsManager.MODE_ALLOWED,
    604             AppOpsManager.MODE_ALLOWED,
    605             AppOpsManager.MODE_ALLOWED,
    606             AppOpsManager.MODE_ALLOWED,
    607             AppOpsManager.MODE_ALLOWED,
    608             AppOpsManager.MODE_ALLOWED,
    609             AppOpsManager.MODE_ALLOWED,
    610             AppOpsManager.MODE_ALLOWED,
    611             AppOpsManager.MODE_ALLOWED,
    612             AppOpsManager.MODE_DEFAULT, // OP_GET_USAGE_STATS
    613             AppOpsManager.MODE_ALLOWED,
    614             AppOpsManager.MODE_ALLOWED,
    615             AppOpsManager.MODE_IGNORED, // OP_PROJECT_MEDIA
    616             AppOpsManager.MODE_IGNORED, // OP_ACTIVATE_VPN
    617     };
    618 
    619     /**
    620      * This specifies whether each option is allowed to be reset
    621      * when resetting all app preferences.  Disable reset for
    622      * app ops that are under strong control of some part of the
    623      * system (such as OP_WRITE_SMS, which should be allowed only
    624      * for whichever app is selected as the current SMS app).
    625      */
    626     private static boolean[] sOpDisableReset = new boolean[] {
    627             false,
    628             false,
    629             false,
    630             false,
    631             false,
    632             false,
    633             false,
    634             false,
    635             false,
    636             false,
    637             false,
    638             false,
    639             false,
    640             false,
    641             false,
    642             true,      // OP_WRITE_SMS
    643             false,
    644             false,
    645             false,
    646             false,
    647             false,
    648             false,
    649             false,
    650             false,
    651             false,
    652             false,
    653             false,
    654             false,
    655             false,
    656             false,
    657             false,
    658             false,
    659             false,
    660             false,
    661             false,
    662             false,
    663             false,
    664             false,
    665             false,
    666             false,
    667             false,
    668             false,
    669             false,
    670             false,
    671             false,
    672             false,
    673             false,
    674             false,
    675     };
    676 
    677     private static HashMap<String, Integer> sOpStrToOp = new HashMap<String, Integer>();
    678 
    679     static {
    680         if (sOpToSwitch.length != _NUM_OP) {
    681             throw new IllegalStateException("sOpToSwitch length " + sOpToSwitch.length
    682                     + " should be " + _NUM_OP);
    683         }
    684         if (sOpToString.length != _NUM_OP) {
    685             throw new IllegalStateException("sOpToString length " + sOpToString.length
    686                     + " should be " + _NUM_OP);
    687         }
    688         if (sOpNames.length != _NUM_OP) {
    689             throw new IllegalStateException("sOpNames length " + sOpNames.length
    690                     + " should be " + _NUM_OP);
    691         }
    692         if (sOpPerms.length != _NUM_OP) {
    693             throw new IllegalStateException("sOpPerms length " + sOpPerms.length
    694                     + " should be " + _NUM_OP);
    695         }
    696         if (sOpDefaultMode.length != _NUM_OP) {
    697             throw new IllegalStateException("sOpDefaultMode length " + sOpDefaultMode.length
    698                     + " should be " + _NUM_OP);
    699         }
    700         if (sOpDisableReset.length != _NUM_OP) {
    701             throw new IllegalStateException("sOpDisableReset length " + sOpDisableReset.length
    702                     + " should be " + _NUM_OP);
    703         }
    704         if (sOpRestrictions.length != _NUM_OP) {
    705             throw new IllegalStateException("sOpRestrictions length " + sOpRestrictions.length
    706                     + " should be " + _NUM_OP);
    707         }
    708         if (sOpAllowSystemRestrictionBypass.length != _NUM_OP) {
    709             throw new IllegalStateException("sOpAllowSYstemRestrictionsBypass length "
    710                     + sOpRestrictions.length + " should be " + _NUM_OP);
    711         }
    712         for (int i=0; i<_NUM_OP; i++) {
    713             if (sOpToString[i] != null) {
    714                 sOpStrToOp.put(sOpToString[i], i);
    715             }
    716         }
    717     }
    718 
    719     /**
    720      * Retrieve the op switch that controls the given operation.
    721      * @hide
    722      */
    723     public static int opToSwitch(int op) {
    724         return sOpToSwitch[op];
    725     }
    726 
    727     /**
    728      * Retrieve a non-localized name for the operation, for debugging output.
    729      * @hide
    730      */
    731     public static String opToName(int op) {
    732         if (op == OP_NONE) return "NONE";
    733         return op < sOpNames.length ? sOpNames[op] : ("Unknown(" + op + ")");
    734     }
    735 
    736     /**
    737      * Retrieve the permission associated with an operation, or null if there is not one.
    738      * @hide
    739      */
    740     public static String opToPermission(int op) {
    741         return sOpPerms[op];
    742     }
    743 
    744     /**
    745      * Retrieve the user restriction associated with an operation, or null if there is not one.
    746      * @hide
    747      */
    748     public static String opToRestriction(int op) {
    749         return sOpRestrictions[op];
    750     }
    751 
    752     /**
    753      * Retrieve whether the op allows the system (and system ui) to
    754      * bypass the user restriction.
    755      * @hide
    756      */
    757     public static boolean opAllowSystemBypassRestriction(int op) {
    758         return sOpAllowSystemRestrictionBypass[op];
    759     }
    760 
    761     /**
    762      * Retrieve the default mode for the operation.
    763      * @hide
    764      */
    765     public static int opToDefaultMode(int op) {
    766         return sOpDefaultMode[op];
    767     }
    768 
    769     /**
    770      * Retrieve whether the op allows itself to be reset.
    771      * @hide
    772      */
    773     public static boolean opAllowsReset(int op) {
    774         return !sOpDisableReset[op];
    775     }
    776 
    777     /**
    778      * Class holding all of the operation information associated with an app.
    779      * @hide
    780      */
    781     public static class PackageOps implements Parcelable {
    782         private final String mPackageName;
    783         private final int mUid;
    784         private final List<OpEntry> mEntries;
    785 
    786         public PackageOps(String packageName, int uid, List<OpEntry> entries) {
    787             mPackageName = packageName;
    788             mUid = uid;
    789             mEntries = entries;
    790         }
    791 
    792         public String getPackageName() {
    793             return mPackageName;
    794         }
    795 
    796         public int getUid() {
    797             return mUid;
    798         }
    799 
    800         public List<OpEntry> getOps() {
    801             return mEntries;
    802         }
    803 
    804         @Override
    805         public int describeContents() {
    806             return 0;
    807         }
    808 
    809         @Override
    810         public void writeToParcel(Parcel dest, int flags) {
    811             dest.writeString(mPackageName);
    812             dest.writeInt(mUid);
    813             dest.writeInt(mEntries.size());
    814             for (int i=0; i<mEntries.size(); i++) {
    815                 mEntries.get(i).writeToParcel(dest, flags);
    816             }
    817         }
    818 
    819         PackageOps(Parcel source) {
    820             mPackageName = source.readString();
    821             mUid = source.readInt();
    822             mEntries = new ArrayList<OpEntry>();
    823             final int N = source.readInt();
    824             for (int i=0; i<N; i++) {
    825                 mEntries.add(OpEntry.CREATOR.createFromParcel(source));
    826             }
    827         }
    828 
    829         public static final Creator<PackageOps> CREATOR = new Creator<PackageOps>() {
    830             @Override public PackageOps createFromParcel(Parcel source) {
    831                 return new PackageOps(source);
    832             }
    833 
    834             @Override public PackageOps[] newArray(int size) {
    835                 return new PackageOps[size];
    836             }
    837         };
    838     }
    839 
    840     /**
    841      * Class holding the information about one unique operation of an application.
    842      * @hide
    843      */
    844     public static class OpEntry implements Parcelable {
    845         private final int mOp;
    846         private final int mMode;
    847         private final long mTime;
    848         private final long mRejectTime;
    849         private final int mDuration;
    850 
    851         public OpEntry(int op, int mode, long time, long rejectTime, int duration) {
    852             mOp = op;
    853             mMode = mode;
    854             mTime = time;
    855             mRejectTime = rejectTime;
    856             mDuration = duration;
    857         }
    858 
    859         public int getOp() {
    860             return mOp;
    861         }
    862 
    863         public int getMode() {
    864             return mMode;
    865         }
    866 
    867         public long getTime() {
    868             return mTime;
    869         }
    870 
    871         public long getRejectTime() {
    872             return mRejectTime;
    873         }
    874 
    875         public boolean isRunning() {
    876             return mDuration == -1;
    877         }
    878 
    879         public int getDuration() {
    880             return mDuration == -1 ? (int)(System.currentTimeMillis()-mTime) : mDuration;
    881         }
    882 
    883         @Override
    884         public int describeContents() {
    885             return 0;
    886         }
    887 
    888         @Override
    889         public void writeToParcel(Parcel dest, int flags) {
    890             dest.writeInt(mOp);
    891             dest.writeInt(mMode);
    892             dest.writeLong(mTime);
    893             dest.writeLong(mRejectTime);
    894             dest.writeInt(mDuration);
    895         }
    896 
    897         OpEntry(Parcel source) {
    898             mOp = source.readInt();
    899             mMode = source.readInt();
    900             mTime = source.readLong();
    901             mRejectTime = source.readLong();
    902             mDuration = source.readInt();
    903         }
    904 
    905         public static final Creator<OpEntry> CREATOR = new Creator<OpEntry>() {
    906             @Override public OpEntry createFromParcel(Parcel source) {
    907                 return new OpEntry(source);
    908             }
    909 
    910             @Override public OpEntry[] newArray(int size) {
    911                 return new OpEntry[size];
    912             }
    913         };
    914     }
    915 
    916     /**
    917      * Callback for notification of changes to operation state.
    918      */
    919     public interface OnOpChangedListener {
    920         public void onOpChanged(String op, String packageName);
    921     }
    922 
    923     /**
    924      * Callback for notification of changes to operation state.
    925      * This allows you to see the raw op codes instead of strings.
    926      * @hide
    927      */
    928     public static class OnOpChangedInternalListener implements OnOpChangedListener {
    929         public void onOpChanged(String op, String packageName) { }
    930         public void onOpChanged(int op, String packageName) { }
    931     }
    932 
    933     AppOpsManager(Context context, IAppOpsService service) {
    934         mContext = context;
    935         mService = service;
    936     }
    937 
    938     /**
    939      * Retrieve current operation state for all applications.
    940      *
    941      * @param ops The set of operations you are interested in, or null if you want all of them.
    942      * @hide
    943      */
    944     public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) {
    945         try {
    946             return mService.getPackagesForOps(ops);
    947         } catch (RemoteException e) {
    948         }
    949         return null;
    950     }
    951 
    952     /**
    953      * Retrieve current operation state for one application.
    954      *
    955      * @param uid The uid of the application of interest.
    956      * @param packageName The name of the application of interest.
    957      * @param ops The set of operations you are interested in, or null if you want all of them.
    958      * @hide
    959      */
    960     public List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, int[] ops) {
    961         try {
    962             return mService.getOpsForPackage(uid, packageName, ops);
    963         } catch (RemoteException e) {
    964         }
    965         return null;
    966     }
    967 
    968     /** @hide */
    969     public void setMode(int code, int uid, String packageName, int mode) {
    970         try {
    971             mService.setMode(code, uid, packageName, mode);
    972         } catch (RemoteException e) {
    973         }
    974     }
    975 
    976     /**
    977      * Set a non-persisted restriction on an audio operation at a stream-level.
    978      * Restrictions are temporary additional constraints imposed on top of the persisted rules
    979      * defined by {@link #setMode}.
    980      *
    981      * @param code The operation to restrict.
    982      * @param usage The {@link android.media.AudioAttributes} usage value.
    983      * @param mode The restriction mode (MODE_IGNORED,MODE_ERRORED) or MODE_ALLOWED to unrestrict.
    984      * @param exceptionPackages Optional list of packages to exclude from the restriction.
    985      * @hide
    986      */
    987     public void setRestriction(int code, @AttributeUsage int usage, int mode,
    988             String[] exceptionPackages) {
    989         try {
    990             final int uid = Binder.getCallingUid();
    991             mService.setAudioRestriction(code, usage, uid, mode, exceptionPackages);
    992         } catch (RemoteException e) {
    993         }
    994     }
    995 
    996     /** @hide */
    997     public void resetAllModes() {
    998         try {
    999             mService.resetAllModes();
   1000         } catch (RemoteException e) {
   1001         }
   1002     }
   1003 
   1004     /**
   1005      * Monitor for changes to the operating mode for the given op in the given app package.
   1006      * @param op The operation to monitor, one of OPSTR_*.
   1007      * @param packageName The name of the application to monitor.
   1008      * @param callback Where to report changes.
   1009      */
   1010     public void startWatchingMode(String op, String packageName,
   1011             final OnOpChangedListener callback) {
   1012         startWatchingMode(strOpToOp(op), packageName, callback);
   1013     }
   1014 
   1015     /**
   1016      * Monitor for changes to the operating mode for the given op in the given app package.
   1017      * @param op The operation to monitor, one of OP_*.
   1018      * @param packageName The name of the application to monitor.
   1019      * @param callback Where to report changes.
   1020      * @hide
   1021      */
   1022     public void startWatchingMode(int op, String packageName, final OnOpChangedListener callback) {
   1023         synchronized (mModeWatchers) {
   1024             IAppOpsCallback cb = mModeWatchers.get(callback);
   1025             if (cb == null) {
   1026                 cb = new IAppOpsCallback.Stub() {
   1027                     public void opChanged(int op, String packageName) {
   1028                         if (callback instanceof OnOpChangedInternalListener) {
   1029                             ((OnOpChangedInternalListener)callback).onOpChanged(op, packageName);
   1030                         }
   1031                         if (sOpToString[op] != null) {
   1032                             callback.onOpChanged(sOpToString[op], packageName);
   1033                         }
   1034                     }
   1035                 };
   1036                 mModeWatchers.put(callback, cb);
   1037             }
   1038             try {
   1039                 mService.startWatchingMode(op, packageName, cb);
   1040             } catch (RemoteException e) {
   1041             }
   1042         }
   1043     }
   1044 
   1045     /**
   1046      * Stop monitoring that was previously started with {@link #startWatchingMode}.  All
   1047      * monitoring associated with this callback will be removed.
   1048      */
   1049     public void stopWatchingMode(OnOpChangedListener callback) {
   1050         synchronized (mModeWatchers) {
   1051             IAppOpsCallback cb = mModeWatchers.get(callback);
   1052             if (cb != null) {
   1053                 try {
   1054                     mService.stopWatchingMode(cb);
   1055                 } catch (RemoteException e) {
   1056                 }
   1057             }
   1058         }
   1059     }
   1060 
   1061     private String buildSecurityExceptionMsg(int op, int uid, String packageName) {
   1062         return packageName + " from uid " + uid + " not allowed to perform " + sOpNames[op];
   1063     }
   1064 
   1065     /**
   1066      * {@hide}
   1067      */
   1068     public static int strOpToOp(String op) {
   1069         Integer val = sOpStrToOp.get(op);
   1070         if (val == null) {
   1071             throw new IllegalArgumentException("Unknown operation string: " + op);
   1072         }
   1073         return val;
   1074     }
   1075 
   1076     /**
   1077      * Do a quick check for whether an application might be able to perform an operation.
   1078      * This is <em>not</em> a security check; you must use {@link #noteOp(String, int, String)}
   1079      * or {@link #startOp(String, int, String)} for your actual security checks, which also
   1080      * ensure that the given uid and package name are consistent.  This function can just be
   1081      * used for a quick check to see if an operation has been disabled for the application,
   1082      * as an early reject of some work.  This does not modify the time stamp or other data
   1083      * about the operation.
   1084      * @param op The operation to check.  One of the OPSTR_* constants.
   1085      * @param uid The user id of the application attempting to perform the operation.
   1086      * @param packageName The name of the application attempting to perform the operation.
   1087      * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
   1088      * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
   1089      * causing the app to crash).
   1090      * @throws SecurityException If the app has been configured to crash on this op.
   1091      */
   1092     public int checkOp(String op, int uid, String packageName) {
   1093         return checkOp(strOpToOp(op), uid, packageName);
   1094     }
   1095 
   1096     /**
   1097      * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
   1098      * returns {@link #MODE_ERRORED}.
   1099      */
   1100     public int checkOpNoThrow(String op, int uid, String packageName) {
   1101         return checkOpNoThrow(strOpToOp(op), uid, packageName);
   1102     }
   1103 
   1104     /**
   1105      * Make note of an application performing an operation.  Note that you must pass
   1106      * in both the uid and name of the application to be checked; this function will verify
   1107      * that these two match, and if not, return {@link #MODE_IGNORED}.  If this call
   1108      * succeeds, the last execution time of the operation for this app will be updated to
   1109      * the current time.
   1110      * @param op The operation to note.  One of the OPSTR_* constants.
   1111      * @param uid The user id of the application attempting to perform the operation.
   1112      * @param packageName The name of the application attempting to perform the operation.
   1113      * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
   1114      * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
   1115      * causing the app to crash).
   1116      * @throws SecurityException If the app has been configured to crash on this op.
   1117      */
   1118     public int noteOp(String op, int uid, String packageName) {
   1119         return noteOp(strOpToOp(op), uid, packageName);
   1120     }
   1121 
   1122     /**
   1123      * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
   1124      * returns {@link #MODE_ERRORED}.
   1125      */
   1126     public int noteOpNoThrow(String op, int uid, String packageName) {
   1127         return noteOpNoThrow(strOpToOp(op), uid, packageName);
   1128     }
   1129 
   1130     /**
   1131      * Report that an application has started executing a long-running operation.  Note that you
   1132      * must pass in both the uid and name of the application to be checked; this function will
   1133      * verify that these two match, and if not, return {@link #MODE_IGNORED}.  If this call
   1134      * succeeds, the last execution time of the operation for this app will be updated to
   1135      * the current time and the operation will be marked as "running".  In this case you must
   1136      * later call {@link #finishOp(String, int, String)} to report when the application is no
   1137      * longer performing the operation.
   1138      * @param op The operation to start.  One of the OPSTR_* constants.
   1139      * @param uid The user id of the application attempting to perform the operation.
   1140      * @param packageName The name of the application attempting to perform the operation.
   1141      * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
   1142      * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
   1143      * causing the app to crash).
   1144      * @throws SecurityException If the app has been configured to crash on this op.
   1145      */
   1146     public int startOp(String op, int uid, String packageName) {
   1147         return startOp(strOpToOp(op), uid, packageName);
   1148     }
   1149 
   1150     /**
   1151      * Like {@link #startOp} but instead of throwing a {@link SecurityException} it
   1152      * returns {@link #MODE_ERRORED}.
   1153      */
   1154     public int startOpNoThrow(String op, int uid, String packageName) {
   1155         return startOpNoThrow(strOpToOp(op), uid, packageName);
   1156     }
   1157 
   1158     /**
   1159      * Report that an application is no longer performing an operation that had previously
   1160      * been started with {@link #startOp(String, int, String)}.  There is no validation of input
   1161      * or result; the parameters supplied here must be the exact same ones previously passed
   1162      * in when starting the operation.
   1163      */
   1164     public void finishOp(String op, int uid, String packageName) {
   1165         finishOp(strOpToOp(op), uid, packageName);
   1166     }
   1167 
   1168     /**
   1169      * Do a quick check for whether an application might be able to perform an operation.
   1170      * This is <em>not</em> a security check; you must use {@link #noteOp(int, int, String)}
   1171      * or {@link #startOp(int, int, String)} for your actual security checks, which also
   1172      * ensure that the given uid and package name are consistent.  This function can just be
   1173      * used for a quick check to see if an operation has been disabled for the application,
   1174      * as an early reject of some work.  This does not modify the time stamp or other data
   1175      * about the operation.
   1176      * @param op The operation to check.  One of the OP_* constants.
   1177      * @param uid The user id of the application attempting to perform the operation.
   1178      * @param packageName The name of the application attempting to perform the operation.
   1179      * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
   1180      * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
   1181      * causing the app to crash).
   1182      * @throws SecurityException If the app has been configured to crash on this op.
   1183      * @hide
   1184      */
   1185     public int checkOp(int op, int uid, String packageName) {
   1186         try {
   1187             int mode = mService.checkOperation(op, uid, packageName);
   1188             if (mode == MODE_ERRORED) {
   1189                 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
   1190             }
   1191             return mode;
   1192         } catch (RemoteException e) {
   1193         }
   1194         return MODE_IGNORED;
   1195     }
   1196 
   1197     /**
   1198      * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
   1199      * returns {@link #MODE_ERRORED}.
   1200      * @hide
   1201      */
   1202     public int checkOpNoThrow(int op, int uid, String packageName) {
   1203         try {
   1204             return mService.checkOperation(op, uid, packageName);
   1205         } catch (RemoteException e) {
   1206         }
   1207         return MODE_IGNORED;
   1208     }
   1209 
   1210     /**
   1211      * Do a quick check to validate if a package name belongs to a UID.
   1212      *
   1213      * @throws SecurityException if the package name doesn't belong to the given
   1214      *             UID, or if ownership cannot be verified.
   1215      */
   1216     public void checkPackage(int uid, String packageName) {
   1217         try {
   1218             if (mService.checkPackage(uid, packageName) != MODE_ALLOWED) {
   1219                 throw new SecurityException(
   1220                         "Package " + packageName + " does not belong to " + uid);
   1221             }
   1222         } catch (RemoteException e) {
   1223             throw new SecurityException("Unable to verify package ownership", e);
   1224         }
   1225     }
   1226 
   1227     /**
   1228      * Like {@link #checkOp} but at a stream-level for audio operations.
   1229      * @hide
   1230      */
   1231     public int checkAudioOp(int op, int stream, int uid, String packageName) {
   1232         try {
   1233             final int mode = mService.checkAudioOperation(op, stream, uid, packageName);
   1234             if (mode == MODE_ERRORED) {
   1235                 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
   1236             }
   1237             return mode;
   1238         } catch (RemoteException e) {
   1239         }
   1240         return MODE_IGNORED;
   1241     }
   1242 
   1243     /**
   1244      * Like {@link #checkAudioOp} but instead of throwing a {@link SecurityException} it
   1245      * returns {@link #MODE_ERRORED}.
   1246      * @hide
   1247      */
   1248     public int checkAudioOpNoThrow(int op, int stream, int uid, String packageName) {
   1249         try {
   1250             return mService.checkAudioOperation(op, stream, uid, packageName);
   1251         } catch (RemoteException e) {
   1252         }
   1253         return MODE_IGNORED;
   1254     }
   1255 
   1256     /**
   1257      * Make note of an application performing an operation.  Note that you must pass
   1258      * in both the uid and name of the application to be checked; this function will verify
   1259      * that these two match, and if not, return {@link #MODE_IGNORED}.  If this call
   1260      * succeeds, the last execution time of the operation for this app will be updated to
   1261      * the current time.
   1262      * @param op The operation to note.  One of the OP_* constants.
   1263      * @param uid The user id of the application attempting to perform the operation.
   1264      * @param packageName The name of the application attempting to perform the operation.
   1265      * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
   1266      * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
   1267      * causing the app to crash).
   1268      * @throws SecurityException If the app has been configured to crash on this op.
   1269      * @hide
   1270      */
   1271     public int noteOp(int op, int uid, String packageName) {
   1272         try {
   1273             int mode = mService.noteOperation(op, uid, packageName);
   1274             if (mode == MODE_ERRORED) {
   1275                 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
   1276             }
   1277             return mode;
   1278         } catch (RemoteException e) {
   1279         }
   1280         return MODE_IGNORED;
   1281     }
   1282 
   1283     /**
   1284      * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
   1285      * returns {@link #MODE_ERRORED}.
   1286      * @hide
   1287      */
   1288     public int noteOpNoThrow(int op, int uid, String packageName) {
   1289         try {
   1290             return mService.noteOperation(op, uid, packageName);
   1291         } catch (RemoteException e) {
   1292         }
   1293         return MODE_IGNORED;
   1294     }
   1295 
   1296     /** @hide */
   1297     public int noteOp(int op) {
   1298         return noteOp(op, Process.myUid(), mContext.getOpPackageName());
   1299     }
   1300 
   1301     /** @hide */
   1302     public static IBinder getToken(IAppOpsService service) {
   1303         synchronized (AppOpsManager.class) {
   1304             if (sToken != null) {
   1305                 return sToken;
   1306             }
   1307             try {
   1308                 sToken = service.getToken(new Binder());
   1309             } catch (RemoteException e) {
   1310                 // System is dead, whatevs.
   1311             }
   1312             return sToken;
   1313         }
   1314     }
   1315 
   1316     /**
   1317      * Report that an application has started executing a long-running operation.  Note that you
   1318      * must pass in both the uid and name of the application to be checked; this function will
   1319      * verify that these two match, and if not, return {@link #MODE_IGNORED}.  If this call
   1320      * succeeds, the last execution time of the operation for this app will be updated to
   1321      * the current time and the operation will be marked as "running".  In this case you must
   1322      * later call {@link #finishOp(int, int, String)} to report when the application is no
   1323      * longer performing the operation.
   1324      * @param op The operation to start.  One of the OP_* constants.
   1325      * @param uid The user id of the application attempting to perform the operation.
   1326      * @param packageName The name of the application attempting to perform the operation.
   1327      * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
   1328      * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
   1329      * causing the app to crash).
   1330      * @throws SecurityException If the app has been configured to crash on this op.
   1331      * @hide
   1332      */
   1333     public int startOp(int op, int uid, String packageName) {
   1334         try {
   1335             int mode = mService.startOperation(getToken(mService), op, uid, packageName);
   1336             if (mode == MODE_ERRORED) {
   1337                 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
   1338             }
   1339             return mode;
   1340         } catch (RemoteException e) {
   1341         }
   1342         return MODE_IGNORED;
   1343     }
   1344 
   1345     /**
   1346      * Like {@link #startOp} but instead of throwing a {@link SecurityException} it
   1347      * returns {@link #MODE_ERRORED}.
   1348      * @hide
   1349      */
   1350     public int startOpNoThrow(int op, int uid, String packageName) {
   1351         try {
   1352             return mService.startOperation(getToken(mService), op, uid, packageName);
   1353         } catch (RemoteException e) {
   1354         }
   1355         return MODE_IGNORED;
   1356     }
   1357 
   1358     /** @hide */
   1359     public int startOp(int op) {
   1360         return startOp(op, Process.myUid(), mContext.getOpPackageName());
   1361     }
   1362 
   1363     /**
   1364      * Report that an application is no longer performing an operation that had previously
   1365      * been started with {@link #startOp(int, int, String)}.  There is no validation of input
   1366      * or result; the parameters supplied here must be the exact same ones previously passed
   1367      * in when starting the operation.
   1368      * @hide
   1369      */
   1370     public void finishOp(int op, int uid, String packageName) {
   1371         try {
   1372             mService.finishOperation(getToken(mService), op, uid, packageName);
   1373         } catch (RemoteException e) {
   1374         }
   1375     }
   1376 
   1377     /** @hide */
   1378     public void finishOp(int op) {
   1379         finishOp(op, Process.myUid(), mContext.getOpPackageName());
   1380     }
   1381 }
   1382