1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.app;
18 
19 import android.Manifest;
20 import android.annotation.SystemApi;
21 import android.app.usage.UsageStatsManager;
22 import android.content.Context;
23 import android.media.AudioAttributes.AttributeUsage;
24 import android.os.Binder;
25 import android.os.IBinder;
26 import android.os.Parcel;
27 import android.os.Parcelable;
28 import android.os.Process;
29 import android.os.RemoteException;
30 import android.os.UserHandle;
31 import android.os.UserManager;
32 import android.util.ArrayMap;
33 
34 import com.android.internal.app.IAppOpsCallback;
35 import com.android.internal.app.IAppOpsService;
36 
37 import java.util.ArrayList;
38 import java.util.HashMap;
39 import 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  */
49 public 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_SMS,
407             OP_RECEIVE_SMS,
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) {
sOpStrToOp.put(sOpToString[i], i)999                 sOpStrToOp.put(sOpToString[i], i);
1000             }
1001         }
1002         for (int op : RUNTIME_PERMISSIONS_OPS) {
1003             if (sOpPerms[op] != null) {
sRuntimePermToOp.put(sOpPerms[op], op)1004                 sRuntimePermToOp.put(sOpPerms[op], op);
1005             }
1006         }
1007     }
1008 
1009     /**
1010      * Retrieve the op switch that controls the given operation.
1011      * @hide
1012      */
opToSwitch(int op)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      */
opToName(int op)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      */
strDebugOpToOp(String op)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      */
opToPermission(int op)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      */
opToRestriction(int op)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      */
permissionToOpCode(String permission)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      */
opAllowSystemBypassRestriction(int op)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      */
opToDefaultMode(int op)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      */
opAllowsReset(int op)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 
PackageOps(String packageName, int uid, List<OpEntry> entries)1099         public PackageOps(String packageName, int uid, List<OpEntry> entries) {
1100             mPackageName = packageName;
1101             mUid = uid;
1102             mEntries = entries;
1103         }
1104 
getPackageName()1105         public String getPackageName() {
1106             return mPackageName;
1107         }
1108 
getUid()1109         public int getUid() {
1110             return mUid;
1111         }
1112 
getOps()1113         public List<OpEntry> getOps() {
1114             return mEntries;
1115         }
1116 
1117         @Override
describeContents()1118         public int describeContents() {
1119             return 0;
1120         }
1121 
1122         @Override
writeToParcel(Parcel dest, int flags)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 
PackageOps(Parcel source)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 
OpEntry(int op, int mode, long time, long rejectTime, int duration, int proxyUid, String proxyPackage)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 
getOp()1177         public int getOp() {
1178             return mOp;
1179         }
1180 
getMode()1181         public int getMode() {
1182             return mMode;
1183         }
1184 
getTime()1185         public long getTime() {
1186             return mTime;
1187         }
1188 
getRejectTime()1189         public long getRejectTime() {
1190             return mRejectTime;
1191         }
1192 
isRunning()1193         public boolean isRunning() {
1194             return mDuration == -1;
1195         }
1196 
getDuration()1197         public int getDuration() {
1198             return mDuration == -1 ? (int)(System.currentTimeMillis()-mTime) : mDuration;
1199         }
1200 
getProxyUid()1201         public int getProxyUid() {
1202             return  mProxyUid;
1203         }
1204 
getProxyPackageName()1205         public String getProxyPackageName() {
1206             return mProxyPackageName;
1207         }
1208 
1209         @Override
describeContents()1210         public int describeContents() {
1211             return 0;
1212         }
1213 
1214         @Override
writeToParcel(Parcel dest, int flags)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 
OpEntry(Parcel source)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 {
onOpChanged(String op, String packageName)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 {
onOpChanged(String op, String packageName)1259         public void onOpChanged(String op, String packageName) { }
onOpChanged(int op, String packageName)1260         public void onOpChanged(int op, String packageName) { }
1261     }
1262 
AppOpsManager(Context context, IAppOpsService service)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      */
getPackagesForOps(int[] ops)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      */
getOpsForPackage(int uid, String packageName, int[] ops)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      */
setUidMode(int code, int uid, int mode)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
setUidMode(String appOp, int uid, int mode)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 */
setUserRestriction(int code, boolean restricted, IBinder token)1336     public void setUserRestriction(int code, boolean restricted, IBinder token) {
1337         setUserRestriction(code, restricted, token, /*exceptionPackages*/null);
1338     }
1339 
1340     /** @hide */
setUserRestriction(int code, boolean restricted, IBinder token, String[] exceptionPackages)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 */
setUserRestrictionForUser(int code, boolean restricted, IBinder token, String[] exceptionPackages, int userId)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 */
setMode(int code, int uid, String packageName, int mode)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      */
setRestriction(int code, @AttributeUsage int usage, int mode, String[] exceptionPackages)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 */
resetAllModes()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      */
permissionToOp(String permission)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      */
startWatchingMode(String op, String packageName, final OnOpChangedListener callback)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      */
startWatchingMode(int op, String packageName, final OnOpChangedListener callback)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      */
stopWatchingMode(OnOpChangedListener callback)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 
buildSecurityExceptionMsg(int op, int uid, String packageName)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      */
strOpToOp(String op)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      */
checkOp(String op, int uid, String packageName)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      */
checkOpNoThrow(String op, int uid, String packageName)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      */
noteOp(String op, int uid, String packageName)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      */
noteOpNoThrow(String op, int uid, String packageName)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      */
noteProxyOp(String op, String proxiedPackageName)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      */
noteProxyOpNoThrow(String op, String proxiedPackageName)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      */
startOp(String op, int uid, String packageName)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      */
startOpNoThrow(String op, int uid, String packageName)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      */
finishOp(String op, int uid, String packageName)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      */
checkOp(int op, int uid, String packageName)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      */
checkOpNoThrow(int op, int uid, String packageName)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      */
checkPackage(int uid, String packageName)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      */
checkAudioOp(int op, int stream, int uid, String packageName)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      */
checkAudioOpNoThrow(int op, int stream, int uid, String packageName)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      */
noteOp(int op, int uid, String packageName)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      */
noteProxyOp(int op, String proxiedPackageName)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      */
noteProxyOpNoThrow(int op, String proxiedPackageName)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      */
noteOpNoThrow(int op, int uid, String packageName)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 */
noteOp(int op)1778     public int noteOp(int op) {
1779         return noteOp(op, Process.myUid(), mContext.getOpPackageName());
1780     }
1781 
1782     /** @hide */
getToken(IAppOpsService service)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      */
startOp(int op, int uid, String packageName)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      */
startOpNoThrow(int op, int uid, String packageName)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 */
startOp(int op)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      */
finishOp(int op, int uid, String packageName)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 */
finishOp(int op)1860     public void finishOp(int op) {
1861         finishOp(op, Process.myUid(), mContext.getOpPackageName());
1862     }
1863 }
1864