AppOpsManager.java revision 1bb42067f077bed8c865d8cef2f4b397be4d996e
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.NonNull;
21import android.annotation.RequiresPermission;
22import android.annotation.SystemApi;
23import android.annotation.SystemService;
24import android.annotation.TestApi;
25import android.app.usage.UsageStatsManager;
26import android.content.Context;
27import android.media.AudioAttributes.AttributeUsage;
28import android.os.Binder;
29import android.os.IBinder;
30import android.os.Parcel;
31import android.os.Parcelable;
32import android.os.Process;
33import android.os.RemoteException;
34import android.os.UserManager;
35import android.util.ArrayMap;
36
37import com.android.internal.app.IAppOpsActiveCallback;
38import com.android.internal.app.IAppOpsCallback;
39import com.android.internal.app.IAppOpsService;
40import com.android.internal.util.Preconditions;
41
42import java.util.ArrayList;
43import java.util.Arrays;
44import java.util.HashMap;
45import java.util.List;
46
47/**
48 * API for interacting with "application operation" tracking.
49 *
50 * <p>This API is not generally intended for third party application developers; most
51 * features are only available to system applications.
52 */
53@SystemService(Context.APP_OPS_SERVICE)
54public class AppOpsManager {
55    /**
56     * <p>App ops allows callers to:</p>
57     *
58     * <ul>
59     * <li> Note when operations are happening, and find out if they are allowed for the current
60     * caller.</li>
61     * <li> Disallow specific apps from doing specific operations.</li>
62     * <li> Collect all of the current information about operations that have been executed or
63     * are not being allowed.</li>
64     * <li> Monitor for changes in whether an operation is allowed.</li>
65     * </ul>
66     *
67     * <p>Each operation is identified by a single integer; these integers are a fixed set of
68     * operations, enumerated by the OP_* constants.
69     *
70     * <p></p>When checking operations, the result is a "mode" integer indicating the current
71     * setting for the operation under that caller: MODE_ALLOWED, MODE_IGNORED (don't execute
72     * the operation but fake its behavior enough so that the caller doesn't crash),
73     * MODE_ERRORED (throw a SecurityException back to the caller; the normal operation calls
74     * will do this for you).
75     */
76
77    final Context mContext;
78    final IAppOpsService mService;
79    final ArrayMap<OnOpChangedListener, IAppOpsCallback> mModeWatchers = new ArrayMap<>();
80    final ArrayMap<OnOpActiveChangedListener, IAppOpsActiveCallback> mActiveWatchers =
81            new ArrayMap<>();
82
83    static IBinder sToken;
84
85    /**
86     * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is
87     * allowed to perform the given operation.
88     */
89    public static final int MODE_ALLOWED = 0;
90
91    /**
92     * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is
93     * not allowed to perform the given operation, and this attempt should
94     * <em>silently fail</em> (it should not cause the app to crash).
95     */
96    public static final int MODE_IGNORED = 1;
97
98    /**
99     * Result from {@link #checkOpNoThrow}, {@link #noteOpNoThrow}, {@link #startOpNoThrow}: the
100     * given caller is not allowed to perform the given operation, and this attempt should
101     * cause it to have a fatal error, typically a {@link SecurityException}.
102     */
103    public static final int MODE_ERRORED = 2;
104
105    /**
106     * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller should
107     * use its default security check.  This mode is not normally used; it should only be used
108     * with appop permissions, and callers must explicitly check for it and deal with it.
109     */
110    public static final int MODE_DEFAULT = 3;
111
112    // when adding one of these:
113    //  - increment _NUM_OP
114    //  - define an OPSTR_* constant (marked as @SystemApi)
115    //  - add rows to sOpToSwitch, sOpToString, sOpNames, sOpToPerms, sOpDefault
116    //  - add descriptive strings to Settings/res/values/arrays.xml
117    //  - add the op to the appropriate template in AppOpsState.OpsTemplate (settings app)
118
119    /** @hide No operation specified. */
120    public static final int OP_NONE = -1;
121    /** @hide Access to coarse location information. */
122    public static final int OP_COARSE_LOCATION = 0;
123    /** @hide Access to fine location information. */
124    public static final int OP_FINE_LOCATION = 1;
125    /** @hide Causing GPS to run. */
126    public static final int OP_GPS = 2;
127    /** @hide */
128    public static final int OP_VIBRATE = 3;
129    /** @hide */
130    public static final int OP_READ_CONTACTS = 4;
131    /** @hide */
132    public static final int OP_WRITE_CONTACTS = 5;
133    /** @hide */
134    public static final int OP_READ_CALL_LOG = 6;
135    /** @hide */
136    public static final int OP_WRITE_CALL_LOG = 7;
137    /** @hide */
138    public static final int OP_READ_CALENDAR = 8;
139    /** @hide */
140    public static final int OP_WRITE_CALENDAR = 9;
141    /** @hide */
142    public static final int OP_WIFI_SCAN = 10;
143    /** @hide */
144    public static final int OP_POST_NOTIFICATION = 11;
145    /** @hide */
146    public static final int OP_NEIGHBORING_CELLS = 12;
147    /** @hide */
148    public static final int OP_CALL_PHONE = 13;
149    /** @hide */
150    public static final int OP_READ_SMS = 14;
151    /** @hide */
152    public static final int OP_WRITE_SMS = 15;
153    /** @hide */
154    public static final int OP_RECEIVE_SMS = 16;
155    /** @hide */
156    public static final int OP_RECEIVE_EMERGECY_SMS = 17;
157    /** @hide */
158    public static final int OP_RECEIVE_MMS = 18;
159    /** @hide */
160    public static final int OP_RECEIVE_WAP_PUSH = 19;
161    /** @hide */
162    public static final int OP_SEND_SMS = 20;
163    /** @hide */
164    public static final int OP_READ_ICC_SMS = 21;
165    /** @hide */
166    public static final int OP_WRITE_ICC_SMS = 22;
167    /** @hide */
168    public static final int OP_WRITE_SETTINGS = 23;
169    /** @hide Required to draw on top of other apps. */
170    @TestApi
171    public static final int OP_SYSTEM_ALERT_WINDOW = 24;
172    /** @hide */
173    public static final int OP_ACCESS_NOTIFICATIONS = 25;
174    /** @hide */
175    public static final int OP_CAMERA = 26;
176    /** @hide */
177    @TestApi
178    public static final int OP_RECORD_AUDIO = 27;
179    /** @hide */
180    public static final int OP_PLAY_AUDIO = 28;
181    /** @hide */
182    public static final int OP_READ_CLIPBOARD = 29;
183    /** @hide */
184    public static final int OP_WRITE_CLIPBOARD = 30;
185    /** @hide */
186    public static final int OP_TAKE_MEDIA_BUTTONS = 31;
187    /** @hide */
188    public static final int OP_TAKE_AUDIO_FOCUS = 32;
189    /** @hide */
190    public static final int OP_AUDIO_MASTER_VOLUME = 33;
191    /** @hide */
192    public static final int OP_AUDIO_VOICE_VOLUME = 34;
193    /** @hide */
194    public static final int OP_AUDIO_RING_VOLUME = 35;
195    /** @hide */
196    public static final int OP_AUDIO_MEDIA_VOLUME = 36;
197    /** @hide */
198    public static final int OP_AUDIO_ALARM_VOLUME = 37;
199    /** @hide */
200    public static final int OP_AUDIO_NOTIFICATION_VOLUME = 38;
201    /** @hide */
202    public static final int OP_AUDIO_BLUETOOTH_VOLUME = 39;
203    /** @hide */
204    public static final int OP_WAKE_LOCK = 40;
205    /** @hide Continually monitoring location data. */
206    public static final int OP_MONITOR_LOCATION = 41;
207    /** @hide Continually monitoring location data with a relatively high power request. */
208    public static final int OP_MONITOR_HIGH_POWER_LOCATION = 42;
209    /** @hide Retrieve current usage stats via {@link UsageStatsManager}. */
210    public static final int OP_GET_USAGE_STATS = 43;
211    /** @hide */
212    public static final int OP_MUTE_MICROPHONE = 44;
213    /** @hide */
214    public static final int OP_TOAST_WINDOW = 45;
215    /** @hide Capture the device's display contents and/or audio */
216    public static final int OP_PROJECT_MEDIA = 46;
217    /** @hide Activate a VPN connection without user intervention. */
218    public static final int OP_ACTIVATE_VPN = 47;
219    /** @hide Access the WallpaperManagerAPI to write wallpapers. */
220    public static final int OP_WRITE_WALLPAPER = 48;
221    /** @hide Received the assist structure from an app. */
222    public static final int OP_ASSIST_STRUCTURE = 49;
223    /** @hide Received a screenshot from assist. */
224    public static final int OP_ASSIST_SCREENSHOT = 50;
225    /** @hide Read the phone state. */
226    public static final int OP_READ_PHONE_STATE = 51;
227    /** @hide Add voicemail messages to the voicemail content provider. */
228    public static final int OP_ADD_VOICEMAIL = 52;
229    /** @hide Access APIs for SIP calling over VOIP or WiFi. */
230    public static final int OP_USE_SIP = 53;
231    /** @hide Intercept outgoing calls. */
232    public static final int OP_PROCESS_OUTGOING_CALLS = 54;
233    /** @hide User the fingerprint API. */
234    public static final int OP_USE_FINGERPRINT = 55;
235    /** @hide Access to body sensors such as heart rate, etc. */
236    public static final int OP_BODY_SENSORS = 56;
237    /** @hide Read previously received cell broadcast messages. */
238    public static final int OP_READ_CELL_BROADCASTS = 57;
239    /** @hide Inject mock location into the system. */
240    public static final int OP_MOCK_LOCATION = 58;
241    /** @hide Read external storage. */
242    public static final int OP_READ_EXTERNAL_STORAGE = 59;
243    /** @hide Write external storage. */
244    public static final int OP_WRITE_EXTERNAL_STORAGE = 60;
245    /** @hide Turned on the screen. */
246    public static final int OP_TURN_SCREEN_ON = 61;
247    /** @hide Get device accounts. */
248    public static final int OP_GET_ACCOUNTS = 62;
249    /** @hide Control whether an application is allowed to run in the background. */
250    public static final int OP_RUN_IN_BACKGROUND = 63;
251    /** @hide */
252    public static final int OP_AUDIO_ACCESSIBILITY_VOLUME = 64;
253    /** @hide Read the phone number. */
254    public static final int OP_READ_PHONE_NUMBERS = 65;
255    /** @hide Request package installs through package installer */
256    public static final int OP_REQUEST_INSTALL_PACKAGES = 66;
257    /** @hide Enter picture-in-picture. */
258    public static final int OP_PICTURE_IN_PICTURE = 67;
259    /** @hide Instant app start foreground service. */
260    public static final int OP_INSTANT_APP_START_FOREGROUND = 68;
261    /** @hide Answer incoming phone calls */
262    public static final int OP_ANSWER_PHONE_CALLS = 69;
263    /** @hide Run jobs when in background */
264    public static final int OP_RUN_ANY_IN_BACKGROUND = 70;
265    /** @hide Change Wi-Fi connectivity state */
266    public static final int OP_CHANGE_WIFI_STATE = 71;
267    /** @hide Request package deletion through package installer */
268    public static final int OP_REQUEST_DELETE_PACKAGES = 72;
269    /** @hide Bind an accessibility service. */
270    public static final int OP_BIND_ACCESSIBILITY_SERVICE = 73;
271    /** @hide Continue handover of a call from another app */
272    public static final int OP_ACCEPT_HANDOVER = 74;
273    /** @hide Create and Manage IPsec Tunnels */
274    public static final int OP_MANAGE_IPSEC_TUNNELS = 75;
275    /** @hide */
276    public static final int _NUM_OP = 76;
277
278    /** Access to coarse location information. */
279    public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
280    /** Access to fine location information. */
281    public static final String OPSTR_FINE_LOCATION =
282            "android:fine_location";
283    /** Continually monitoring location data. */
284    public static final String OPSTR_MONITOR_LOCATION
285            = "android:monitor_location";
286    /** Continually monitoring location data with a relatively high power request. */
287    public static final String OPSTR_MONITOR_HIGH_POWER_LOCATION
288            = "android:monitor_location_high_power";
289    /** Access to {@link android.app.usage.UsageStatsManager}. */
290    public static final String OPSTR_GET_USAGE_STATS
291            = "android:get_usage_stats";
292    /** Activate a VPN connection without user intervention. @hide */
293    @SystemApi @TestApi
294    public static final String OPSTR_ACTIVATE_VPN
295            = "android:activate_vpn";
296    /** Allows an application to read the user's contacts data. */
297    public static final String OPSTR_READ_CONTACTS
298            = "android:read_contacts";
299    /** Allows an application to write to the user's contacts data. */
300    public static final String OPSTR_WRITE_CONTACTS
301            = "android:write_contacts";
302    /** Allows an application to read the user's call log. */
303    public static final String OPSTR_READ_CALL_LOG
304            = "android:read_call_log";
305    /** Allows an application to write to the user's call log. */
306    public static final String OPSTR_WRITE_CALL_LOG
307            = "android:write_call_log";
308    /** Allows an application to read the user's calendar data. */
309    public static final String OPSTR_READ_CALENDAR
310            = "android:read_calendar";
311    /** Allows an application to write to the user's calendar data. */
312    public static final String OPSTR_WRITE_CALENDAR
313            = "android:write_calendar";
314    /** Allows an application to initiate a phone call. */
315    public static final String OPSTR_CALL_PHONE
316            = "android:call_phone";
317    /** Allows an application to read SMS messages. */
318    public static final String OPSTR_READ_SMS
319            = "android:read_sms";
320    /** Allows an application to receive SMS messages. */
321    public static final String OPSTR_RECEIVE_SMS
322            = "android:receive_sms";
323    /** Allows an application to receive MMS messages. */
324    public static final String OPSTR_RECEIVE_MMS
325            = "android:receive_mms";
326    /** Allows an application to receive WAP push messages. */
327    public static final String OPSTR_RECEIVE_WAP_PUSH
328            = "android:receive_wap_push";
329    /** Allows an application to send SMS messages. */
330    public static final String OPSTR_SEND_SMS
331            = "android:send_sms";
332    /** Required to be able to access the camera device. */
333    public static final String OPSTR_CAMERA
334            = "android:camera";
335    /** Required to be able to access the microphone device. */
336    public static final String OPSTR_RECORD_AUDIO
337            = "android:record_audio";
338    /** Required to access phone state related information. */
339    public static final String OPSTR_READ_PHONE_STATE
340            = "android:read_phone_state";
341    /** Required to access phone state related information. */
342    public static final String OPSTR_ADD_VOICEMAIL
343            = "android:add_voicemail";
344    /** Access APIs for SIP calling over VOIP or WiFi */
345    public static final String OPSTR_USE_SIP
346            = "android:use_sip";
347    /** Access APIs for diverting outgoing calls */
348    public static final String OPSTR_PROCESS_OUTGOING_CALLS
349            = "android:process_outgoing_calls";
350    /** Use the fingerprint API. */
351    public static final String OPSTR_USE_FINGERPRINT
352            = "android:use_fingerprint";
353    /** Access to body sensors such as heart rate, etc. */
354    public static final String OPSTR_BODY_SENSORS
355            = "android:body_sensors";
356    /** Read previously received cell broadcast messages. */
357    public static final String OPSTR_READ_CELL_BROADCASTS
358            = "android:read_cell_broadcasts";
359    /** Inject mock location into the system. */
360    public static final String OPSTR_MOCK_LOCATION
361            = "android:mock_location";
362    /** Read external storage. */
363    public static final String OPSTR_READ_EXTERNAL_STORAGE
364            = "android:read_external_storage";
365    /** Write external storage. */
366    public static final String OPSTR_WRITE_EXTERNAL_STORAGE
367            = "android:write_external_storage";
368    /** Required to draw on top of other apps. */
369    public static final String OPSTR_SYSTEM_ALERT_WINDOW
370            = "android:system_alert_window";
371    /** Required to write/modify/update system settingss. */
372    public static final String OPSTR_WRITE_SETTINGS
373            = "android:write_settings";
374    /** @hide Get device accounts. */
375    @SystemApi @TestApi
376    public static final String OPSTR_GET_ACCOUNTS
377            = "android:get_accounts";
378    public static final String OPSTR_READ_PHONE_NUMBERS
379            = "android:read_phone_numbers";
380    /** Access to picture-in-picture. */
381    public static final String OPSTR_PICTURE_IN_PICTURE
382            = "android:picture_in_picture";
383    /** @hide */
384    @SystemApi @TestApi
385    public static final String OPSTR_INSTANT_APP_START_FOREGROUND
386            = "android:instant_app_start_foreground";
387    /** Answer incoming phone calls */
388    public static final String OPSTR_ANSWER_PHONE_CALLS
389            = "android:answer_phone_calls";
390    /**
391     * Accept call handover
392     * @hide
393     */
394    @SystemApi @TestApi
395    public static final String OPSTR_ACCEPT_HANDOVER
396            = "android:accept_handover";
397    /** @hide */
398    @SystemApi @TestApi
399    public static final String OPSTR_GPS = "android:gps";
400    /** @hide */
401    @SystemApi @TestApi
402    public static final String OPSTR_VIBRATE = "android:vibrate";
403    /** @hide */
404    @SystemApi @TestApi
405    public static final String OPSTR_WIFI_SCAN = "android:wifi_scan";
406    /** @hide */
407    @SystemApi @TestApi
408    public static final String OPSTR_POST_NOTIFICATION = "android:post_notification";
409    /** @hide */
410    @SystemApi @TestApi
411    public static final String OPSTR_NEIGHBORING_CELLS = "android:neighboring_cells";
412    /** @hide */
413    @SystemApi @TestApi
414    public static final String OPSTR_WRITE_SMS = "android:write_sms";
415    /** @hide */
416    @SystemApi @TestApi
417    public static final String OPSTR_RECEIVE_EMERGENCY_BROADCAST =
418            "android:receive_emergency_broadcast";
419    /** @hide */
420    @SystemApi @TestApi
421    public static final String OPSTR_READ_ICC_SMS = "android:read_icc_sms";
422    /** @hide */
423    @SystemApi @TestApi
424    public static final String OPSTR_WRITE_ICC_SMS = "android:write_icc_sms";
425    /** @hide */
426    @SystemApi @TestApi
427    public static final String OPSTR_ACCESS_NOTIFICATIONS = "android:access_notifications";
428    /** @hide */
429    @SystemApi @TestApi
430    public static final String OPSTR_PLAY_AUDIO = "android:play_audio";
431    /** @hide */
432    @SystemApi @TestApi
433    public static final String OPSTR_READ_CLIPBOARD = "android:read_clipboard";
434    /** @hide */
435    @SystemApi @TestApi
436    public static final String OPSTR_WRITE_CLIPBOARD = "android:write_clipboard";
437    /** @hide */
438    @SystemApi @TestApi
439    public static final String OPSTR_TAKE_MEDIA_BUTTONS = "android:take_media_buttons";
440    /** @hide */
441    @SystemApi @TestApi
442    public static final String OPSTR_TAKE_AUDIO_FOCUS = "android:take_audio_focus";
443    /** @hide */
444    @SystemApi @TestApi
445    public static final String OPSTR_AUDIO_MASTER_VOLUME = "android:audio_master_volume";
446    /** @hide */
447    @SystemApi @TestApi
448    public static final String OPSTR_AUDIO_VOICE_VOLUME = "android:audio_voice_volume";
449    /** @hide */
450    @SystemApi @TestApi
451    public static final String OPSTR_AUDIO_RING_VOLUME = "android:audio_ring_volume";
452    /** @hide */
453    @SystemApi @TestApi
454    public static final String OPSTR_AUDIO_MEDIA_VOLUME = "android:audio_media_volume";
455    /** @hide */
456    @SystemApi @TestApi
457    public static final String OPSTR_AUDIO_ALARM_VOLUME = "android:audio_alarm_volume";
458    /** @hide */
459    @SystemApi @TestApi
460    public static final String OPSTR_AUDIO_NOTIFICATION_VOLUME =
461            "android:audio_notification_volume";
462    /** @hide */
463    @SystemApi @TestApi
464    public static final String OPSTR_AUDIO_BLUETOOTH_VOLUME = "android:audio_bluetooth_volume";
465    /** @hide */
466    @SystemApi @TestApi
467    public static final String OPSTR_WAKE_LOCK = "android:wake_lock";
468    /** @hide */
469    @SystemApi @TestApi
470    public static final String OPSTR_MUTE_MICROPHONE = "android:mute_microphone";
471    /** @hide */
472    @SystemApi @TestApi
473    public static final String OPSTR_TOAST_WINDOW = "android:toast_window";
474    /** @hide */
475    @SystemApi @TestApi
476    public static final String OPSTR_PROJECT_MEDIA = "android:project_media";
477    /** @hide */
478    @SystemApi @TestApi
479    public static final String OPSTR_WRITE_WALLPAPER = "android:write_wallpaper";
480    /** @hide */
481    @SystemApi @TestApi
482    public static final String OPSTR_ASSIST_STRUCTURE = "android:assist_structure";
483    /** @hide */
484    @SystemApi @TestApi
485    public static final String OPSTR_ASSIST_SCREENSHOT = "android:assist_screenshot";
486    /** @hide */
487    @SystemApi @TestApi
488    public static final String OPSTR_TURN_SCREEN_ON = "android:turn_screen_on";
489    /** @hide */
490    @SystemApi @TestApi
491    public static final String OPSTR_RUN_IN_BACKGROUND = "android:run_in_background";
492    /** @hide */
493    @SystemApi @TestApi
494    public static final String OPSTR_AUDIO_ACCESSIBILITY_VOLUME =
495            "android:audio_accessibility_volume";
496    /** @hide */
497    @SystemApi @TestApi
498    public static final String OPSTR_REQUEST_INSTALL_PACKAGES = "android:request_install_packages";
499    /** @hide */
500    @SystemApi @TestApi
501    public static final String OPSTR_RUN_ANY_IN_BACKGROUND = "android:run_any_in_background";
502    /** @hide */
503    @SystemApi @TestApi
504    public static final String OPSTR_CHANGE_WIFI_STATE = "android:change_wifi_state";
505    /** @hide */
506    @SystemApi @TestApi
507    public static final String OPSTR_REQUEST_DELETE_PACKAGES = "android:request_delete_packages";
508    /** @hide */
509    @SystemApi @TestApi
510    public static final String OPSTR_BIND_ACCESSIBILITY_SERVICE =
511            "android:bind_accessibility_service";
512    /** @hide */
513    @SystemApi @TestApi
514    public static final String OPSTR_MANAGE_IPSEC_TUNNELS = "android:manage_ipsec_tunnels";
515
516    // Warning: If an permission is added here it also has to be added to
517    // com.android.packageinstaller.permission.utils.EventLogger
518    private static final int[] RUNTIME_AND_APPOP_PERMISSIONS_OPS = {
519            // RUNTIME PERMISSIONS
520            // Contacts
521            OP_READ_CONTACTS,
522            OP_WRITE_CONTACTS,
523            OP_GET_ACCOUNTS,
524            // Calendar
525            OP_READ_CALENDAR,
526            OP_WRITE_CALENDAR,
527            // SMS
528            OP_SEND_SMS,
529            OP_RECEIVE_SMS,
530            OP_READ_SMS,
531            OP_RECEIVE_WAP_PUSH,
532            OP_RECEIVE_MMS,
533            OP_READ_CELL_BROADCASTS,
534            // Storage
535            OP_READ_EXTERNAL_STORAGE,
536            OP_WRITE_EXTERNAL_STORAGE,
537            // Location
538            OP_COARSE_LOCATION,
539            OP_FINE_LOCATION,
540            // Phone
541            OP_READ_PHONE_STATE,
542            OP_READ_PHONE_NUMBERS,
543            OP_CALL_PHONE,
544            OP_READ_CALL_LOG,
545            OP_WRITE_CALL_LOG,
546            OP_ADD_VOICEMAIL,
547            OP_USE_SIP,
548            OP_PROCESS_OUTGOING_CALLS,
549            OP_ANSWER_PHONE_CALLS,
550            OP_ACCEPT_HANDOVER,
551            // Microphone
552            OP_RECORD_AUDIO,
553            // Camera
554            OP_CAMERA,
555            // Body sensors
556            OP_BODY_SENSORS,
557
558            // APPOP PERMISSIONS
559            OP_ACCESS_NOTIFICATIONS,
560            OP_SYSTEM_ALERT_WINDOW,
561            OP_WRITE_SETTINGS,
562            OP_REQUEST_INSTALL_PACKAGES,
563    };
564
565    /**
566     * This maps each operation to the operation that serves as the
567     * switch to determine whether it is allowed.  Generally this is
568     * a 1:1 mapping, but for some things (like location) that have
569     * multiple low-level operations being tracked that should be
570     * presented to the user as one switch then this can be used to
571     * make them all controlled by the same single operation.
572     */
573    private static int[] sOpToSwitch = new int[] {
574            OP_COARSE_LOCATION,
575            OP_COARSE_LOCATION,
576            OP_COARSE_LOCATION,
577            OP_VIBRATE,
578            OP_READ_CONTACTS,
579            OP_WRITE_CONTACTS,
580            OP_READ_CALL_LOG,
581            OP_WRITE_CALL_LOG,
582            OP_READ_CALENDAR,
583            OP_WRITE_CALENDAR,
584            OP_COARSE_LOCATION,
585            OP_POST_NOTIFICATION,
586            OP_COARSE_LOCATION,
587            OP_CALL_PHONE,
588            OP_READ_SMS,
589            OP_WRITE_SMS,
590            OP_RECEIVE_SMS,
591            OP_RECEIVE_SMS,
592            OP_RECEIVE_MMS,
593            OP_RECEIVE_WAP_PUSH,
594            OP_SEND_SMS,
595            OP_READ_SMS,
596            OP_WRITE_SMS,
597            OP_WRITE_SETTINGS,
598            OP_SYSTEM_ALERT_WINDOW,
599            OP_ACCESS_NOTIFICATIONS,
600            OP_CAMERA,
601            OP_RECORD_AUDIO,
602            OP_PLAY_AUDIO,
603            OP_READ_CLIPBOARD,
604            OP_WRITE_CLIPBOARD,
605            OP_TAKE_MEDIA_BUTTONS,
606            OP_TAKE_AUDIO_FOCUS,
607            OP_AUDIO_MASTER_VOLUME,
608            OP_AUDIO_VOICE_VOLUME,
609            OP_AUDIO_RING_VOLUME,
610            OP_AUDIO_MEDIA_VOLUME,
611            OP_AUDIO_ALARM_VOLUME,
612            OP_AUDIO_NOTIFICATION_VOLUME,
613            OP_AUDIO_BLUETOOTH_VOLUME,
614            OP_WAKE_LOCK,
615            OP_COARSE_LOCATION,
616            OP_COARSE_LOCATION,
617            OP_GET_USAGE_STATS,
618            OP_MUTE_MICROPHONE,
619            OP_TOAST_WINDOW,
620            OP_PROJECT_MEDIA,
621            OP_ACTIVATE_VPN,
622            OP_WRITE_WALLPAPER,
623            OP_ASSIST_STRUCTURE,
624            OP_ASSIST_SCREENSHOT,
625            OP_READ_PHONE_STATE,
626            OP_ADD_VOICEMAIL,
627            OP_USE_SIP,
628            OP_PROCESS_OUTGOING_CALLS,
629            OP_USE_FINGERPRINT,
630            OP_BODY_SENSORS,
631            OP_READ_CELL_BROADCASTS,
632            OP_MOCK_LOCATION,
633            OP_READ_EXTERNAL_STORAGE,
634            OP_WRITE_EXTERNAL_STORAGE,
635            OP_TURN_SCREEN_ON,
636            OP_GET_ACCOUNTS,
637            OP_RUN_IN_BACKGROUND,
638            OP_AUDIO_ACCESSIBILITY_VOLUME,
639            OP_READ_PHONE_NUMBERS,
640            OP_REQUEST_INSTALL_PACKAGES,
641            OP_PICTURE_IN_PICTURE,
642            OP_INSTANT_APP_START_FOREGROUND,
643            OP_ANSWER_PHONE_CALLS,
644            OP_RUN_ANY_IN_BACKGROUND,
645            OP_CHANGE_WIFI_STATE,
646            OP_REQUEST_DELETE_PACKAGES,
647            OP_BIND_ACCESSIBILITY_SERVICE,
648            OP_ACCEPT_HANDOVER,
649            OP_MANAGE_IPSEC_TUNNELS,
650    };
651
652    /**
653     * This maps each operation to the public string constant for it.
654     */
655    private static String[] sOpToString = new String[]{
656            OPSTR_COARSE_LOCATION,
657            OPSTR_FINE_LOCATION,
658            OPSTR_GPS,
659            OPSTR_VIBRATE,
660            OPSTR_READ_CONTACTS,
661            OPSTR_WRITE_CONTACTS,
662            OPSTR_READ_CALL_LOG,
663            OPSTR_WRITE_CALL_LOG,
664            OPSTR_READ_CALENDAR,
665            OPSTR_WRITE_CALENDAR,
666            OPSTR_WIFI_SCAN,
667            OPSTR_POST_NOTIFICATION,
668            OPSTR_NEIGHBORING_CELLS,
669            OPSTR_CALL_PHONE,
670            OPSTR_READ_SMS,
671            OPSTR_WRITE_SMS,
672            OPSTR_RECEIVE_SMS,
673            OPSTR_RECEIVE_EMERGENCY_BROADCAST,
674            OPSTR_RECEIVE_MMS,
675            OPSTR_RECEIVE_WAP_PUSH,
676            OPSTR_SEND_SMS,
677            OPSTR_READ_ICC_SMS,
678            OPSTR_WRITE_ICC_SMS,
679            OPSTR_WRITE_SETTINGS,
680            OPSTR_SYSTEM_ALERT_WINDOW,
681            OPSTR_ACCESS_NOTIFICATIONS,
682            OPSTR_CAMERA,
683            OPSTR_RECORD_AUDIO,
684            OPSTR_PLAY_AUDIO,
685            OPSTR_READ_CLIPBOARD,
686            OPSTR_WRITE_CLIPBOARD,
687            OPSTR_TAKE_MEDIA_BUTTONS,
688            OPSTR_TAKE_AUDIO_FOCUS,
689            OPSTR_AUDIO_MASTER_VOLUME,
690            OPSTR_AUDIO_VOICE_VOLUME,
691            OPSTR_AUDIO_RING_VOLUME,
692            OPSTR_AUDIO_MEDIA_VOLUME,
693            OPSTR_AUDIO_ALARM_VOLUME,
694            OPSTR_AUDIO_NOTIFICATION_VOLUME,
695            OPSTR_AUDIO_BLUETOOTH_VOLUME,
696            OPSTR_WAKE_LOCK,
697            OPSTR_MONITOR_LOCATION,
698            OPSTR_MONITOR_HIGH_POWER_LOCATION,
699            OPSTR_GET_USAGE_STATS,
700            OPSTR_MUTE_MICROPHONE,
701            OPSTR_TOAST_WINDOW,
702            OPSTR_PROJECT_MEDIA,
703            OPSTR_ACTIVATE_VPN,
704            OPSTR_WRITE_WALLPAPER,
705            OPSTR_ASSIST_STRUCTURE,
706            OPSTR_ASSIST_SCREENSHOT,
707            OPSTR_READ_PHONE_STATE,
708            OPSTR_ADD_VOICEMAIL,
709            OPSTR_USE_SIP,
710            OPSTR_PROCESS_OUTGOING_CALLS,
711            OPSTR_USE_FINGERPRINT,
712            OPSTR_BODY_SENSORS,
713            OPSTR_READ_CELL_BROADCASTS,
714            OPSTR_MOCK_LOCATION,
715            OPSTR_READ_EXTERNAL_STORAGE,
716            OPSTR_WRITE_EXTERNAL_STORAGE,
717            OPSTR_TURN_SCREEN_ON,
718            OPSTR_GET_ACCOUNTS,
719            OPSTR_RUN_IN_BACKGROUND,
720            OPSTR_AUDIO_ACCESSIBILITY_VOLUME,
721            OPSTR_READ_PHONE_NUMBERS,
722            OPSTR_REQUEST_INSTALL_PACKAGES,
723            OPSTR_PICTURE_IN_PICTURE,
724            OPSTR_INSTANT_APP_START_FOREGROUND,
725            OPSTR_ANSWER_PHONE_CALLS,
726            OPSTR_RUN_ANY_IN_BACKGROUND,
727            OPSTR_CHANGE_WIFI_STATE,
728            OPSTR_REQUEST_DELETE_PACKAGES,
729            OPSTR_BIND_ACCESSIBILITY_SERVICE,
730            OPSTR_ACCEPT_HANDOVER,
731            OPSTR_MANAGE_IPSEC_TUNNELS,
732    };
733
734    /**
735     * This provides a simple name for each operation to be used
736     * in debug output.
737     */
738    private static String[] sOpNames = new String[] {
739            "COARSE_LOCATION",
740            "FINE_LOCATION",
741            "GPS",
742            "VIBRATE",
743            "READ_CONTACTS",
744            "WRITE_CONTACTS",
745            "READ_CALL_LOG",
746            "WRITE_CALL_LOG",
747            "READ_CALENDAR",
748            "WRITE_CALENDAR",
749            "WIFI_SCAN",
750            "POST_NOTIFICATION",
751            "NEIGHBORING_CELLS",
752            "CALL_PHONE",
753            "READ_SMS",
754            "WRITE_SMS",
755            "RECEIVE_SMS",
756            "RECEIVE_EMERGECY_SMS",
757            "RECEIVE_MMS",
758            "RECEIVE_WAP_PUSH",
759            "SEND_SMS",
760            "READ_ICC_SMS",
761            "WRITE_ICC_SMS",
762            "WRITE_SETTINGS",
763            "SYSTEM_ALERT_WINDOW",
764            "ACCESS_NOTIFICATIONS",
765            "CAMERA",
766            "RECORD_AUDIO",
767            "PLAY_AUDIO",
768            "READ_CLIPBOARD",
769            "WRITE_CLIPBOARD",
770            "TAKE_MEDIA_BUTTONS",
771            "TAKE_AUDIO_FOCUS",
772            "AUDIO_MASTER_VOLUME",
773            "AUDIO_VOICE_VOLUME",
774            "AUDIO_RING_VOLUME",
775            "AUDIO_MEDIA_VOLUME",
776            "AUDIO_ALARM_VOLUME",
777            "AUDIO_NOTIFICATION_VOLUME",
778            "AUDIO_BLUETOOTH_VOLUME",
779            "WAKE_LOCK",
780            "MONITOR_LOCATION",
781            "MONITOR_HIGH_POWER_LOCATION",
782            "GET_USAGE_STATS",
783            "MUTE_MICROPHONE",
784            "TOAST_WINDOW",
785            "PROJECT_MEDIA",
786            "ACTIVATE_VPN",
787            "WRITE_WALLPAPER",
788            "ASSIST_STRUCTURE",
789            "ASSIST_SCREENSHOT",
790            "OP_READ_PHONE_STATE",
791            "ADD_VOICEMAIL",
792            "USE_SIP",
793            "PROCESS_OUTGOING_CALLS",
794            "USE_FINGERPRINT",
795            "BODY_SENSORS",
796            "READ_CELL_BROADCASTS",
797            "MOCK_LOCATION",
798            "READ_EXTERNAL_STORAGE",
799            "WRITE_EXTERNAL_STORAGE",
800            "TURN_ON_SCREEN",
801            "GET_ACCOUNTS",
802            "RUN_IN_BACKGROUND",
803            "AUDIO_ACCESSIBILITY_VOLUME",
804            "READ_PHONE_NUMBERS",
805            "REQUEST_INSTALL_PACKAGES",
806            "PICTURE_IN_PICTURE",
807            "INSTANT_APP_START_FOREGROUND",
808            "ANSWER_PHONE_CALLS",
809            "RUN_ANY_IN_BACKGROUND",
810            "CHANGE_WIFI_STATE",
811            "REQUEST_DELETE_PACKAGES",
812            "BIND_ACCESSIBILITY_SERVICE",
813            "ACCEPT_HANDOVER",
814            "MANAGE_IPSEC_TUNNELS",
815    };
816
817    /**
818     * This optionally maps a permission to an operation.  If there
819     * is no permission associated with an operation, it is null.
820     */
821    private static String[] sOpPerms = new String[] {
822            android.Manifest.permission.ACCESS_COARSE_LOCATION,
823            android.Manifest.permission.ACCESS_FINE_LOCATION,
824            null,
825            android.Manifest.permission.VIBRATE,
826            android.Manifest.permission.READ_CONTACTS,
827            android.Manifest.permission.WRITE_CONTACTS,
828            android.Manifest.permission.READ_CALL_LOG,
829            android.Manifest.permission.WRITE_CALL_LOG,
830            android.Manifest.permission.READ_CALENDAR,
831            android.Manifest.permission.WRITE_CALENDAR,
832            android.Manifest.permission.ACCESS_WIFI_STATE,
833            null, // no permission required for notifications
834            null, // neighboring cells shares the coarse location perm
835            android.Manifest.permission.CALL_PHONE,
836            android.Manifest.permission.READ_SMS,
837            null, // no permission required for writing sms
838            android.Manifest.permission.RECEIVE_SMS,
839            android.Manifest.permission.RECEIVE_EMERGENCY_BROADCAST,
840            android.Manifest.permission.RECEIVE_MMS,
841            android.Manifest.permission.RECEIVE_WAP_PUSH,
842            android.Manifest.permission.SEND_SMS,
843            android.Manifest.permission.READ_SMS,
844            null, // no permission required for writing icc sms
845            android.Manifest.permission.WRITE_SETTINGS,
846            android.Manifest.permission.SYSTEM_ALERT_WINDOW,
847            android.Manifest.permission.ACCESS_NOTIFICATIONS,
848            android.Manifest.permission.CAMERA,
849            android.Manifest.permission.RECORD_AUDIO,
850            null, // no permission for playing audio
851            null, // no permission for reading clipboard
852            null, // no permission for writing clipboard
853            null, // no permission for taking media buttons
854            null, // no permission for taking audio focus
855            null, // no permission for changing master volume
856            null, // no permission for changing voice volume
857            null, // no permission for changing ring volume
858            null, // no permission for changing media volume
859            null, // no permission for changing alarm volume
860            null, // no permission for changing notification volume
861            null, // no permission for changing bluetooth volume
862            android.Manifest.permission.WAKE_LOCK,
863            null, // no permission for generic location monitoring
864            null, // no permission for high power location monitoring
865            android.Manifest.permission.PACKAGE_USAGE_STATS,
866            null, // no permission for muting/unmuting microphone
867            null, // no permission for displaying toasts
868            null, // no permission for projecting media
869            null, // no permission for activating vpn
870            null, // no permission for supporting wallpaper
871            null, // no permission for receiving assist structure
872            null, // no permission for receiving assist screenshot
873            Manifest.permission.READ_PHONE_STATE,
874            Manifest.permission.ADD_VOICEMAIL,
875            Manifest.permission.USE_SIP,
876            Manifest.permission.PROCESS_OUTGOING_CALLS,
877            Manifest.permission.USE_FINGERPRINT,
878            Manifest.permission.BODY_SENSORS,
879            Manifest.permission.READ_CELL_BROADCASTS,
880            null,
881            Manifest.permission.READ_EXTERNAL_STORAGE,
882            Manifest.permission.WRITE_EXTERNAL_STORAGE,
883            null, // no permission for turning the screen on
884            Manifest.permission.GET_ACCOUNTS,
885            null, // no permission for running in background
886            null, // no permission for changing accessibility volume
887            Manifest.permission.READ_PHONE_NUMBERS,
888            Manifest.permission.REQUEST_INSTALL_PACKAGES,
889            null, // no permission for entering picture-in-picture on hide
890            Manifest.permission.INSTANT_APP_FOREGROUND_SERVICE,
891            Manifest.permission.ANSWER_PHONE_CALLS,
892            null, // no permission for OP_RUN_ANY_IN_BACKGROUND
893            Manifest.permission.CHANGE_WIFI_STATE,
894            Manifest.permission.REQUEST_DELETE_PACKAGES,
895            Manifest.permission.BIND_ACCESSIBILITY_SERVICE,
896            Manifest.permission.ACCEPT_HANDOVER,
897            null, // no permission for OP_MANAGE_IPSEC_TUNNELS
898    };
899
900    /**
901     * Specifies whether an Op should be restricted by a user restriction.
902     * Each Op should be filled with a restriction string from UserManager or
903     * null to specify it is not affected by any user restriction.
904     */
905    private static String[] sOpRestrictions = new String[] {
906            UserManager.DISALLOW_SHARE_LOCATION, //COARSE_LOCATION
907            UserManager.DISALLOW_SHARE_LOCATION, //FINE_LOCATION
908            UserManager.DISALLOW_SHARE_LOCATION, //GPS
909            null, //VIBRATE
910            null, //READ_CONTACTS
911            null, //WRITE_CONTACTS
912            UserManager.DISALLOW_OUTGOING_CALLS, //READ_CALL_LOG
913            UserManager.DISALLOW_OUTGOING_CALLS, //WRITE_CALL_LOG
914            null, //READ_CALENDAR
915            null, //WRITE_CALENDAR
916            UserManager.DISALLOW_SHARE_LOCATION, //WIFI_SCAN
917            null, //POST_NOTIFICATION
918            null, //NEIGHBORING_CELLS
919            null, //CALL_PHONE
920            UserManager.DISALLOW_SMS, //READ_SMS
921            UserManager.DISALLOW_SMS, //WRITE_SMS
922            UserManager.DISALLOW_SMS, //RECEIVE_SMS
923            null, //RECEIVE_EMERGENCY_SMS
924            UserManager.DISALLOW_SMS, //RECEIVE_MMS
925            null, //RECEIVE_WAP_PUSH
926            UserManager.DISALLOW_SMS, //SEND_SMS
927            UserManager.DISALLOW_SMS, //READ_ICC_SMS
928            UserManager.DISALLOW_SMS, //WRITE_ICC_SMS
929            null, //WRITE_SETTINGS
930            UserManager.DISALLOW_CREATE_WINDOWS, //SYSTEM_ALERT_WINDOW
931            null, //ACCESS_NOTIFICATIONS
932            UserManager.DISALLOW_CAMERA, //CAMERA
933            UserManager.DISALLOW_RECORD_AUDIO, //RECORD_AUDIO
934            null, //PLAY_AUDIO
935            null, //READ_CLIPBOARD
936            null, //WRITE_CLIPBOARD
937            null, //TAKE_MEDIA_BUTTONS
938            null, //TAKE_AUDIO_FOCUS
939            UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MASTER_VOLUME
940            UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_VOICE_VOLUME
941            UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_RING_VOLUME
942            UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MEDIA_VOLUME
943            UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ALARM_VOLUME
944            UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_NOTIFICATION_VOLUME
945            UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_BLUETOOTH_VOLUME
946            null, //WAKE_LOCK
947            UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_LOCATION
948            UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_HIGH_POWER_LOCATION
949            null, //GET_USAGE_STATS
950            UserManager.DISALLOW_UNMUTE_MICROPHONE, // MUTE_MICROPHONE
951            UserManager.DISALLOW_CREATE_WINDOWS, // TOAST_WINDOW
952            null, //PROJECT_MEDIA
953            null, // ACTIVATE_VPN
954            UserManager.DISALLOW_WALLPAPER, // WRITE_WALLPAPER
955            null, // ASSIST_STRUCTURE
956            null, // ASSIST_SCREENSHOT
957            null, // READ_PHONE_STATE
958            null, // ADD_VOICEMAIL
959            null, // USE_SIP
960            null, // PROCESS_OUTGOING_CALLS
961            null, // USE_FINGERPRINT
962            null, // BODY_SENSORS
963            null, // READ_CELL_BROADCASTS
964            null, // MOCK_LOCATION
965            null, // READ_EXTERNAL_STORAGE
966            null, // WRITE_EXTERNAL_STORAGE
967            null, // TURN_ON_SCREEN
968            null, // GET_ACCOUNTS
969            null, // RUN_IN_BACKGROUND
970            UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ACCESSIBILITY_VOLUME
971            null, // READ_PHONE_NUMBERS
972            null, // REQUEST_INSTALL_PACKAGES
973            null, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
974            null, // INSTANT_APP_START_FOREGROUND
975            null, // ANSWER_PHONE_CALLS
976            null, // OP_RUN_ANY_IN_BACKGROUND
977            null, // OP_CHANGE_WIFI_STATE
978            null, // REQUEST_DELETE_PACKAGES
979            null, // OP_BIND_ACCESSIBILITY_SERVICE
980            null, // ACCEPT_HANDOVER
981            null, // MANAGE_IPSEC_TUNNELS
982    };
983
984    /**
985     * This specifies whether each option should allow the system
986     * (and system ui) to bypass the user restriction when active.
987     */
988    private static boolean[] sOpAllowSystemRestrictionBypass = new boolean[] {
989            true, //COARSE_LOCATION
990            true, //FINE_LOCATION
991            false, //GPS
992            false, //VIBRATE
993            false, //READ_CONTACTS
994            false, //WRITE_CONTACTS
995            false, //READ_CALL_LOG
996            false, //WRITE_CALL_LOG
997            false, //READ_CALENDAR
998            false, //WRITE_CALENDAR
999            true, //WIFI_SCAN
1000            false, //POST_NOTIFICATION
1001            false, //NEIGHBORING_CELLS
1002            false, //CALL_PHONE
1003            false, //READ_SMS
1004            false, //WRITE_SMS
1005            false, //RECEIVE_SMS
1006            false, //RECEIVE_EMERGECY_SMS
1007            false, //RECEIVE_MMS
1008            false, //RECEIVE_WAP_PUSH
1009            false, //SEND_SMS
1010            false, //READ_ICC_SMS
1011            false, //WRITE_ICC_SMS
1012            false, //WRITE_SETTINGS
1013            true, //SYSTEM_ALERT_WINDOW
1014            false, //ACCESS_NOTIFICATIONS
1015            false, //CAMERA
1016            false, //RECORD_AUDIO
1017            false, //PLAY_AUDIO
1018            false, //READ_CLIPBOARD
1019            false, //WRITE_CLIPBOARD
1020            false, //TAKE_MEDIA_BUTTONS
1021            false, //TAKE_AUDIO_FOCUS
1022            false, //AUDIO_MASTER_VOLUME
1023            false, //AUDIO_VOICE_VOLUME
1024            false, //AUDIO_RING_VOLUME
1025            false, //AUDIO_MEDIA_VOLUME
1026            false, //AUDIO_ALARM_VOLUME
1027            false, //AUDIO_NOTIFICATION_VOLUME
1028            false, //AUDIO_BLUETOOTH_VOLUME
1029            false, //WAKE_LOCK
1030            false, //MONITOR_LOCATION
1031            false, //MONITOR_HIGH_POWER_LOCATION
1032            false, //GET_USAGE_STATS
1033            false, //MUTE_MICROPHONE
1034            true, //TOAST_WINDOW
1035            false, //PROJECT_MEDIA
1036            false, //ACTIVATE_VPN
1037            false, //WALLPAPER
1038            false, //ASSIST_STRUCTURE
1039            false, //ASSIST_SCREENSHOT
1040            false, //READ_PHONE_STATE
1041            false, //ADD_VOICEMAIL
1042            false, // USE_SIP
1043            false, // PROCESS_OUTGOING_CALLS
1044            false, // USE_FINGERPRINT
1045            false, // BODY_SENSORS
1046            false, // READ_CELL_BROADCASTS
1047            false, // MOCK_LOCATION
1048            false, // READ_EXTERNAL_STORAGE
1049            false, // WRITE_EXTERNAL_STORAGE
1050            false, // TURN_ON_SCREEN
1051            false, // GET_ACCOUNTS
1052            false, // RUN_IN_BACKGROUND
1053            false, // AUDIO_ACCESSIBILITY_VOLUME
1054            false, // READ_PHONE_NUMBERS
1055            false, // REQUEST_INSTALL_PACKAGES
1056            false, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
1057            false, // INSTANT_APP_START_FOREGROUND
1058            false, // ANSWER_PHONE_CALLS
1059            false, // OP_RUN_ANY_IN_BACKGROUND
1060            false, // OP_CHANGE_WIFI_STATE
1061            false, // OP_REQUEST_DELETE_PACKAGES
1062            false, // OP_BIND_ACCESSIBILITY_SERVICE
1063            false, // ACCEPT_HANDOVER
1064            false, // MANAGE_IPSEC_HANDOVERS
1065    };
1066
1067    /**
1068     * This specifies the default mode for each operation.
1069     */
1070    private static int[] sOpDefaultMode = new int[] {
1071            AppOpsManager.MODE_ALLOWED,
1072            AppOpsManager.MODE_ALLOWED,
1073            AppOpsManager.MODE_ALLOWED,
1074            AppOpsManager.MODE_ALLOWED,
1075            AppOpsManager.MODE_ALLOWED,
1076            AppOpsManager.MODE_ALLOWED,
1077            AppOpsManager.MODE_ALLOWED,
1078            AppOpsManager.MODE_ALLOWED,
1079            AppOpsManager.MODE_ALLOWED,
1080            AppOpsManager.MODE_ALLOWED,
1081            AppOpsManager.MODE_ALLOWED,
1082            AppOpsManager.MODE_ALLOWED,
1083            AppOpsManager.MODE_ALLOWED,
1084            AppOpsManager.MODE_ALLOWED,
1085            AppOpsManager.MODE_ALLOWED,
1086            AppOpsManager.MODE_IGNORED, // OP_WRITE_SMS
1087            AppOpsManager.MODE_ALLOWED,
1088            AppOpsManager.MODE_ALLOWED,
1089            AppOpsManager.MODE_ALLOWED,
1090            AppOpsManager.MODE_ALLOWED,
1091            AppOpsManager.MODE_ALLOWED,
1092            AppOpsManager.MODE_ALLOWED,
1093            AppOpsManager.MODE_ALLOWED,
1094            AppOpsManager.MODE_DEFAULT, // OP_WRITE_SETTINGS
1095            AppOpsManager.MODE_DEFAULT, // OP_SYSTEM_ALERT_WINDOW
1096            AppOpsManager.MODE_ALLOWED,
1097            AppOpsManager.MODE_ALLOWED,
1098            AppOpsManager.MODE_ALLOWED,
1099            AppOpsManager.MODE_ALLOWED,
1100            AppOpsManager.MODE_ALLOWED,
1101            AppOpsManager.MODE_ALLOWED,
1102            AppOpsManager.MODE_ALLOWED,
1103            AppOpsManager.MODE_ALLOWED,
1104            AppOpsManager.MODE_ALLOWED,
1105            AppOpsManager.MODE_ALLOWED,
1106            AppOpsManager.MODE_ALLOWED,
1107            AppOpsManager.MODE_ALLOWED,
1108            AppOpsManager.MODE_ALLOWED,
1109            AppOpsManager.MODE_ALLOWED,
1110            AppOpsManager.MODE_ALLOWED,
1111            AppOpsManager.MODE_ALLOWED,
1112            AppOpsManager.MODE_ALLOWED,
1113            AppOpsManager.MODE_ALLOWED,
1114            AppOpsManager.MODE_DEFAULT, // OP_GET_USAGE_STATS
1115            AppOpsManager.MODE_ALLOWED,
1116            AppOpsManager.MODE_ALLOWED,
1117            AppOpsManager.MODE_IGNORED, // OP_PROJECT_MEDIA
1118            AppOpsManager.MODE_IGNORED, // OP_ACTIVATE_VPN
1119            AppOpsManager.MODE_ALLOWED,
1120            AppOpsManager.MODE_ALLOWED,
1121            AppOpsManager.MODE_ALLOWED,
1122            AppOpsManager.MODE_ALLOWED,
1123            AppOpsManager.MODE_ALLOWED,
1124            AppOpsManager.MODE_ALLOWED,
1125            AppOpsManager.MODE_ALLOWED,
1126            AppOpsManager.MODE_ALLOWED,
1127            AppOpsManager.MODE_ALLOWED,
1128            AppOpsManager.MODE_ALLOWED,
1129            AppOpsManager.MODE_ERRORED,  // OP_MOCK_LOCATION
1130            AppOpsManager.MODE_ALLOWED,
1131            AppOpsManager.MODE_ALLOWED,
1132            AppOpsManager.MODE_ALLOWED,  // OP_TURN_ON_SCREEN
1133            AppOpsManager.MODE_ALLOWED,
1134            AppOpsManager.MODE_ALLOWED,  // OP_RUN_IN_BACKGROUND
1135            AppOpsManager.MODE_ALLOWED,  // OP_AUDIO_ACCESSIBILITY_VOLUME
1136            AppOpsManager.MODE_ALLOWED,
1137            AppOpsManager.MODE_DEFAULT,  // OP_REQUEST_INSTALL_PACKAGES
1138            AppOpsManager.MODE_ALLOWED,  // OP_PICTURE_IN_PICTURE
1139            AppOpsManager.MODE_DEFAULT,  // OP_INSTANT_APP_START_FOREGROUND
1140            AppOpsManager.MODE_ALLOWED, // ANSWER_PHONE_CALLS
1141            AppOpsManager.MODE_ALLOWED,  // OP_RUN_ANY_IN_BACKGROUND
1142            AppOpsManager.MODE_ALLOWED,  // OP_CHANGE_WIFI_STATE
1143            AppOpsManager.MODE_ALLOWED,  // REQUEST_DELETE_PACKAGES
1144            AppOpsManager.MODE_ALLOWED,  // OP_BIND_ACCESSIBILITY_SERVICE
1145            AppOpsManager.MODE_ALLOWED,  // ACCEPT_HANDOVER
1146            AppOpsManager.MODE_ERRORED,  // MANAGE_IPSEC_TUNNELS
1147    };
1148
1149    /**
1150     * This specifies whether each option is allowed to be reset
1151     * when resetting all app preferences.  Disable reset for
1152     * app ops that are under strong control of some part of the
1153     * system (such as OP_WRITE_SMS, which should be allowed only
1154     * for whichever app is selected as the current SMS app).
1155     */
1156    private static boolean[] sOpDisableReset = new boolean[] {
1157            false,
1158            false,
1159            false,
1160            false,
1161            false,
1162            false,
1163            false,
1164            false,
1165            false,
1166            false,
1167            false,
1168            false,
1169            false,
1170            false,
1171            false,
1172            true,      // OP_WRITE_SMS
1173            false,
1174            false,
1175            false,
1176            false,
1177            false,
1178            false,
1179            false,
1180            false,
1181            false,
1182            false,
1183            false,
1184            false,
1185            false,
1186            false,
1187            false,
1188            false,
1189            false,
1190            false,
1191            false,
1192            false,
1193            false,
1194            false,
1195            false,
1196            false,
1197            false,
1198            false,
1199            false,
1200            false,
1201            false,
1202            false,
1203            false,
1204            false,
1205            false,
1206            false,
1207            false,
1208            false,
1209            false,
1210            false,
1211            false,
1212            false,
1213            false,
1214            false,
1215            false,
1216            false,
1217            false,
1218            false,
1219            false,
1220            false,
1221            false, // OP_AUDIO_ACCESSIBILITY_VOLUME
1222            false,
1223            false, // OP_REQUEST_INSTALL_PACKAGES
1224            false, // OP_PICTURE_IN_PICTURE
1225            false,
1226            false, // ANSWER_PHONE_CALLS
1227            false, // OP_RUN_ANY_IN_BACKGROUND
1228            false, // OP_CHANGE_WIFI_STATE
1229            false, // OP_REQUEST_DELETE_PACKAGES
1230            false, // OP_BIND_ACCESSIBILITY_SERVICE
1231            false, // ACCEPT_HANDOVER
1232            false, // MANAGE_IPSEC_TUNNELS
1233    };
1234
1235    /**
1236     * Mapping from an app op name to the app op code.
1237     */
1238    private static HashMap<String, Integer> sOpStrToOp = new HashMap<>();
1239
1240    /**
1241     * Mapping from a permission to the corresponding app op.
1242     */
1243    private static HashMap<String, Integer> sPermToOp = new HashMap<>();
1244
1245    static {
1246        if (sOpToSwitch.length != _NUM_OP) {
1247            throw new IllegalStateException("sOpToSwitch length " + sOpToSwitch.length
1248                    + " should be " + _NUM_OP);
1249        }
1250        if (sOpToString.length != _NUM_OP) {
1251            throw new IllegalStateException("sOpToString length " + sOpToString.length
1252                    + " should be " + _NUM_OP);
1253        }
1254        if (sOpNames.length != _NUM_OP) {
1255            throw new IllegalStateException("sOpNames length " + sOpNames.length
1256                    + " should be " + _NUM_OP);
1257        }
1258        if (sOpPerms.length != _NUM_OP) {
1259            throw new IllegalStateException("sOpPerms length " + sOpPerms.length
1260                    + " should be " + _NUM_OP);
1261        }
1262        if (sOpDefaultMode.length != _NUM_OP) {
1263            throw new IllegalStateException("sOpDefaultMode length " + sOpDefaultMode.length
1264                    + " should be " + _NUM_OP);
1265        }
1266        if (sOpDisableReset.length != _NUM_OP) {
1267            throw new IllegalStateException("sOpDisableReset length " + sOpDisableReset.length
1268                    + " should be " + _NUM_OP);
1269        }
1270        if (sOpRestrictions.length != _NUM_OP) {
1271            throw new IllegalStateException("sOpRestrictions length " + sOpRestrictions.length
1272                    + " should be " + _NUM_OP);
1273        }
1274        if (sOpAllowSystemRestrictionBypass.length != _NUM_OP) {
1275            throw new IllegalStateException("sOpAllowSYstemRestrictionsBypass length "
1276                    + sOpRestrictions.length + " should be " + _NUM_OP);
1277        }
1278        for (int i=0; i<_NUM_OP; i++) {
1279            if (sOpToString[i] != null) {
1280                sOpStrToOp.put(sOpToString[i], i);
1281            }
1282        }
1283        for (int op : RUNTIME_AND_APPOP_PERMISSIONS_OPS) {
1284            if (sOpPerms[op] != null) {
1285                sPermToOp.put(sOpPerms[op], op);
1286            }
1287        }
1288    }
1289
1290    /**
1291     * Retrieve the op switch that controls the given operation.
1292     * @hide
1293     */
1294    public static int opToSwitch(int op) {
1295        return sOpToSwitch[op];
1296    }
1297
1298    /**
1299     * Retrieve a non-localized name for the operation, for debugging output.
1300     * @hide
1301     */
1302    public static String opToName(int op) {
1303        if (op == OP_NONE) return "NONE";
1304        return op < sOpNames.length ? sOpNames[op] : ("Unknown(" + op + ")");
1305    }
1306
1307    /**
1308     * @hide
1309     */
1310    public static int strDebugOpToOp(String op) {
1311        for (int i=0; i<sOpNames.length; i++) {
1312            if (sOpNames[i].equals(op)) {
1313                return i;
1314            }
1315        }
1316        throw new IllegalArgumentException("Unknown operation string: " + op);
1317    }
1318
1319    /**
1320     * Retrieve the permission associated with an operation, or null if there is not one.
1321     * @hide
1322     */
1323    public static String opToPermission(int op) {
1324        return sOpPerms[op];
1325    }
1326
1327    /**
1328     * Retrieve the user restriction associated with an operation, or null if there is not one.
1329     * @hide
1330     */
1331    public static String opToRestriction(int op) {
1332        return sOpRestrictions[op];
1333    }
1334
1335    /**
1336     * Retrieve the app op code for a permission, or null if there is not one.
1337     * This API is intended to be used for mapping runtime or appop permissions
1338     * to the corresponding app op.
1339     * @hide
1340     */
1341    public static int permissionToOpCode(String permission) {
1342        Integer boxedOpCode = sPermToOp.get(permission);
1343        return boxedOpCode != null ? boxedOpCode : OP_NONE;
1344    }
1345
1346    /**
1347     * Retrieve whether the op allows the system (and system ui) to
1348     * bypass the user restriction.
1349     * @hide
1350     */
1351    public static boolean opAllowSystemBypassRestriction(int op) {
1352        return sOpAllowSystemRestrictionBypass[op];
1353    }
1354
1355    /**
1356     * Retrieve the default mode for the operation.
1357     * @hide
1358     */
1359    public static int opToDefaultMode(int op) {
1360        return sOpDefaultMode[op];
1361    }
1362
1363    /**
1364     * Retrieve the human readable mode.
1365     * @hide
1366     */
1367    public static String modeToString(int mode) {
1368        switch (mode) {
1369            case MODE_ALLOWED:
1370                return "allow";
1371            case MODE_IGNORED:
1372                return "ignore";
1373            case MODE_ERRORED:
1374                return "deny";
1375            case MODE_DEFAULT:
1376                return "default";
1377            default:
1378                return "mode=" + mode;
1379        }
1380    }
1381
1382    /**
1383     * Retrieve whether the op allows itself to be reset.
1384     * @hide
1385     */
1386    public static boolean opAllowsReset(int op) {
1387        return !sOpDisableReset[op];
1388    }
1389
1390    /**
1391     * Class holding all of the operation information associated with an app.
1392     * @hide
1393     */
1394    public static class PackageOps implements Parcelable {
1395        private final String mPackageName;
1396        private final int mUid;
1397        private final List<OpEntry> mEntries;
1398
1399        public PackageOps(String packageName, int uid, List<OpEntry> entries) {
1400            mPackageName = packageName;
1401            mUid = uid;
1402            mEntries = entries;
1403        }
1404
1405        public String getPackageName() {
1406            return mPackageName;
1407        }
1408
1409        public int getUid() {
1410            return mUid;
1411        }
1412
1413        public List<OpEntry> getOps() {
1414            return mEntries;
1415        }
1416
1417        @Override
1418        public int describeContents() {
1419            return 0;
1420        }
1421
1422        @Override
1423        public void writeToParcel(Parcel dest, int flags) {
1424            dest.writeString(mPackageName);
1425            dest.writeInt(mUid);
1426            dest.writeInt(mEntries.size());
1427            for (int i=0; i<mEntries.size(); i++) {
1428                mEntries.get(i).writeToParcel(dest, flags);
1429            }
1430        }
1431
1432        PackageOps(Parcel source) {
1433            mPackageName = source.readString();
1434            mUid = source.readInt();
1435            mEntries = new ArrayList<OpEntry>();
1436            final int N = source.readInt();
1437            for (int i=0; i<N; i++) {
1438                mEntries.add(OpEntry.CREATOR.createFromParcel(source));
1439            }
1440        }
1441
1442        public static final Creator<PackageOps> CREATOR = new Creator<PackageOps>() {
1443            @Override public PackageOps createFromParcel(Parcel source) {
1444                return new PackageOps(source);
1445            }
1446
1447            @Override public PackageOps[] newArray(int size) {
1448                return new PackageOps[size];
1449            }
1450        };
1451    }
1452
1453    /**
1454     * Class holding the information about one unique operation of an application.
1455     * @hide
1456     */
1457    public static class OpEntry implements Parcelable {
1458        private final int mOp;
1459        private final int mMode;
1460        private final long mTime;
1461        private final long mRejectTime;
1462        private final int mDuration;
1463        private final int mProxyUid;
1464        private final String mProxyPackageName;
1465
1466        public OpEntry(int op, int mode, long time, long rejectTime, int duration,
1467                int proxyUid, String proxyPackage) {
1468            mOp = op;
1469            mMode = mode;
1470            mTime = time;
1471            mRejectTime = rejectTime;
1472            mDuration = duration;
1473            mProxyUid = proxyUid;
1474            mProxyPackageName = proxyPackage;
1475        }
1476
1477        public int getOp() {
1478            return mOp;
1479        }
1480
1481        public int getMode() {
1482            return mMode;
1483        }
1484
1485        public long getTime() {
1486            return mTime;
1487        }
1488
1489        public long getRejectTime() {
1490            return mRejectTime;
1491        }
1492
1493        public boolean isRunning() {
1494            return mDuration == -1;
1495        }
1496
1497        public int getDuration() {
1498            return mDuration == -1 ? (int)(System.currentTimeMillis()-mTime) : mDuration;
1499        }
1500
1501        public int getProxyUid() {
1502            return  mProxyUid;
1503        }
1504
1505        public String getProxyPackageName() {
1506            return mProxyPackageName;
1507        }
1508
1509        @Override
1510        public int describeContents() {
1511            return 0;
1512        }
1513
1514        @Override
1515        public void writeToParcel(Parcel dest, int flags) {
1516            dest.writeInt(mOp);
1517            dest.writeInt(mMode);
1518            dest.writeLong(mTime);
1519            dest.writeLong(mRejectTime);
1520            dest.writeInt(mDuration);
1521            dest.writeInt(mProxyUid);
1522            dest.writeString(mProxyPackageName);
1523        }
1524
1525        OpEntry(Parcel source) {
1526            mOp = source.readInt();
1527            mMode = source.readInt();
1528            mTime = source.readLong();
1529            mRejectTime = source.readLong();
1530            mDuration = source.readInt();
1531            mProxyUid = source.readInt();
1532            mProxyPackageName = source.readString();
1533        }
1534
1535        public static final Creator<OpEntry> CREATOR = new Creator<OpEntry>() {
1536            @Override public OpEntry createFromParcel(Parcel source) {
1537                return new OpEntry(source);
1538            }
1539
1540            @Override public OpEntry[] newArray(int size) {
1541                return new OpEntry[size];
1542            }
1543        };
1544    }
1545
1546    /**
1547     * Callback for notification of changes to operation state.
1548     */
1549    public interface OnOpChangedListener {
1550        public void onOpChanged(String op, String packageName);
1551    }
1552
1553    /**
1554     * Callback for notification of changes to operation active state.
1555     *
1556     * @hide
1557     */
1558    @TestApi
1559    public interface OnOpActiveChangedListener {
1560        /**
1561         * Called when the active state of an app op changes.
1562         *
1563         * @param code The op code.
1564         * @param uid The UID performing the operation.
1565         * @param packageName The package performing the operation.
1566         * @param active Whether the operation became active or inactive.
1567         */
1568        void onOpActiveChanged(int code, int uid, String packageName, boolean active);
1569    }
1570
1571    /**
1572     * Callback for notification of changes to operation state.
1573     * This allows you to see the raw op codes instead of strings.
1574     * @hide
1575     */
1576    public static class OnOpChangedInternalListener implements OnOpChangedListener {
1577        public void onOpChanged(String op, String packageName) { }
1578        public void onOpChanged(int op, String packageName) { }
1579    }
1580
1581    AppOpsManager(Context context, IAppOpsService service) {
1582        mContext = context;
1583        mService = service;
1584    }
1585
1586    /**
1587     * Retrieve current operation state for all applications.
1588     *
1589     * @param ops The set of operations you are interested in, or null if you want all of them.
1590     * @hide
1591     */
1592    public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) {
1593        try {
1594            return mService.getPackagesForOps(ops);
1595        } catch (RemoteException e) {
1596            throw e.rethrowFromSystemServer();
1597        }
1598    }
1599
1600    /**
1601     * Retrieve current operation state for one application.
1602     *
1603     * @param uid The uid of the application of interest.
1604     * @param packageName The name of the application of interest.
1605     * @param ops The set of operations you are interested in, or null if you want all of them.
1606     * @hide
1607     */
1608    public List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, int[] ops) {
1609        try {
1610            return mService.getOpsForPackage(uid, packageName, ops);
1611        } catch (RemoteException e) {
1612            throw e.rethrowFromSystemServer();
1613        }
1614    }
1615
1616    /**
1617     * Sets given app op in the specified mode for app ops in the UID.
1618     * This applies to all apps currently in the UID or installed in
1619     * this UID in the future.
1620     *
1621     * @param code The app op.
1622     * @param uid The UID for which to set the app.
1623     * @param mode The app op mode to set.
1624     * @hide
1625     */
1626    @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
1627    public void setUidMode(int code, int uid, int mode) {
1628        try {
1629            mService.setUidMode(code, uid, mode);
1630        } catch (RemoteException e) {
1631            throw e.rethrowFromSystemServer();
1632        }
1633    }
1634
1635    /**
1636     * Sets given app op in the specified mode for app ops in the UID.
1637     * This applies to all apps currently in the UID or installed in
1638     * this UID in the future.
1639     *
1640     * @param appOp The app op.
1641     * @param uid The UID for which to set the app.
1642     * @param mode The app op mode to set.
1643     * @hide
1644     */
1645    @SystemApi
1646    @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
1647    public void setUidMode(String appOp, int uid, int mode) {
1648        try {
1649            mService.setUidMode(AppOpsManager.strOpToOp(appOp), uid, mode);
1650        } catch (RemoteException e) {
1651            throw e.rethrowFromSystemServer();
1652        }
1653    }
1654
1655    /** @hide */
1656    public void setUserRestriction(int code, boolean restricted, IBinder token) {
1657        setUserRestriction(code, restricted, token, /*exceptionPackages*/null);
1658    }
1659
1660    /** @hide */
1661    public void setUserRestriction(int code, boolean restricted, IBinder token,
1662            String[] exceptionPackages) {
1663        setUserRestrictionForUser(code, restricted, token, exceptionPackages, mContext.getUserId());
1664    }
1665
1666    /** @hide */
1667    public void setUserRestrictionForUser(int code, boolean restricted, IBinder token,
1668            String[] exceptionPackages, int userId) {
1669        try {
1670            mService.setUserRestriction(code, restricted, token, userId, exceptionPackages);
1671        } catch (RemoteException e) {
1672            throw e.rethrowFromSystemServer();
1673        }
1674    }
1675
1676    /** @hide */
1677    @TestApi
1678    @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
1679    public void setMode(int code, int uid, String packageName, int mode) {
1680        try {
1681            mService.setMode(code, uid, packageName, mode);
1682        } catch (RemoteException e) {
1683            throw e.rethrowFromSystemServer();
1684        }
1685    }
1686
1687    /**
1688     * Change the operating mode for the given op in the given app package.  You must pass
1689     * in both the uid and name of the application whose mode is being modified; if these
1690     * do not match, the modification will not be applied.
1691     *
1692     * @param op The operation to modify.  One of the OPSTR_* constants.
1693     * @param uid The user id of the application whose mode will be changed.
1694     * @param packageName The name of the application package name whose mode will
1695     * be changed.
1696     * @hide
1697     */
1698    @SystemApi
1699    @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
1700    public void setMode(String op, int uid, String packageName, int mode) {
1701        try {
1702            mService.setMode(strOpToOp(op), uid, packageName, mode);
1703        } catch (RemoteException e) {
1704            throw e.rethrowFromSystemServer();
1705        }
1706    }
1707
1708    /**
1709     * Set a non-persisted restriction on an audio operation at a stream-level.
1710     * Restrictions are temporary additional constraints imposed on top of the persisted rules
1711     * defined by {@link #setMode}.
1712     *
1713     * @param code The operation to restrict.
1714     * @param usage The {@link android.media.AudioAttributes} usage value.
1715     * @param mode The restriction mode (MODE_IGNORED,MODE_ERRORED) or MODE_ALLOWED to unrestrict.
1716     * @param exceptionPackages Optional list of packages to exclude from the restriction.
1717     * @hide
1718     */
1719    @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
1720    public void setRestriction(int code, @AttributeUsage int usage, int mode,
1721            String[] exceptionPackages) {
1722        try {
1723            final int uid = Binder.getCallingUid();
1724            mService.setAudioRestriction(code, usage, uid, mode, exceptionPackages);
1725        } catch (RemoteException e) {
1726            throw e.rethrowFromSystemServer();
1727        }
1728    }
1729
1730    /** @hide */
1731    @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
1732    public void resetAllModes() {
1733        try {
1734            mService.resetAllModes(mContext.getUserId(), null);
1735        } catch (RemoteException e) {
1736            throw e.rethrowFromSystemServer();
1737        }
1738    }
1739
1740    /**
1741     * Gets the app op name associated with a given permission.
1742     * The app op name is one of the public constants defined
1743     * in this class such as {@link #OPSTR_COARSE_LOCATION}.
1744     * This API is intended to be used for mapping runtime
1745     * permissions to the corresponding app op.
1746     *
1747     * @param permission The permission.
1748     * @return The app op associated with the permission or null.
1749     */
1750    public static String permissionToOp(String permission) {
1751        final Integer opCode = sPermToOp.get(permission);
1752        if (opCode == null) {
1753            return null;
1754        }
1755        return sOpToString[opCode];
1756    }
1757
1758    /**
1759     * Monitor for changes to the operating mode for the given op in the given app package.
1760     * You can watch op changes only for your UID.
1761     *
1762     * @param op The operation to monitor, one of OPSTR_*.
1763     * @param packageName The name of the application to monitor.
1764     * @param callback Where to report changes.
1765     */
1766    public void startWatchingMode(String op, String packageName,
1767            final OnOpChangedListener callback) {
1768        startWatchingMode(strOpToOp(op), packageName, callback);
1769    }
1770
1771    /**
1772     * Monitor for changes to the operating mode for the given op in the given app package.
1773     *
1774     * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
1775     * you can watch changes only for your UID.
1776     *
1777     * @param op The operation to monitor, one of OP_*.
1778     * @param packageName The name of the application to monitor.
1779     * @param callback Where to report changes.
1780     * @hide
1781     */
1782    @RequiresPermission(value=android.Manifest.permission.WATCH_APPOPS, conditional=true)
1783    public void startWatchingMode(int op, String packageName, final OnOpChangedListener callback) {
1784        synchronized (mModeWatchers) {
1785            IAppOpsCallback cb = mModeWatchers.get(callback);
1786            if (cb == null) {
1787                cb = new IAppOpsCallback.Stub() {
1788                    public void opChanged(int op, int uid, String packageName) {
1789                        if (callback instanceof OnOpChangedInternalListener) {
1790                            ((OnOpChangedInternalListener)callback).onOpChanged(op, packageName);
1791                        }
1792                        if (sOpToString[op] != null) {
1793                            callback.onOpChanged(sOpToString[op], packageName);
1794                        }
1795                    }
1796                };
1797                mModeWatchers.put(callback, cb);
1798            }
1799            try {
1800                mService.startWatchingMode(op, packageName, cb);
1801            } catch (RemoteException e) {
1802                throw e.rethrowFromSystemServer();
1803            }
1804        }
1805    }
1806
1807    /**
1808     * Stop monitoring that was previously started with {@link #startWatchingMode}.  All
1809     * monitoring associated with this callback will be removed.
1810     */
1811    public void stopWatchingMode(OnOpChangedListener callback) {
1812        synchronized (mModeWatchers) {
1813            IAppOpsCallback cb = mModeWatchers.get(callback);
1814            if (cb != null) {
1815                try {
1816                    mService.stopWatchingMode(cb);
1817                } catch (RemoteException e) {
1818                    throw e.rethrowFromSystemServer();
1819                }
1820            }
1821        }
1822    }
1823
1824    /**
1825     * Start watching for changes to the active state of app ops. An app op may be
1826     * long running and it has a clear start and stop delimiters. If an op is being
1827     * started or stopped by any package you will get a callback. To change the
1828     * watched ops for a registered callback you need to unregister and register it
1829     * again.
1830     *
1831     * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
1832     * you can watch changes only for your UID.
1833     *
1834     * @param ops The ops to watch.
1835     * @param callback Where to report changes.
1836     *
1837     * @see #isOperationActive(int, int, String)
1838     * @see #stopWatchingActive(OnOpActiveChangedListener)
1839     * @see #startOp(int, int, String)
1840     * @see #finishOp(int, int, String)
1841     *
1842     * @hide
1843     */
1844    @TestApi
1845    // TODO: Uncomment below annotation once b/73559440 is fixed
1846    // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
1847    public void startWatchingActive(@NonNull int[] ops,
1848            @NonNull OnOpActiveChangedListener callback) {
1849        Preconditions.checkNotNull(ops, "ops cannot be null");
1850        Preconditions.checkNotNull(callback, "callback cannot be null");
1851        IAppOpsActiveCallback cb;
1852        synchronized (mActiveWatchers) {
1853            cb = mActiveWatchers.get(callback);
1854            if (cb != null) {
1855                return;
1856            }
1857            cb = new IAppOpsActiveCallback.Stub() {
1858                @Override
1859                public void opActiveChanged(int op, int uid, String packageName, boolean active) {
1860                    callback.onOpActiveChanged(op, uid, packageName, active);
1861                }
1862            };
1863            mActiveWatchers.put(callback, cb);
1864        }
1865        try {
1866            mService.startWatchingActive(ops, cb);
1867        } catch (RemoteException e) {
1868            throw e.rethrowFromSystemServer();
1869        }
1870    }
1871
1872    /**
1873     * Stop watching for changes to the active state of an app op. An app op may be
1874     * long running and it has a clear start and stop delimiters. Unregistering a
1875     * non-registered callback has no effect.
1876     *
1877     * @see #isOperationActive#(int, int, String)
1878     * @see #startWatchingActive(int[], OnOpActiveChangedListener)
1879     * @see #startOp(int, int, String)
1880     * @see #finishOp(int, int, String)
1881     *
1882     * @hide
1883     */
1884    @TestApi
1885    public void stopWatchingActive(@NonNull OnOpActiveChangedListener callback) {
1886        synchronized (mActiveWatchers) {
1887            final IAppOpsActiveCallback cb = mActiveWatchers.get(callback);
1888            if (cb != null) {
1889                try {
1890                    mService.stopWatchingActive(cb);
1891                } catch (RemoteException e) {
1892                    throw e.rethrowFromSystemServer();
1893                }
1894            }
1895        }
1896    }
1897
1898    private String buildSecurityExceptionMsg(int op, int uid, String packageName) {
1899        return packageName + " from uid " + uid + " not allowed to perform " + sOpNames[op];
1900    }
1901
1902    /**
1903     * {@hide}
1904     */
1905    public static int strOpToOp(String op) {
1906        Integer val = sOpStrToOp.get(op);
1907        if (val == null) {
1908            throw new IllegalArgumentException("Unknown operation string: " + op);
1909        }
1910        return val;
1911    }
1912
1913    /**
1914     * Do a quick check for whether an application might be able to perform an operation.
1915     * This is <em>not</em> a security check; you must use {@link #noteOp(String, int, String)}
1916     * or {@link #startOp(String, int, String)} for your actual security checks, which also
1917     * ensure that the given uid and package name are consistent.  This function can just be
1918     * used for a quick check to see if an operation has been disabled for the application,
1919     * as an early reject of some work.  This does not modify the time stamp or other data
1920     * about the operation.
1921     * @param op The operation to check.  One of the OPSTR_* constants.
1922     * @param uid The user id of the application attempting to perform the operation.
1923     * @param packageName The name of the application attempting to perform the operation.
1924     * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1925     * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1926     * causing the app to crash).
1927     * @throws SecurityException If the app has been configured to crash on this op.
1928     */
1929    public int checkOp(String op, int uid, String packageName) {
1930        return checkOp(strOpToOp(op), uid, packageName);
1931    }
1932
1933    /**
1934     * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
1935     * returns {@link #MODE_ERRORED}.
1936     */
1937    public int checkOpNoThrow(String op, int uid, String packageName) {
1938        return checkOpNoThrow(strOpToOp(op), uid, packageName);
1939    }
1940
1941    /**
1942     * Make note of an application performing an operation.  Note that you must pass
1943     * in both the uid and name of the application to be checked; this function will verify
1944     * that these two match, and if not, return {@link #MODE_IGNORED}.  If this call
1945     * succeeds, the last execution time of the operation for this app will be updated to
1946     * the current time.
1947     * @param op The operation to note.  One of the OPSTR_* constants.
1948     * @param uid The user id of the application attempting to perform the operation.
1949     * @param packageName The name of the application attempting to perform the operation.
1950     * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1951     * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1952     * causing the app to crash).
1953     * @throws SecurityException If the app has been configured to crash on this op.
1954     */
1955    public int noteOp(String op, int uid, String packageName) {
1956        return noteOp(strOpToOp(op), uid, packageName);
1957    }
1958
1959    /**
1960     * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
1961     * returns {@link #MODE_ERRORED}.
1962     */
1963    public int noteOpNoThrow(String op, int uid, String packageName) {
1964        return noteOpNoThrow(strOpToOp(op), uid, packageName);
1965    }
1966
1967    /**
1968     * Make note of an application performing an operation on behalf of another
1969     * application when handling an IPC. Note that you must pass the package name
1970     * of the application that is being proxied while its UID will be inferred from
1971     * the IPC state; this function will verify that the calling uid and proxied
1972     * package name match, and if not, return {@link #MODE_IGNORED}. If this call
1973     * succeeds, the last execution time of the operation for the proxied app and
1974     * your app will be updated to the current time.
1975     * @param op The operation to note.  One of the OPSTR_* constants.
1976     * @param proxiedPackageName The name of the application calling into the proxy application.
1977     * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1978     * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1979     * causing the app to crash).
1980     * @throws SecurityException If the app has been configured to crash on this op.
1981     */
1982    public int noteProxyOp(String op, String proxiedPackageName) {
1983        return noteProxyOp(strOpToOp(op), proxiedPackageName);
1984    }
1985
1986    /**
1987     * Like {@link #noteProxyOp(String, String)} but instead
1988     * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
1989     */
1990    public int noteProxyOpNoThrow(String op, String proxiedPackageName) {
1991        return noteProxyOpNoThrow(strOpToOp(op), proxiedPackageName);
1992    }
1993
1994    /**
1995     * Report that an application has started executing a long-running operation.  Note that you
1996     * must pass in both the uid and name of the application to be checked; this function will
1997     * verify that these two match, and if not, return {@link #MODE_IGNORED}.  If this call
1998     * succeeds, the last execution time of the operation for this app will be updated to
1999     * the current time and the operation will be marked as "running".  In this case you must
2000     * later call {@link #finishOp(String, int, String)} to report when the application is no
2001     * longer performing the operation.
2002     * @param op The operation to start.  One of the OPSTR_* constants.
2003     * @param uid The user id of the application attempting to perform the operation.
2004     * @param packageName The name of the application attempting to perform the operation.
2005     * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
2006     * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
2007     * causing the app to crash).
2008     * @throws SecurityException If the app has been configured to crash on this op.
2009     */
2010    public int startOp(String op, int uid, String packageName) {
2011        return startOp(strOpToOp(op), uid, packageName);
2012    }
2013
2014    /**
2015     * Like {@link #startOp} but instead of throwing a {@link SecurityException} it
2016     * returns {@link #MODE_ERRORED}.
2017     */
2018    public int startOpNoThrow(String op, int uid, String packageName) {
2019        return startOpNoThrow(strOpToOp(op), uid, packageName);
2020    }
2021
2022    /**
2023     * Report that an application is no longer performing an operation that had previously
2024     * been started with {@link #startOp(String, int, String)}.  There is no validation of input
2025     * or result; the parameters supplied here must be the exact same ones previously passed
2026     * in when starting the operation.
2027     */
2028    public void finishOp(String op, int uid, String packageName) {
2029        finishOp(strOpToOp(op), uid, packageName);
2030    }
2031
2032    /**
2033     * Do a quick check for whether an application might be able to perform an operation.
2034     * This is <em>not</em> a security check; you must use {@link #noteOp(int, int, String)}
2035     * or {@link #startOp(int, int, String)} for your actual security checks, which also
2036     * ensure that the given uid and package name are consistent.  This function can just be
2037     * used for a quick check to see if an operation has been disabled for the application,
2038     * as an early reject of some work.  This does not modify the time stamp or other data
2039     * about the operation.
2040     * @param op The operation to check.  One of the OP_* constants.
2041     * @param uid The user id of the application attempting to perform the operation.
2042     * @param packageName The name of the application attempting to perform the operation.
2043     * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
2044     * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
2045     * causing the app to crash).
2046     * @throws SecurityException If the app has been configured to crash on this op.
2047     * @hide
2048     */
2049    public int checkOp(int op, int uid, String packageName) {
2050        try {
2051            int mode = mService.checkOperation(op, uid, packageName);
2052            if (mode == MODE_ERRORED) {
2053                throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
2054            }
2055            return mode;
2056        } catch (RemoteException e) {
2057            throw e.rethrowFromSystemServer();
2058        }
2059    }
2060
2061    /**
2062     * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
2063     * returns {@link #MODE_ERRORED}.
2064     * @hide
2065     */
2066    public int checkOpNoThrow(int op, int uid, String packageName) {
2067        try {
2068            return mService.checkOperation(op, uid, packageName);
2069        } catch (RemoteException e) {
2070            throw e.rethrowFromSystemServer();
2071        }
2072    }
2073
2074    /**
2075     * Do a quick check to validate if a package name belongs to a UID.
2076     *
2077     * @throws SecurityException if the package name doesn't belong to the given
2078     *             UID, or if ownership cannot be verified.
2079     */
2080    public void checkPackage(int uid, String packageName) {
2081        try {
2082            if (mService.checkPackage(uid, packageName) != MODE_ALLOWED) {
2083                throw new SecurityException(
2084                        "Package " + packageName + " does not belong to " + uid);
2085            }
2086        } catch (RemoteException e) {
2087            throw e.rethrowFromSystemServer();
2088        }
2089    }
2090
2091    /**
2092     * Like {@link #checkOp} but at a stream-level for audio operations.
2093     * @hide
2094     */
2095    public int checkAudioOp(int op, int stream, int uid, String packageName) {
2096        try {
2097            final int mode = mService.checkAudioOperation(op, stream, uid, packageName);
2098            if (mode == MODE_ERRORED) {
2099                throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
2100            }
2101            return mode;
2102        } catch (RemoteException e) {
2103            throw e.rethrowFromSystemServer();
2104        }
2105    }
2106
2107    /**
2108     * Like {@link #checkAudioOp} but instead of throwing a {@link SecurityException} it
2109     * returns {@link #MODE_ERRORED}.
2110     * @hide
2111     */
2112    public int checkAudioOpNoThrow(int op, int stream, int uid, String packageName) {
2113        try {
2114            return mService.checkAudioOperation(op, stream, uid, packageName);
2115        } catch (RemoteException e) {
2116            throw e.rethrowFromSystemServer();
2117        }
2118    }
2119
2120    /**
2121     * Make note of an application performing an operation.  Note that you must pass
2122     * in both the uid and name of the application to be checked; this function will verify
2123     * that these two match, and if not, return {@link #MODE_IGNORED}.  If this call
2124     * succeeds, the last execution time of the operation for this app will be updated to
2125     * the current time.
2126     * @param op The operation to note.  One of the OP_* constants.
2127     * @param uid The user id of the application attempting to perform the operation.
2128     * @param packageName The name of the application attempting to perform the operation.
2129     * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
2130     * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
2131     * causing the app to crash).
2132     * @throws SecurityException If the app has been configured to crash on this op.
2133     * @hide
2134     */
2135    public int noteOp(int op, int uid, String packageName) {
2136        final int mode = noteOpNoThrow(op, uid, packageName);
2137        if (mode == MODE_ERRORED) {
2138            throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
2139        }
2140        return mode;
2141    }
2142
2143    /**
2144     * Make note of an application performing an operation on behalf of another
2145     * application when handling an IPC. Note that you must pass the package name
2146     * of the application that is being proxied while its UID will be inferred from
2147     * the IPC state; this function will verify that the calling uid and proxied
2148     * package name match, and if not, return {@link #MODE_IGNORED}. If this call
2149     * succeeds, the last execution time of the operation for the proxied app and
2150     * your app will be updated to the current time.
2151     * @param op The operation to note. One of the OPSTR_* constants.
2152     * @param proxiedPackageName The name of the application calling into the proxy application.
2153     * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
2154     * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
2155     * causing the app to crash).
2156     * @throws SecurityException If the proxy or proxied app has been configured to
2157     * crash on this op.
2158     *
2159     * @hide
2160     */
2161    public int noteProxyOp(int op, String proxiedPackageName) {
2162        int mode = noteProxyOpNoThrow(op, proxiedPackageName);
2163        if (mode == MODE_ERRORED) {
2164            throw new SecurityException("Proxy package " + mContext.getOpPackageName()
2165                    + " from uid " + Process.myUid() + " or calling package "
2166                    + proxiedPackageName + " from uid " + Binder.getCallingUid()
2167                    + " not allowed to perform " + sOpNames[op]);
2168        }
2169        return mode;
2170    }
2171
2172    /**
2173     * Like {@link #noteProxyOp(int, String)} but instead
2174     * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
2175     * @hide
2176     */
2177    public int noteProxyOpNoThrow(int op, String proxiedPackageName) {
2178        try {
2179            return mService.noteProxyOperation(op, mContext.getOpPackageName(),
2180                    Binder.getCallingUid(), proxiedPackageName);
2181        } catch (RemoteException e) {
2182            throw e.rethrowFromSystemServer();
2183        }
2184    }
2185
2186    /**
2187     * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
2188     * returns {@link #MODE_ERRORED}.
2189     * @hide
2190     */
2191    public int noteOpNoThrow(int op, int uid, String packageName) {
2192        try {
2193            return mService.noteOperation(op, uid, packageName);
2194        } catch (RemoteException e) {
2195            throw e.rethrowFromSystemServer();
2196        }
2197    }
2198
2199    /** @hide */
2200    public int noteOp(int op) {
2201        return noteOp(op, Process.myUid(), mContext.getOpPackageName());
2202    }
2203
2204    /** @hide */
2205    public static IBinder getToken(IAppOpsService service) {
2206        synchronized (AppOpsManager.class) {
2207            if (sToken != null) {
2208                return sToken;
2209            }
2210            try {
2211                sToken = service.getToken(new Binder());
2212            } catch (RemoteException e) {
2213                throw e.rethrowFromSystemServer();
2214            }
2215            return sToken;
2216        }
2217    }
2218
2219    /** @hide */
2220    public int startOp(int op) {
2221        return startOp(op, Process.myUid(), mContext.getOpPackageName());
2222    }
2223
2224    /**
2225     * Report that an application has started executing a long-running operation.  Note that you
2226     * must pass in both the uid and name of the application to be checked; this function will
2227     * verify that these two match, and if not, return {@link #MODE_IGNORED}.  If this call
2228     * succeeds, the last execution time of the operation for this app will be updated to
2229     * the current time and the operation will be marked as "running".  In this case you must
2230     * later call {@link #finishOp(int, int, String)} to report when the application is no
2231     * longer performing the operation.
2232     *
2233     * @param op The operation to start.  One of the OP_* constants.
2234     * @param uid The user id of the application attempting to perform the operation.
2235     * @param packageName The name of the application attempting to perform the operation.
2236     * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
2237     * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
2238     * causing the app to crash).
2239     * @throws SecurityException If the app has been configured to crash on this op.
2240     * @hide
2241     */
2242    public int startOp(int op, int uid, String packageName) {
2243        return startOp(op, uid, packageName, false);
2244    }
2245
2246    /**
2247     * Report that an application has started executing a long-running operation. Similar
2248     * to {@link #startOp(String, int, String) except that if the mode is {@link #MODE_DEFAULT}
2249     * the operation should succeed since the caller has performed its standard permission
2250     * checks which passed and would perform the protected operation for this mode.
2251     *
2252     * @param op The operation to start.  One of the OP_* constants.
2253     * @param uid The user id of the application attempting to perform the operation.
2254     * @param packageName The name of the application attempting to perform the operation.
2255     * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
2256     * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
2257     * causing the app to crash).
2258     * @param startIfModeDefault Whether to start if mode is {@link #MODE_DEFAULT}.
2259     *
2260     * @throws SecurityException If the app has been configured to crash on this op or
2261     * the package is not in the passed in UID.
2262     *
2263     * @hide
2264     */
2265    public int startOp(int op, int uid, String packageName, boolean startIfModeDefault) {
2266        final int mode = startOpNoThrow(op, uid, packageName, startIfModeDefault);
2267        if (mode == MODE_ERRORED) {
2268            throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
2269        }
2270        return mode;
2271    }
2272
2273    /**
2274     * Like {@link #startOp} but instead of throwing a {@link SecurityException} it
2275     * returns {@link #MODE_ERRORED}.
2276     * @hide
2277     */
2278    public int startOpNoThrow(int op, int uid, String packageName) {
2279        return startOpNoThrow(op, uid, packageName, false);
2280    }
2281
2282    /**
2283     * Like {@link #startOp(int, int, String, boolean)} but instead of throwing a
2284     * {@link SecurityException} it returns {@link #MODE_ERRORED}.
2285     *
2286     * @param op The operation to start.  One of the OP_* constants.
2287     * @param uid The user id of the application attempting to perform the operation.
2288     * @param packageName The name of the application attempting to perform the operation.
2289     * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
2290     * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
2291     * causing the app to crash).
2292     * @param startIfModeDefault Whether to start if mode is {@link #MODE_DEFAULT}.
2293     *
2294     * @hide
2295     */
2296    public int startOpNoThrow(int op, int uid, String packageName, boolean startIfModeDefault) {
2297        try {
2298            return mService.startOperation(getToken(mService), op, uid, packageName,
2299                    startIfModeDefault);
2300        } catch (RemoteException e) {
2301            throw e.rethrowFromSystemServer();
2302        }
2303    }
2304
2305    /**
2306     * Report that an application is no longer performing an operation that had previously
2307     * been started with {@link #startOp(int, int, String)}.  There is no validation of input
2308     * or result; the parameters supplied here must be the exact same ones previously passed
2309     * in when starting the operation.
2310     * @hide
2311     */
2312    public void finishOp(int op, int uid, String packageName) {
2313        try {
2314            mService.finishOperation(getToken(mService), op, uid, packageName);
2315        } catch (RemoteException e) {
2316            throw e.rethrowFromSystemServer();
2317        }
2318    }
2319
2320    /** @hide */
2321    public void finishOp(int op) {
2322        finishOp(op, Process.myUid(), mContext.getOpPackageName());
2323    }
2324
2325    /**
2326     * Checks whether the given op for a UID and package is active.
2327     *
2328     * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
2329     * you can query only for your UID.
2330     *
2331     * @see #startWatchingActive(int[], OnOpActiveChangedListener)
2332     * @see #stopWatchingMode(OnOpChangedListener)
2333     * @see #finishOp(int)
2334     * @see #startOp(int)
2335     *
2336     * @hide */
2337    @TestApi
2338    // TODO: Uncomment below annotation once b/73559440 is fixed
2339    // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
2340    public boolean isOperationActive(int code, int uid, String packageName) {
2341        try {
2342            return mService.isOperationActive(code, uid, packageName);
2343        } catch (RemoteException e) {
2344            throw e.rethrowFromSystemServer();
2345        }
2346    }
2347
2348    /**
2349     * Returns all supported operation names.
2350     * @hide
2351     */
2352    @SystemApi
2353    @TestApi
2354    public static String[] getOpStrs() {
2355        return Arrays.copyOf(sOpToString, sOpToString.length);
2356    }
2357}
2358