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