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