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