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