blob: 67fbc5a46832d88b05c0b229cf2a419afdfafb53 [file] [log] [blame]
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001/*
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
Svet Ganov16a16892015-04-16 10:32:04 -070019import android.Manifest;
Jeff Davidson05542602014-08-11 14:07:27 -070020import android.annotation.SystemApi;
21import android.app.usage.UsageStatsManager;
22import android.content.Context;
John Spurlock7b414672014-07-18 13:02:39 -040023import android.media.AudioAttributes.AttributeUsage;
Dianne Hackborne98f5db2013-07-17 17:23:25 -070024import android.os.Binder;
25import android.os.IBinder;
Dianne Hackborn35654b62013-01-14 17:38:02 -080026import android.os.Parcel;
27import android.os.Parcelable;
Dianne Hackborna06de0f2012-12-11 16:34:47 -080028import android.os.Process;
29import android.os.RemoteException;
Dianne Hackborn7b7c58b2014-12-02 18:32:20 -080030import android.os.UserHandle;
Jeff Davidson05542602014-08-11 14:07:27 -070031import android.os.UserManager;
32import android.util.ArrayMap;
33
34import com.android.internal.app.IAppOpsCallback;
35import com.android.internal.app.IAppOpsService;
36
37import java.util.ArrayList;
38import java.util.HashMap;
39import java.util.List;
Dianne Hackborna06de0f2012-12-11 16:34:47 -080040
Dianne Hackbornd7d28e62013-02-12 14:59:53 -080041/**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070042 * API for interacting with "application operation" tracking.
Dianne Hackbornd7d28e62013-02-12 14:59:53 -080043 *
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070044 * <p>This API is not generally intended for third party application developers; most
John Spurlock925b85e2014-03-10 16:52:11 -040045 * features are only available to system applications. Obtain an instance of it through
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070046 * {@link Context#getSystemService(String) Context.getSystemService} with
47 * {@link Context#APP_OPS_SERVICE Context.APP_OPS_SERVICE}.</p>
Dianne Hackbornd7d28e62013-02-12 14:59:53 -080048 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -080049public class AppOpsManager {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070050 /**
51 * <p>App ops allows callers to:</p>
52 *
53 * <ul>
54 * <li> Note when operations are happening, and find out if they are allowed for the current
55 * caller.</li>
56 * <li> Disallow specific apps from doing specific operations.</li>
57 * <li> Collect all of the current information about operations that have been executed or
58 * are not being allowed.</li>
59 * <li> Monitor for changes in whether an operation is allowed.</li>
60 * </ul>
61 *
62 * <p>Each operation is identified by a single integer; these integers are a fixed set of
63 * operations, enumerated by the OP_* constants.
64 *
65 * <p></p>When checking operations, the result is a "mode" integer indicating the current
66 * setting for the operation under that caller: MODE_ALLOWED, MODE_IGNORED (don't execute
67 * the operation but fake its behavior enough so that the caller doesn't crash),
68 * MODE_ERRORED (throw a SecurityException back to the caller; the normal operation calls
69 * will do this for you).
70 */
71
Dianne Hackborna06de0f2012-12-11 16:34:47 -080072 final Context mContext;
73 final IAppOpsService mService;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070074 final ArrayMap<OnOpChangedListener, IAppOpsCallback> mModeWatchers
75 = new ArrayMap<OnOpChangedListener, IAppOpsCallback>();
Dianne Hackborna06de0f2012-12-11 16:34:47 -080076
Dianne Hackborne98f5db2013-07-17 17:23:25 -070077 static IBinder sToken;
78
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070079 /**
80 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is
81 * allowed to perform the given operation.
82 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -080083 public static final int MODE_ALLOWED = 0;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070084
85 /**
86 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is
87 * not allowed to perform the given operation, and this attempt should
88 * <em>silently fail</em> (it should not cause the app to crash).
89 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -080090 public static final int MODE_IGNORED = 1;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070091
92 /**
93 * Result from {@link #checkOpNoThrow}, {@link #noteOpNoThrow}, {@link #startOpNoThrow}: the
94 * given caller is not allowed to perform the given operation, and this attempt should
95 * cause it to have a fatal error, typically a {@link SecurityException}.
96 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -080097 public static final int MODE_ERRORED = 2;
98
Dianne Hackborn33f5ddd2014-07-21 15:35:45 -070099 /**
100 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller should
101 * use its default security check. This mode is not normally used; it should only be used
102 * with appop permissions, and callers must explicitly check for it and deal with it.
103 */
104 public static final int MODE_DEFAULT = 3;
105
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500106 // when adding one of these:
107 // - increment _NUM_OP
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -0700108 // - add rows to sOpToSwitch, sOpToString, sOpNames, sOpToPerms, sOpDefault
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500109 // - add descriptive strings to Settings/res/values/arrays.xml
David Christie0b837452013-07-29 16:02:13 -0700110 // - add the op to the appropriate template in AppOpsState.OpsTemplate (settings app)
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700111
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700112 /** @hide No operation specified. */
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800113 public static final int OP_NONE = -1;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700114 /** @hide Access to coarse location information. */
Dianne Hackborn35654b62013-01-14 17:38:02 -0800115 public static final int OP_COARSE_LOCATION = 0;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700116 /** @hide Access to fine location information. */
Dianne Hackborn35654b62013-01-14 17:38:02 -0800117 public static final int OP_FINE_LOCATION = 1;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700118 /** @hide Causing GPS to run. */
Dianne Hackborn35654b62013-01-14 17:38:02 -0800119 public static final int OP_GPS = 2;
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800120 /** @hide */
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700121 public static final int OP_VIBRATE = 3;
122 /** @hide */
123 public static final int OP_READ_CONTACTS = 4;
124 /** @hide */
125 public static final int OP_WRITE_CONTACTS = 5;
126 /** @hide */
127 public static final int OP_READ_CALL_LOG = 6;
128 /** @hide */
129 public static final int OP_WRITE_CALL_LOG = 7;
130 /** @hide */
131 public static final int OP_READ_CALENDAR = 8;
132 /** @hide */
133 public static final int OP_WRITE_CALENDAR = 9;
134 /** @hide */
135 public static final int OP_WIFI_SCAN = 10;
136 /** @hide */
137 public static final int OP_POST_NOTIFICATION = 11;
138 /** @hide */
139 public static final int OP_NEIGHBORING_CELLS = 12;
140 /** @hide */
141 public static final int OP_CALL_PHONE = 13;
142 /** @hide */
143 public static final int OP_READ_SMS = 14;
144 /** @hide */
145 public static final int OP_WRITE_SMS = 15;
146 /** @hide */
147 public static final int OP_RECEIVE_SMS = 16;
148 /** @hide */
149 public static final int OP_RECEIVE_EMERGECY_SMS = 17;
150 /** @hide */
151 public static final int OP_RECEIVE_MMS = 18;
152 /** @hide */
153 public static final int OP_RECEIVE_WAP_PUSH = 19;
154 /** @hide */
155 public static final int OP_SEND_SMS = 20;
156 /** @hide */
157 public static final int OP_READ_ICC_SMS = 21;
158 /** @hide */
159 public static final int OP_WRITE_ICC_SMS = 22;
160 /** @hide */
161 public static final int OP_WRITE_SETTINGS = 23;
162 /** @hide */
163 public static final int OP_SYSTEM_ALERT_WINDOW = 24;
164 /** @hide */
165 public static final int OP_ACCESS_NOTIFICATIONS = 25;
166 /** @hide */
167 public static final int OP_CAMERA = 26;
168 /** @hide */
169 public static final int OP_RECORD_AUDIO = 27;
170 /** @hide */
171 public static final int OP_PLAY_AUDIO = 28;
172 /** @hide */
173 public static final int OP_READ_CLIPBOARD = 29;
174 /** @hide */
175 public static final int OP_WRITE_CLIPBOARD = 30;
176 /** @hide */
177 public static final int OP_TAKE_MEDIA_BUTTONS = 31;
178 /** @hide */
179 public static final int OP_TAKE_AUDIO_FOCUS = 32;
180 /** @hide */
181 public static final int OP_AUDIO_MASTER_VOLUME = 33;
182 /** @hide */
183 public static final int OP_AUDIO_VOICE_VOLUME = 34;
184 /** @hide */
185 public static final int OP_AUDIO_RING_VOLUME = 35;
186 /** @hide */
187 public static final int OP_AUDIO_MEDIA_VOLUME = 36;
188 /** @hide */
189 public static final int OP_AUDIO_ALARM_VOLUME = 37;
190 /** @hide */
191 public static final int OP_AUDIO_NOTIFICATION_VOLUME = 38;
192 /** @hide */
193 public static final int OP_AUDIO_BLUETOOTH_VOLUME = 39;
194 /** @hide */
195 public static final int OP_WAKE_LOCK = 40;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700196 /** @hide Continually monitoring location data. */
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700197 public static final int OP_MONITOR_LOCATION = 41;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700198 /** @hide Continually monitoring location data with a relatively high power request. */
David Christie0b837452013-07-29 16:02:13 -0700199 public static final int OP_MONITOR_HIGH_POWER_LOCATION = 42;
Dianne Hackborne22b3b12014-05-07 18:06:44 -0700200 /** @hide Retrieve current usage stats via {@link UsageStatsManager}. */
201 public static final int OP_GET_USAGE_STATS = 43;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700202 /** @hide */
Emily Bernier22c921a2014-05-28 11:01:32 -0400203 public static final int OP_MUTE_MICROPHONE = 44;
204 /** @hide */
Jason Monk1c7c3192014-06-26 12:52:18 -0400205 public static final int OP_TOAST_WINDOW = 45;
Michael Wrightc39d47a2014-07-08 18:07:36 -0700206 /** @hide Capture the device's display contents and/or audio */
207 public static final int OP_PROJECT_MEDIA = 46;
Jeff Davidson05542602014-08-11 14:07:27 -0700208 /** @hide Activate a VPN connection without user intervention. */
209 public static final int OP_ACTIVATE_VPN = 47;
Benjamin Franzf3ece362015-02-11 10:51:10 +0000210 /** @hide Access the WallpaperManagerAPI to write wallpapers. */
211 public static final int OP_WRITE_WALLPAPER = 48;
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700212 /** @hide Received the assist structure from an app. */
213 public static final int OP_ASSIST_STRUCTURE = 49;
214 /** @hide Received a screenshot from assist. */
215 public static final int OP_ASSIST_SCREENSHOT = 50;
Svet Ganov16a16892015-04-16 10:32:04 -0700216 /** @hide Read the phone state. */
217 public static final int OP_READ_PHONE_STATE = 51;
Svet Ganovc3300092015-04-17 09:07:22 -0700218 /** @hide Add voicemail messages to the voicemail content provider. */
219 public static final int OP_ADD_VOICEMAIL = 52;
Svetoslav5335b672015-04-29 12:00:51 -0700220 /** @hide Access APIs for SIP calling over VOIP or WiFi. */
221 public static final int OP_USE_SIP = 53;
Svetoslavc656e6f2015-04-29 14:08:16 -0700222 /** @hide Intercept outgoing calls. */
223 public static final int OP_PROCESS_OUTGOING_CALLS = 54;
Svetoslav4af76a52015-04-29 15:29:46 -0700224 /** @hide User the fingerprint API. */
225 public static final int OP_USE_FINGERPRINT = 55;
Svet Ganovb9d71a62015-04-30 10:38:13 -0700226 /** @hide Access to body sensors such as heart rate, etc. */
227 public static final int OP_BODY_SENSORS = 56;
Svet Ganovede43162015-05-02 17:42:44 -0700228 /** @hide Read previously received cell broadcast messages. */
229 public static final int OP_READ_CELL_BROADCASTS = 57;
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700230 /** @hide Inject mock location into the system. */
231 public static final int OP_MOCK_LOCATION = 58;
Svet Ganov921c7df2015-06-29 21:51:41 -0700232 /** @hide Read external storage. */
233 public static final int OP_READ_EXTERNAL_STORAGE = 59;
234 /** @hide Write external storage. */
235 public static final int OP_WRITE_EXTERNAL_STORAGE = 60;
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700236 /** @hide Turned on the screen. */
237 public static final int OP_TURN_SCREEN_ON = 61;
Svetoslavf3f02ac2015-09-08 14:36:35 -0700238 /** @hide Get device accounts. */
239 public static final int OP_GET_ACCOUNTS = 62;
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700240 /** @hide Control whether an application is allowed to run in the background. */
241 public static final int OP_RUN_IN_BACKGROUND = 63;
Jason Monk1c7c3192014-06-26 12:52:18 -0400242 /** @hide */
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -0800243 public static final int OP_AUDIO_ACCESSIBILITY_VOLUME = 64;
Chad Brubaker73ec8f92016-11-10 11:24:40 -0800244 /** @hide Read the phone number. */
245 public static final int OP_READ_PHONE_NUMBER = 65;
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -0800246 /** @hide */
Chad Brubaker73ec8f92016-11-10 11:24:40 -0800247 public static final int _NUM_OP = 66;
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800248
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700249 /** Access to coarse location information. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700250 public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700251 /** Access to fine location information. */
252 public static final String OPSTR_FINE_LOCATION =
253 "android:fine_location";
254 /** Continually monitoring location data. */
255 public static final String OPSTR_MONITOR_LOCATION
256 = "android:monitor_location";
257 /** Continually monitoring location data with a relatively high power request. */
258 public static final String OPSTR_MONITOR_HIGH_POWER_LOCATION
259 = "android:monitor_location_high_power";
Dianne Hackborn5064e7c2014-09-02 10:57:16 -0700260 /** Access to {@link android.app.usage.UsageStatsManager}. */
261 public static final String OPSTR_GET_USAGE_STATS
262 = "android:get_usage_stats";
Jeff Davidson05542602014-08-11 14:07:27 -0700263 /** Activate a VPN connection without user intervention. @hide */
264 @SystemApi
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700265 public static final String OPSTR_ACTIVATE_VPN
266 = "android:activate_vpn";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700267 /** Allows an application to read the user's contacts data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700268 public static final String OPSTR_READ_CONTACTS
269 = "android:read_contacts";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700270 /** Allows an application to write to the user's contacts data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700271 public static final String OPSTR_WRITE_CONTACTS
272 = "android:write_contacts";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700273 /** Allows an application to read the user's call log. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700274 public static final String OPSTR_READ_CALL_LOG
275 = "android:read_call_log";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700276 /** Allows an application to write to the user's call log. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700277 public static final String OPSTR_WRITE_CALL_LOG
278 = "android:write_call_log";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700279 /** Allows an application to read the user's calendar data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700280 public static final String OPSTR_READ_CALENDAR
281 = "android:read_calendar";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700282 /** Allows an application to write to the user's calendar data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700283 public static final String OPSTR_WRITE_CALENDAR
284 = "android:write_calendar";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700285 /** Allows an application to initiate a phone call. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700286 public static final String OPSTR_CALL_PHONE
287 = "android:call_phone";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700288 /** Allows an application to read SMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700289 public static final String OPSTR_READ_SMS
290 = "android:read_sms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700291 /** Allows an application to receive SMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700292 public static final String OPSTR_RECEIVE_SMS
293 = "android:receive_sms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700294 /** Allows an application to receive MMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700295 public static final String OPSTR_RECEIVE_MMS
296 = "android:receive_mms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700297 /** Allows an application to receive WAP push messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700298 public static final String OPSTR_RECEIVE_WAP_PUSH
299 = "android:receive_wap_push";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700300 /** Allows an application to send SMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700301 public static final String OPSTR_SEND_SMS
302 = "android:send_sms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700303 /** Required to be able to access the camera device. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700304 public static final String OPSTR_CAMERA
305 = "android:camera";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700306 /** Required to be able to access the microphone device. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700307 public static final String OPSTR_RECORD_AUDIO
308 = "android:record_audio";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700309 /** Required to access phone state related information. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700310 public static final String OPSTR_READ_PHONE_STATE
311 = "android:read_phone_state";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700312 /** Required to access phone state related information. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700313 public static final String OPSTR_ADD_VOICEMAIL
314 = "android:add_voicemail";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700315 /** Access APIs for SIP calling over VOIP or WiFi */
Svet Ganovb9d71a62015-04-30 10:38:13 -0700316 public static final String OPSTR_USE_SIP
317 = "android:use_sip";
Svet Ganove8e89422016-09-22 19:56:50 -0700318 /** Access APIs for diverting outgoing calls */
Svet Ganov824ad6e2016-09-22 19:36:53 -0700319 public static final String OPSTR_PROCESS_OUTGOING_CALLS
320 = "android:process_outgoing_calls";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700321 /** Use the fingerprint API. */
Svet Ganovb9d71a62015-04-30 10:38:13 -0700322 public static final String OPSTR_USE_FINGERPRINT
323 = "android:use_fingerprint";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700324 /** Access to body sensors such as heart rate, etc. */
Svet Ganovb9d71a62015-04-30 10:38:13 -0700325 public static final String OPSTR_BODY_SENSORS
326 = "android:body_sensors";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700327 /** Read previously received cell broadcast messages. */
Svet Ganovede43162015-05-02 17:42:44 -0700328 public static final String OPSTR_READ_CELL_BROADCASTS
329 = "android:read_cell_broadcasts";
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700330 /** Inject mock location into the system. */
331 public static final String OPSTR_MOCK_LOCATION
332 = "android:mock_location";
Svet Ganov921c7df2015-06-29 21:51:41 -0700333 /** Read external storage. */
334 public static final String OPSTR_READ_EXTERNAL_STORAGE
335 = "android:read_external_storage";
336 /** Write external storage. */
337 public static final String OPSTR_WRITE_EXTERNAL_STORAGE
338 = "android:write_external_storage";
Billy Lau24b9c832015-07-20 17:34:09 +0100339 /** Required to draw on top of other apps. */
340 public static final String OPSTR_SYSTEM_ALERT_WINDOW
341 = "android:system_alert_window";
342 /** Required to write/modify/update system settingss. */
343 public static final String OPSTR_WRITE_SETTINGS
344 = "android:write_settings";
Svetoslavf3f02ac2015-09-08 14:36:35 -0700345 /** @hide Get device accounts. */
346 public static final String OPSTR_GET_ACCOUNTS
347 = "android:get_accounts";
Chad Brubaker73ec8f92016-11-10 11:24:40 -0800348 public static final String OPSTR_READ_PHONE_NUMBER
349 = "android:read_phone_number";
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700350
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -0700351 private static final int[] RUNTIME_PERMISSIONS_OPS = {
352 // Contacts
353 OP_READ_CONTACTS,
354 OP_WRITE_CONTACTS,
355 OP_GET_ACCOUNTS,
356 // Calendar
357 OP_READ_CALENDAR,
358 OP_WRITE_CALENDAR,
359 // SMS
360 OP_SEND_SMS,
361 OP_RECEIVE_SMS,
362 OP_READ_SMS,
363 OP_RECEIVE_WAP_PUSH,
364 OP_RECEIVE_MMS,
365 OP_READ_CELL_BROADCASTS,
366 // Storage
367 OP_READ_EXTERNAL_STORAGE,
368 OP_WRITE_EXTERNAL_STORAGE,
369 // Location
370 OP_COARSE_LOCATION,
371 OP_FINE_LOCATION,
372 // Phone
373 OP_READ_PHONE_STATE,
Chad Brubaker73ec8f92016-11-10 11:24:40 -0800374 OP_READ_PHONE_NUMBER,
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -0700375 OP_CALL_PHONE,
376 OP_READ_CALL_LOG,
377 OP_WRITE_CALL_LOG,
378 OP_ADD_VOICEMAIL,
379 OP_USE_SIP,
380 OP_PROCESS_OUTGOING_CALLS,
381 // Microphone
382 OP_RECORD_AUDIO,
383 // Camera
384 OP_CAMERA,
385 // Body sensors
386 OP_BODY_SENSORS
387 };
388
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800389 /**
390 * This maps each operation to the operation that serves as the
391 * switch to determine whether it is allowed. Generally this is
392 * a 1:1 mapping, but for some things (like location) that have
393 * multiple low-level operations being tracked that should be
David Christie0b837452013-07-29 16:02:13 -0700394 * presented to the user as one switch then this can be used to
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800395 * make them all controlled by the same single operation.
396 */
397 private static int[] sOpToSwitch = new int[] {
398 OP_COARSE_LOCATION,
399 OP_COARSE_LOCATION,
400 OP_COARSE_LOCATION,
401 OP_VIBRATE,
402 OP_READ_CONTACTS,
403 OP_WRITE_CONTACTS,
404 OP_READ_CALL_LOG,
405 OP_WRITE_CALL_LOG,
406 OP_READ_CALENDAR,
407 OP_WRITE_CALENDAR,
408 OP_COARSE_LOCATION,
409 OP_POST_NOTIFICATION,
410 OP_COARSE_LOCATION,
411 OP_CALL_PHONE,
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800412 OP_READ_SMS,
413 OP_WRITE_SMS,
David Braun18966a82013-09-10 13:14:46 -0700414 OP_RECEIVE_SMS,
415 OP_RECEIVE_SMS,
Svet Ganov99e4d512016-09-21 19:50:14 -0700416 OP_RECEIVE_MMS,
417 OP_RECEIVE_WAP_PUSH,
David Braun18966a82013-09-10 13:14:46 -0700418 OP_SEND_SMS,
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800419 OP_READ_SMS,
420 OP_WRITE_SMS,
Dianne Hackborn961321f2013-02-05 17:22:41 -0800421 OP_WRITE_SETTINGS,
Dianne Hackbornc2293022013-02-06 23:14:49 -0800422 OP_SYSTEM_ALERT_WINDOW,
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500423 OP_ACCESS_NOTIFICATIONS,
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800424 OP_CAMERA,
425 OP_RECORD_AUDIO,
426 OP_PLAY_AUDIO,
Dianne Hackbornefcc1a22013-02-25 18:02:35 -0800427 OP_READ_CLIPBOARD,
428 OP_WRITE_CLIPBOARD,
Dianne Hackbornba50b97c2013-04-30 15:04:46 -0700429 OP_TAKE_MEDIA_BUTTONS,
430 OP_TAKE_AUDIO_FOCUS,
431 OP_AUDIO_MASTER_VOLUME,
432 OP_AUDIO_VOICE_VOLUME,
433 OP_AUDIO_RING_VOLUME,
434 OP_AUDIO_MEDIA_VOLUME,
435 OP_AUDIO_ALARM_VOLUME,
436 OP_AUDIO_NOTIFICATION_VOLUME,
437 OP_AUDIO_BLUETOOTH_VOLUME,
Dianne Hackborn713df152013-05-17 11:27:57 -0700438 OP_WAKE_LOCK,
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700439 OP_COARSE_LOCATION,
David Christie0b837452013-07-29 16:02:13 -0700440 OP_COARSE_LOCATION,
Dianne Hackborne22b3b12014-05-07 18:06:44 -0700441 OP_GET_USAGE_STATS,
Jason Monk1c7c3192014-06-26 12:52:18 -0400442 OP_MUTE_MICROPHONE,
443 OP_TOAST_WINDOW,
Michael Wrightc39d47a2014-07-08 18:07:36 -0700444 OP_PROJECT_MEDIA,
Jeff Davidson05542602014-08-11 14:07:27 -0700445 OP_ACTIVATE_VPN,
Benjamin Franzf3ece362015-02-11 10:51:10 +0000446 OP_WRITE_WALLPAPER,
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700447 OP_ASSIST_STRUCTURE,
448 OP_ASSIST_SCREENSHOT,
Svet Ganovc3300092015-04-17 09:07:22 -0700449 OP_READ_PHONE_STATE,
Svetoslav5335b672015-04-29 12:00:51 -0700450 OP_ADD_VOICEMAIL,
Svetoslavc656e6f2015-04-29 14:08:16 -0700451 OP_USE_SIP,
Svetoslav4af76a52015-04-29 15:29:46 -0700452 OP_PROCESS_OUTGOING_CALLS,
Svet Ganovb9d71a62015-04-30 10:38:13 -0700453 OP_USE_FINGERPRINT,
Svet Ganovede43162015-05-02 17:42:44 -0700454 OP_BODY_SENSORS,
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700455 OP_READ_CELL_BROADCASTS,
Svet Ganov921c7df2015-06-29 21:51:41 -0700456 OP_MOCK_LOCATION,
457 OP_READ_EXTERNAL_STORAGE,
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700458 OP_WRITE_EXTERNAL_STORAGE,
459 OP_TURN_SCREEN_ON,
Svetoslavf3f02ac2015-09-08 14:36:35 -0700460 OP_GET_ACCOUNTS,
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700461 OP_RUN_IN_BACKGROUND,
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -0800462 OP_AUDIO_ACCESSIBILITY_VOLUME,
Chad Brubaker73ec8f92016-11-10 11:24:40 -0800463 OP_READ_PHONE_NUMBER,
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800464 };
465
466 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700467 * This maps each operation to the public string constant for it.
468 * If it doesn't have a public string constant, it maps to null.
469 */
470 private static String[] sOpToString = new String[] {
471 OPSTR_COARSE_LOCATION,
472 OPSTR_FINE_LOCATION,
473 null,
474 null,
Svet Ganovb9d71a62015-04-30 10:38:13 -0700475 OPSTR_READ_CONTACTS,
476 OPSTR_WRITE_CONTACTS,
477 OPSTR_READ_CALL_LOG,
478 OPSTR_WRITE_CALL_LOG,
479 OPSTR_READ_CALENDAR,
480 OPSTR_WRITE_CALENDAR,
481 null,
482 null,
483 null,
484 OPSTR_CALL_PHONE,
485 OPSTR_READ_SMS,
486 null,
487 OPSTR_RECEIVE_SMS,
488 null,
489 OPSTR_RECEIVE_MMS,
490 OPSTR_RECEIVE_WAP_PUSH,
491 OPSTR_SEND_SMS,
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700492 null,
493 null,
Billy Lau24b9c832015-07-20 17:34:09 +0100494 OPSTR_WRITE_SETTINGS,
495 OPSTR_SYSTEM_ALERT_WINDOW,
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700496 null,
Svet Ganovb9d71a62015-04-30 10:38:13 -0700497 OPSTR_CAMERA,
498 OPSTR_RECORD_AUDIO,
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700499 null,
500 null,
501 null,
502 null,
503 null,
504 null,
505 null,
506 null,
507 null,
508 null,
509 null,
510 null,
511 null,
512 OPSTR_MONITOR_LOCATION,
513 OPSTR_MONITOR_HIGH_POWER_LOCATION,
Dianne Hackborn5064e7c2014-09-02 10:57:16 -0700514 OPSTR_GET_USAGE_STATS,
Emily Bernier22c921a2014-05-28 11:01:32 -0400515 null,
Jason Monk1c7c3192014-06-26 12:52:18 -0400516 null,
Michael Wrightc39d47a2014-07-08 18:07:36 -0700517 null,
Jeff Davidson05542602014-08-11 14:07:27 -0700518 OPSTR_ACTIVATE_VPN,
Benjamin Franzf3ece362015-02-11 10:51:10 +0000519 null,
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700520 null,
521 null,
Svet Ganovb9d71a62015-04-30 10:38:13 -0700522 OPSTR_READ_PHONE_STATE,
523 OPSTR_ADD_VOICEMAIL,
524 OPSTR_USE_SIP,
Svet Ganov824ad6e2016-09-22 19:36:53 -0700525 OPSTR_PROCESS_OUTGOING_CALLS,
Svet Ganovb9d71a62015-04-30 10:38:13 -0700526 OPSTR_USE_FINGERPRINT,
Svet Ganovede43162015-05-02 17:42:44 -0700527 OPSTR_BODY_SENSORS,
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700528 OPSTR_READ_CELL_BROADCASTS,
Svet Ganov921c7df2015-06-29 21:51:41 -0700529 OPSTR_MOCK_LOCATION,
530 OPSTR_READ_EXTERNAL_STORAGE,
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700531 OPSTR_WRITE_EXTERNAL_STORAGE,
532 null,
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700533 OPSTR_GET_ACCOUNTS,
534 null,
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -0800535 null, // OP_AUDIO_ACCESSIBILITY_VOLUME
Chad Brubaker73ec8f92016-11-10 11:24:40 -0800536 OPSTR_READ_PHONE_NUMBER,
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700537 };
538
539 /**
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800540 * This provides a simple name for each operation to be used
541 * in debug output.
542 */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800543 private static String[] sOpNames = new String[] {
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800544 "COARSE_LOCATION",
545 "FINE_LOCATION",
546 "GPS",
547 "VIBRATE",
548 "READ_CONTACTS",
549 "WRITE_CONTACTS",
550 "READ_CALL_LOG",
551 "WRITE_CALL_LOG",
552 "READ_CALENDAR",
553 "WRITE_CALENDAR",
554 "WIFI_SCAN",
555 "POST_NOTIFICATION",
556 "NEIGHBORING_CELLS",
557 "CALL_PHONE",
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800558 "READ_SMS",
559 "WRITE_SMS",
560 "RECEIVE_SMS",
561 "RECEIVE_EMERGECY_SMS",
562 "RECEIVE_MMS",
563 "RECEIVE_WAP_PUSH",
564 "SEND_SMS",
565 "READ_ICC_SMS",
566 "WRITE_ICC_SMS",
Dianne Hackborn961321f2013-02-05 17:22:41 -0800567 "WRITE_SETTINGS",
Dianne Hackbornc2293022013-02-06 23:14:49 -0800568 "SYSTEM_ALERT_WINDOW",
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500569 "ACCESS_NOTIFICATIONS",
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800570 "CAMERA",
571 "RECORD_AUDIO",
572 "PLAY_AUDIO",
Dianne Hackbornefcc1a22013-02-25 18:02:35 -0800573 "READ_CLIPBOARD",
574 "WRITE_CLIPBOARD",
Dianne Hackbornba50b97c2013-04-30 15:04:46 -0700575 "TAKE_MEDIA_BUTTONS",
576 "TAKE_AUDIO_FOCUS",
577 "AUDIO_MASTER_VOLUME",
578 "AUDIO_VOICE_VOLUME",
579 "AUDIO_RING_VOLUME",
580 "AUDIO_MEDIA_VOLUME",
581 "AUDIO_ALARM_VOLUME",
582 "AUDIO_NOTIFICATION_VOLUME",
583 "AUDIO_BLUETOOTH_VOLUME",
Dianne Hackborn713df152013-05-17 11:27:57 -0700584 "WAKE_LOCK",
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700585 "MONITOR_LOCATION",
David Christie0b837452013-07-29 16:02:13 -0700586 "MONITOR_HIGH_POWER_LOCATION",
Emily Bernier22c921a2014-05-28 11:01:32 -0400587 "GET_USAGE_STATS",
Michael Wrightc39d47a2014-07-08 18:07:36 -0700588 "MUTE_MICROPHONE",
Jason Monk1c7c3192014-06-26 12:52:18 -0400589 "TOAST_WINDOW",
Michael Wrightc39d47a2014-07-08 18:07:36 -0700590 "PROJECT_MEDIA",
Jeff Davidson05542602014-08-11 14:07:27 -0700591 "ACTIVATE_VPN",
Benjamin Franzf3ece362015-02-11 10:51:10 +0000592 "WRITE_WALLPAPER",
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700593 "ASSIST_STRUCTURE",
Svet Ganov16a16892015-04-16 10:32:04 -0700594 "ASSIST_SCREENSHOT",
Svet Ganovc3300092015-04-17 09:07:22 -0700595 "OP_READ_PHONE_STATE",
Svetoslav5335b672015-04-29 12:00:51 -0700596 "ADD_VOICEMAIL",
Svetoslavc656e6f2015-04-29 14:08:16 -0700597 "USE_SIP",
Svetoslav4af76a52015-04-29 15:29:46 -0700598 "PROCESS_OUTGOING_CALLS",
Svet Ganovb9d71a62015-04-30 10:38:13 -0700599 "USE_FINGERPRINT",
Svet Ganovede43162015-05-02 17:42:44 -0700600 "BODY_SENSORS",
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700601 "READ_CELL_BROADCASTS",
Svet Ganov921c7df2015-06-29 21:51:41 -0700602 "MOCK_LOCATION",
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700603 "READ_EXTERNAL_STORAGE",
604 "WRITE_EXTERNAL_STORAGE",
605 "TURN_ON_SCREEN",
Svetoslavf3f02ac2015-09-08 14:36:35 -0700606 "GET_ACCOUNTS",
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700607 "RUN_IN_BACKGROUND",
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -0800608 "AUDIO_ACCESSIBILITY_VOLUME",
Chad Brubaker73ec8f92016-11-10 11:24:40 -0800609 "READ_PHONE_NUMBER",
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800610 };
611
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800612 /**
613 * This optionally maps a permission to an operation. If there
614 * is no permission associated with an operation, it is null.
615 */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800616 private static String[] sOpPerms = new String[] {
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800617 android.Manifest.permission.ACCESS_COARSE_LOCATION,
618 android.Manifest.permission.ACCESS_FINE_LOCATION,
619 null,
620 android.Manifest.permission.VIBRATE,
621 android.Manifest.permission.READ_CONTACTS,
622 android.Manifest.permission.WRITE_CONTACTS,
623 android.Manifest.permission.READ_CALL_LOG,
624 android.Manifest.permission.WRITE_CALL_LOG,
625 android.Manifest.permission.READ_CALENDAR,
626 android.Manifest.permission.WRITE_CALENDAR,
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800627 android.Manifest.permission.ACCESS_WIFI_STATE,
Robert Craigf97616c2013-10-07 12:32:02 -0400628 null, // no permission required for notifications
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800629 null, // neighboring cells shares the coarse location perm
630 android.Manifest.permission.CALL_PHONE,
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800631 android.Manifest.permission.READ_SMS,
Svetoslav6c589572015-04-16 16:19:24 -0700632 null, // no permission required for writing sms
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800633 android.Manifest.permission.RECEIVE_SMS,
634 android.Manifest.permission.RECEIVE_EMERGENCY_BROADCAST,
635 android.Manifest.permission.RECEIVE_MMS,
636 android.Manifest.permission.RECEIVE_WAP_PUSH,
637 android.Manifest.permission.SEND_SMS,
638 android.Manifest.permission.READ_SMS,
Svetoslav6c589572015-04-16 16:19:24 -0700639 null, // no permission required for writing icc sms
Dianne Hackborn961321f2013-02-05 17:22:41 -0800640 android.Manifest.permission.WRITE_SETTINGS,
Dianne Hackbornc2293022013-02-06 23:14:49 -0800641 android.Manifest.permission.SYSTEM_ALERT_WINDOW,
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500642 android.Manifest.permission.ACCESS_NOTIFICATIONS,
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800643 android.Manifest.permission.CAMERA,
644 android.Manifest.permission.RECORD_AUDIO,
645 null, // no permission for playing audio
Dianne Hackbornefcc1a22013-02-25 18:02:35 -0800646 null, // no permission for reading clipboard
647 null, // no permission for writing clipboard
Dianne Hackbornba50b97c2013-04-30 15:04:46 -0700648 null, // no permission for taking media buttons
649 null, // no permission for taking audio focus
650 null, // no permission for changing master volume
651 null, // no permission for changing voice volume
652 null, // no permission for changing ring volume
653 null, // no permission for changing media volume
654 null, // no permission for changing alarm volume
655 null, // no permission for changing notification volume
656 null, // no permission for changing bluetooth volume
Dianne Hackborn713df152013-05-17 11:27:57 -0700657 android.Manifest.permission.WAKE_LOCK,
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700658 null, // no permission for generic location monitoring
David Christie0b837452013-07-29 16:02:13 -0700659 null, // no permission for high power location monitoring
Dianne Hackborne22b3b12014-05-07 18:06:44 -0700660 android.Manifest.permission.PACKAGE_USAGE_STATS,
Emily Bernier22c921a2014-05-28 11:01:32 -0400661 null, // no permission for muting/unmuting microphone
Jason Monk1c7c3192014-06-26 12:52:18 -0400662 null, // no permission for displaying toasts
Michael Wrightc39d47a2014-07-08 18:07:36 -0700663 null, // no permission for projecting media
Jeff Davidson05542602014-08-11 14:07:27 -0700664 null, // no permission for activating vpn
Benjamin Franzf3ece362015-02-11 10:51:10 +0000665 null, // no permission for supporting wallpaper
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700666 null, // no permission for receiving assist structure
667 null, // no permission for receiving assist screenshot
Svet Ganovc3300092015-04-17 09:07:22 -0700668 Manifest.permission.READ_PHONE_STATE,
Svetoslav5335b672015-04-29 12:00:51 -0700669 Manifest.permission.ADD_VOICEMAIL,
Svetoslavc656e6f2015-04-29 14:08:16 -0700670 Manifest.permission.USE_SIP,
Svetoslav4af76a52015-04-29 15:29:46 -0700671 Manifest.permission.PROCESS_OUTGOING_CALLS,
Svet Ganovb9d71a62015-04-30 10:38:13 -0700672 Manifest.permission.USE_FINGERPRINT,
Svet Ganovede43162015-05-02 17:42:44 -0700673 Manifest.permission.BODY_SENSORS,
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700674 Manifest.permission.READ_CELL_BROADCASTS,
Svet Ganov921c7df2015-06-29 21:51:41 -0700675 null,
676 Manifest.permission.READ_EXTERNAL_STORAGE,
677 Manifest.permission.WRITE_EXTERNAL_STORAGE,
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700678 null, // no permission for turning the screen on
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700679 Manifest.permission.GET_ACCOUNTS,
680 null, // no permission for running in background
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -0800681 null, // no permission for changing accessibility volume
Chad Brubaker73ec8f92016-11-10 11:24:40 -0800682 Manifest.permission.READ_PHONE_NUMBER,
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800683 };
684
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800685 /**
Jason Monk62062992014-05-06 09:55:28 -0400686 * Specifies whether an Op should be restricted by a user restriction.
687 * Each Op should be filled with a restriction string from UserManager or
688 * null to specify it is not affected by any user restriction.
689 */
690 private static String[] sOpRestrictions = new String[] {
Julia Reynolds9854d572014-07-02 14:46:02 -0400691 UserManager.DISALLOW_SHARE_LOCATION, //COARSE_LOCATION
692 UserManager.DISALLOW_SHARE_LOCATION, //FINE_LOCATION
693 UserManager.DISALLOW_SHARE_LOCATION, //GPS
Jason Monk62062992014-05-06 09:55:28 -0400694 null, //VIBRATE
695 null, //READ_CONTACTS
696 null, //WRITE_CONTACTS
Yorke Lee15f83c62014-08-13 14:14:29 -0700697 UserManager.DISALLOW_OUTGOING_CALLS, //READ_CALL_LOG
698 UserManager.DISALLOW_OUTGOING_CALLS, //WRITE_CALL_LOG
Jason Monk62062992014-05-06 09:55:28 -0400699 null, //READ_CALENDAR
700 null, //WRITE_CALENDAR
Julia Reynolds9854d572014-07-02 14:46:02 -0400701 UserManager.DISALLOW_SHARE_LOCATION, //WIFI_SCAN
Jason Monk62062992014-05-06 09:55:28 -0400702 null, //POST_NOTIFICATION
703 null, //NEIGHBORING_CELLS
704 null, //CALL_PHONE
Amith Yamasani41c1ded2014-08-05 11:15:05 -0700705 UserManager.DISALLOW_SMS, //READ_SMS
706 UserManager.DISALLOW_SMS, //WRITE_SMS
707 UserManager.DISALLOW_SMS, //RECEIVE_SMS
708 null, //RECEIVE_EMERGENCY_SMS
709 UserManager.DISALLOW_SMS, //RECEIVE_MMS
Jason Monk62062992014-05-06 09:55:28 -0400710 null, //RECEIVE_WAP_PUSH
Amith Yamasani41c1ded2014-08-05 11:15:05 -0700711 UserManager.DISALLOW_SMS, //SEND_SMS
712 UserManager.DISALLOW_SMS, //READ_ICC_SMS
713 UserManager.DISALLOW_SMS, //WRITE_ICC_SMS
Jason Monk62062992014-05-06 09:55:28 -0400714 null, //WRITE_SETTINGS
Jason Monk1c7c3192014-06-26 12:52:18 -0400715 UserManager.DISALLOW_CREATE_WINDOWS, //SYSTEM_ALERT_WINDOW
Jason Monk62062992014-05-06 09:55:28 -0400716 null, //ACCESS_NOTIFICATIONS
Makoto Onuki759a7632015-10-28 16:43:10 -0700717 UserManager.DISALLOW_CAMERA, //CAMERA
Fyodor Kupolovb5013302015-04-17 17:59:14 -0700718 UserManager.DISALLOW_RECORD_AUDIO, //RECORD_AUDIO
Jason Monk62062992014-05-06 09:55:28 -0400719 null, //PLAY_AUDIO
720 null, //READ_CLIPBOARD
721 null, //WRITE_CLIPBOARD
722 null, //TAKE_MEDIA_BUTTONS
723 null, //TAKE_AUDIO_FOCUS
Emily Bernier45775c42014-05-16 15:12:04 -0400724 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MASTER_VOLUME
725 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_VOICE_VOLUME
726 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_RING_VOLUME
727 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MEDIA_VOLUME
728 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ALARM_VOLUME
729 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_NOTIFICATION_VOLUME
730 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_BLUETOOTH_VOLUME
Jason Monk62062992014-05-06 09:55:28 -0400731 null, //WAKE_LOCK
Julia Reynolds9854d572014-07-02 14:46:02 -0400732 UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_LOCATION
733 UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_HIGH_POWER_LOCATION
Jason Monk62062992014-05-06 09:55:28 -0400734 null, //GET_USAGE_STATS
Emily Bernier22c921a2014-05-28 11:01:32 -0400735 UserManager.DISALLOW_UNMUTE_MICROPHONE, // MUTE_MICROPHONE
Jason Monk1c7c3192014-06-26 12:52:18 -0400736 UserManager.DISALLOW_CREATE_WINDOWS, // TOAST_WINDOW
Michael Wrightc39d47a2014-07-08 18:07:36 -0700737 null, //PROJECT_MEDIA
Tony Mak33d03a92016-06-02 15:01:16 +0100738 null, // ACTIVATE_VPN
Benjamin Franzf3ece362015-02-11 10:51:10 +0000739 UserManager.DISALLOW_WALLPAPER, // WRITE_WALLPAPER
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700740 null, // ASSIST_STRUCTURE
741 null, // ASSIST_SCREENSHOT
Svet Ganovc3300092015-04-17 09:07:22 -0700742 null, // READ_PHONE_STATE
Svetoslav5335b672015-04-29 12:00:51 -0700743 null, // ADD_VOICEMAIL
Svetoslavc656e6f2015-04-29 14:08:16 -0700744 null, // USE_SIP
Svetoslav4af76a52015-04-29 15:29:46 -0700745 null, // PROCESS_OUTGOING_CALLS
Svet Ganovb9d71a62015-04-30 10:38:13 -0700746 null, // USE_FINGERPRINT
Svet Ganovede43162015-05-02 17:42:44 -0700747 null, // BODY_SENSORS
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700748 null, // READ_CELL_BROADCASTS
Svet Ganov921c7df2015-06-29 21:51:41 -0700749 null, // MOCK_LOCATION
750 null, // READ_EXTERNAL_STORAGE
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700751 null, // WRITE_EXTERNAL_STORAGE
752 null, // TURN_ON_SCREEN
Svetoslavf3f02ac2015-09-08 14:36:35 -0700753 null, // GET_ACCOUNTS
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700754 null, // RUN_IN_BACKGROUND
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -0800755 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ACCESSIBILITY_VOLUME
Chad Brubaker73ec8f92016-11-10 11:24:40 -0800756 null, // READ_PHONE_NUMBER
Jason Monk1c7c3192014-06-26 12:52:18 -0400757 };
758
759 /**
760 * This specifies whether each option should allow the system
761 * (and system ui) to bypass the user restriction when active.
762 */
763 private static boolean[] sOpAllowSystemRestrictionBypass = new boolean[] {
Fyodor Kupolov639e73d2016-02-25 11:58:21 -0800764 true, //COARSE_LOCATION
765 true, //FINE_LOCATION
Jason Monk1c7c3192014-06-26 12:52:18 -0400766 false, //GPS
767 false, //VIBRATE
768 false, //READ_CONTACTS
769 false, //WRITE_CONTACTS
770 false, //READ_CALL_LOG
771 false, //WRITE_CALL_LOG
772 false, //READ_CALENDAR
773 false, //WRITE_CALENDAR
Julia Reynolds9854d572014-07-02 14:46:02 -0400774 true, //WIFI_SCAN
Jason Monk1c7c3192014-06-26 12:52:18 -0400775 false, //POST_NOTIFICATION
776 false, //NEIGHBORING_CELLS
777 false, //CALL_PHONE
778 false, //READ_SMS
779 false, //WRITE_SMS
780 false, //RECEIVE_SMS
781 false, //RECEIVE_EMERGECY_SMS
782 false, //RECEIVE_MMS
783 false, //RECEIVE_WAP_PUSH
784 false, //SEND_SMS
785 false, //READ_ICC_SMS
786 false, //WRITE_ICC_SMS
787 false, //WRITE_SETTINGS
788 true, //SYSTEM_ALERT_WINDOW
789 false, //ACCESS_NOTIFICATIONS
790 false, //CAMERA
791 false, //RECORD_AUDIO
792 false, //PLAY_AUDIO
793 false, //READ_CLIPBOARD
794 false, //WRITE_CLIPBOARD
795 false, //TAKE_MEDIA_BUTTONS
796 false, //TAKE_AUDIO_FOCUS
797 false, //AUDIO_MASTER_VOLUME
798 false, //AUDIO_VOICE_VOLUME
799 false, //AUDIO_RING_VOLUME
800 false, //AUDIO_MEDIA_VOLUME
801 false, //AUDIO_ALARM_VOLUME
802 false, //AUDIO_NOTIFICATION_VOLUME
803 false, //AUDIO_BLUETOOTH_VOLUME
804 false, //WAKE_LOCK
805 false, //MONITOR_LOCATION
806 false, //MONITOR_HIGH_POWER_LOCATION
807 false, //GET_USAGE_STATS
Michael Wrightc39d47a2014-07-08 18:07:36 -0700808 false, //MUTE_MICROPHONE
809 true, //TOAST_WINDOW
810 false, //PROJECT_MEDIA
Jeff Davidson05542602014-08-11 14:07:27 -0700811 false, //ACTIVATE_VPN
Benjamin Franzf3ece362015-02-11 10:51:10 +0000812 false, //WALLPAPER
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700813 false, //ASSIST_STRUCTURE
814 false, //ASSIST_SCREENSHOT
Svet Ganov16a16892015-04-16 10:32:04 -0700815 false, //READ_PHONE_STATE
Svetoslav5335b672015-04-29 12:00:51 -0700816 false, //ADD_VOICEMAIL
Svetoslavc656e6f2015-04-29 14:08:16 -0700817 false, // USE_SIP
Svetoslav4af76a52015-04-29 15:29:46 -0700818 false, // PROCESS_OUTGOING_CALLS
Svet Ganovb9d71a62015-04-30 10:38:13 -0700819 false, // USE_FINGERPRINT
Svet Ganovede43162015-05-02 17:42:44 -0700820 false, // BODY_SENSORS
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700821 false, // READ_CELL_BROADCASTS
Svet Ganov921c7df2015-06-29 21:51:41 -0700822 false, // MOCK_LOCATION
823 false, // READ_EXTERNAL_STORAGE
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700824 false, // WRITE_EXTERNAL_STORAGE
825 false, // TURN_ON_SCREEN
Svetoslavf3f02ac2015-09-08 14:36:35 -0700826 false, // GET_ACCOUNTS
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700827 false, // RUN_IN_BACKGROUND
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -0800828 false, // AUDIO_ACCESSIBILITY_VOLUME
Chad Brubaker73ec8f92016-11-10 11:24:40 -0800829 false, // READ_PHONE_NUMBER
Jason Monk62062992014-05-06 09:55:28 -0400830 };
831
832 /**
David Braunf5d83192013-09-16 13:43:51 -0700833 * This specifies the default mode for each operation.
834 */
835 private static int[] sOpDefaultMode = new int[] {
836 AppOpsManager.MODE_ALLOWED,
837 AppOpsManager.MODE_ALLOWED,
838 AppOpsManager.MODE_ALLOWED,
839 AppOpsManager.MODE_ALLOWED,
840 AppOpsManager.MODE_ALLOWED,
841 AppOpsManager.MODE_ALLOWED,
842 AppOpsManager.MODE_ALLOWED,
843 AppOpsManager.MODE_ALLOWED,
844 AppOpsManager.MODE_ALLOWED,
845 AppOpsManager.MODE_ALLOWED,
846 AppOpsManager.MODE_ALLOWED,
847 AppOpsManager.MODE_ALLOWED,
848 AppOpsManager.MODE_ALLOWED,
849 AppOpsManager.MODE_ALLOWED,
850 AppOpsManager.MODE_ALLOWED,
851 AppOpsManager.MODE_IGNORED, // OP_WRITE_SMS
852 AppOpsManager.MODE_ALLOWED,
853 AppOpsManager.MODE_ALLOWED,
854 AppOpsManager.MODE_ALLOWED,
855 AppOpsManager.MODE_ALLOWED,
856 AppOpsManager.MODE_ALLOWED,
857 AppOpsManager.MODE_ALLOWED,
858 AppOpsManager.MODE_ALLOWED,
Billy Lau6ad2d662015-07-18 00:26:58 +0100859 AppOpsManager.MODE_DEFAULT, // OP_WRITE_SETTINGS
Billy Lau060275f2015-07-15 22:29:19 +0100860 AppOpsManager.MODE_DEFAULT, // OP_SYSTEM_ALERT_WINDOW
David Braunf5d83192013-09-16 13:43:51 -0700861 AppOpsManager.MODE_ALLOWED,
862 AppOpsManager.MODE_ALLOWED,
863 AppOpsManager.MODE_ALLOWED,
864 AppOpsManager.MODE_ALLOWED,
865 AppOpsManager.MODE_ALLOWED,
866 AppOpsManager.MODE_ALLOWED,
867 AppOpsManager.MODE_ALLOWED,
868 AppOpsManager.MODE_ALLOWED,
869 AppOpsManager.MODE_ALLOWED,
870 AppOpsManager.MODE_ALLOWED,
871 AppOpsManager.MODE_ALLOWED,
872 AppOpsManager.MODE_ALLOWED,
873 AppOpsManager.MODE_ALLOWED,
874 AppOpsManager.MODE_ALLOWED,
875 AppOpsManager.MODE_ALLOWED,
876 AppOpsManager.MODE_ALLOWED,
877 AppOpsManager.MODE_ALLOWED,
878 AppOpsManager.MODE_ALLOWED,
Dianne Hackborn33f5ddd2014-07-21 15:35:45 -0700879 AppOpsManager.MODE_DEFAULT, // OP_GET_USAGE_STATS
Emily Bernier22c921a2014-05-28 11:01:32 -0400880 AppOpsManager.MODE_ALLOWED,
Jason Monk1c7c3192014-06-26 12:52:18 -0400881 AppOpsManager.MODE_ALLOWED,
Michael Wrightc39d47a2014-07-08 18:07:36 -0700882 AppOpsManager.MODE_IGNORED, // OP_PROJECT_MEDIA
Jeff Davidson05542602014-08-11 14:07:27 -0700883 AppOpsManager.MODE_IGNORED, // OP_ACTIVATE_VPN
Benjamin Franzf3ece362015-02-11 10:51:10 +0000884 AppOpsManager.MODE_ALLOWED,
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700885 AppOpsManager.MODE_ALLOWED,
886 AppOpsManager.MODE_ALLOWED,
Svet Ganovc3300092015-04-17 09:07:22 -0700887 AppOpsManager.MODE_ALLOWED,
Svetoslav5335b672015-04-29 12:00:51 -0700888 AppOpsManager.MODE_ALLOWED,
Svetoslavc656e6f2015-04-29 14:08:16 -0700889 AppOpsManager.MODE_ALLOWED,
Svetoslav4af76a52015-04-29 15:29:46 -0700890 AppOpsManager.MODE_ALLOWED,
Svet Ganovb9d71a62015-04-30 10:38:13 -0700891 AppOpsManager.MODE_ALLOWED,
Svet Ganovede43162015-05-02 17:42:44 -0700892 AppOpsManager.MODE_ALLOWED,
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700893 AppOpsManager.MODE_ALLOWED,
Svet Ganov921c7df2015-06-29 21:51:41 -0700894 AppOpsManager.MODE_ERRORED, // OP_MOCK_LOCATION
895 AppOpsManager.MODE_ALLOWED,
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700896 AppOpsManager.MODE_ALLOWED,
897 AppOpsManager.MODE_ALLOWED, // OP_TURN_ON_SCREEN
Svetoslavf3f02ac2015-09-08 14:36:35 -0700898 AppOpsManager.MODE_ALLOWED,
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700899 AppOpsManager.MODE_ALLOWED, // OP_RUN_IN_BACKGROUND
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -0800900 AppOpsManager.MODE_ALLOWED, // OP_AUDIO_ACCESSIBILITY_VOLUME
Chad Brubaker73ec8f92016-11-10 11:24:40 -0800901 AppOpsManager.MODE_ALLOWED,
David Braunf5d83192013-09-16 13:43:51 -0700902 };
903
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700904 /**
905 * This specifies whether each option is allowed to be reset
906 * when resetting all app preferences. Disable reset for
907 * app ops that are under strong control of some part of the
908 * system (such as OP_WRITE_SMS, which should be allowed only
909 * for whichever app is selected as the current SMS app).
910 */
911 private static boolean[] sOpDisableReset = new boolean[] {
912 false,
913 false,
914 false,
915 false,
916 false,
917 false,
918 false,
919 false,
920 false,
921 false,
922 false,
923 false,
924 false,
925 false,
926 false,
927 true, // OP_WRITE_SMS
928 false,
929 false,
930 false,
931 false,
932 false,
933 false,
934 false,
935 false,
936 false,
937 false,
938 false,
939 false,
940 false,
941 false,
942 false,
943 false,
944 false,
945 false,
946 false,
947 false,
948 false,
949 false,
950 false,
951 false,
952 false,
953 false,
954 false,
Dianne Hackborne22b3b12014-05-07 18:06:44 -0700955 false,
Emily Bernier22c921a2014-05-28 11:01:32 -0400956 false,
Jason Monk1c7c3192014-06-26 12:52:18 -0400957 false,
Michael Wrightc39d47a2014-07-08 18:07:36 -0700958 false,
Jeff Davidson05542602014-08-11 14:07:27 -0700959 false,
Benjamin Franzf3ece362015-02-11 10:51:10 +0000960 false,
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700961 false,
962 false,
Svet Ganovc3300092015-04-17 09:07:22 -0700963 false,
Svetoslav5335b672015-04-29 12:00:51 -0700964 false,
Svetoslavc656e6f2015-04-29 14:08:16 -0700965 false,
Svetoslav4af76a52015-04-29 15:29:46 -0700966 false,
Svet Ganovb9d71a62015-04-30 10:38:13 -0700967 false,
Svet Ganovede43162015-05-02 17:42:44 -0700968 false,
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700969 false,
Svet Ganov921c7df2015-06-29 21:51:41 -0700970 false,
971 false,
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700972 false,
973 false,
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700974 false,
975 false,
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -0800976 false, // OP_AUDIO_ACCESSIBILITY_VOLUME
Chad Brubaker73ec8f92016-11-10 11:24:40 -0800977 false,
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700978 };
979
Svet Ganovfbf01f72015-04-28 18:39:06 -0700980 /**
Svet Ganovb9d71a62015-04-30 10:38:13 -0700981 * Mapping from an app op name to the app op code.
Svet Ganovfbf01f72015-04-28 18:39:06 -0700982 */
Svet Ganovb9d71a62015-04-30 10:38:13 -0700983 private static HashMap<String, Integer> sOpStrToOp = new HashMap<>();
Svet Ganovfbf01f72015-04-28 18:39:06 -0700984
Svet Ganovb9d71a62015-04-30 10:38:13 -0700985 /**
986 * Mapping from a permission to the corresponding app op.
987 */
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -0700988 private static HashMap<String, Integer> sRuntimePermToOp = new HashMap<>();
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700989
990 static {
991 if (sOpToSwitch.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700992 throw new IllegalStateException("sOpToSwitch length " + sOpToSwitch.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700993 + " should be " + _NUM_OP);
994 }
995 if (sOpToString.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700996 throw new IllegalStateException("sOpToString length " + sOpToString.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700997 + " should be " + _NUM_OP);
998 }
999 if (sOpNames.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001000 throw new IllegalStateException("sOpNames length " + sOpNames.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001001 + " should be " + _NUM_OP);
1002 }
1003 if (sOpPerms.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001004 throw new IllegalStateException("sOpPerms length " + sOpPerms.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001005 + " should be " + _NUM_OP);
1006 }
1007 if (sOpDefaultMode.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001008 throw new IllegalStateException("sOpDefaultMode length " + sOpDefaultMode.length
1009 + " should be " + _NUM_OP);
1010 }
1011 if (sOpDisableReset.length != _NUM_OP) {
1012 throw new IllegalStateException("sOpDisableReset length " + sOpDisableReset.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001013 + " should be " + _NUM_OP);
1014 }
Jason Monk62062992014-05-06 09:55:28 -04001015 if (sOpRestrictions.length != _NUM_OP) {
1016 throw new IllegalStateException("sOpRestrictions length " + sOpRestrictions.length
1017 + " should be " + _NUM_OP);
1018 }
Jason Monk1c7c3192014-06-26 12:52:18 -04001019 if (sOpAllowSystemRestrictionBypass.length != _NUM_OP) {
1020 throw new IllegalStateException("sOpAllowSYstemRestrictionsBypass length "
1021 + sOpRestrictions.length + " should be " + _NUM_OP);
1022 }
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001023 for (int i=0; i<_NUM_OP; i++) {
1024 if (sOpToString[i] != null) {
1025 sOpStrToOp.put(sOpToString[i], i);
1026 }
1027 }
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001028 for (int op : RUNTIME_PERMISSIONS_OPS) {
1029 if (sOpPerms[op] != null) {
1030 sRuntimePermToOp.put(sOpPerms[op], op);
Svet Ganovb9d71a62015-04-30 10:38:13 -07001031 }
1032 }
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001033 }
1034
David Braunf5d83192013-09-16 13:43:51 -07001035 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001036 * Retrieve the op switch that controls the given operation.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001037 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001038 */
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001039 public static int opToSwitch(int op) {
1040 return sOpToSwitch[op];
1041 }
1042
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001043 /**
1044 * Retrieve a non-localized name for the operation, for debugging output.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001045 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001046 */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001047 public static String opToName(int op) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08001048 if (op == OP_NONE) return "NONE";
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001049 return op < sOpNames.length ? sOpNames[op] : ("Unknown(" + op + ")");
1050 }
1051
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001052 /**
Dianne Hackborn7b7c58b2014-12-02 18:32:20 -08001053 * @hide
1054 */
1055 public static int strDebugOpToOp(String op) {
1056 for (int i=0; i<sOpNames.length; i++) {
1057 if (sOpNames[i].equals(op)) {
1058 return i;
1059 }
1060 }
1061 throw new IllegalArgumentException("Unknown operation string: " + op);
1062 }
1063
1064 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001065 * Retrieve the permission associated with an operation, or null if there is not one.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001066 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001067 */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001068 public static String opToPermission(int op) {
1069 return sOpPerms[op];
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001070 }
1071
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001072 /**
Jason Monk62062992014-05-06 09:55:28 -04001073 * Retrieve the user restriction associated with an operation, or null if there is not one.
1074 * @hide
1075 */
1076 public static String opToRestriction(int op) {
1077 return sOpRestrictions[op];
1078 }
1079
1080 /**
Svet Ganovb9d71a62015-04-30 10:38:13 -07001081 * Retrieve the app op code for a permission, or null if there is not one.
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001082 * This API is intended to be used for mapping runtime permissions to the
1083 * corresponding app op.
Svet Ganovb9d71a62015-04-30 10:38:13 -07001084 * @hide
1085 */
1086 public static int permissionToOpCode(String permission) {
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001087 Integer boxedOpCode = sRuntimePermToOp.get(permission);
Svet Ganov019d2302015-05-04 11:07:38 -07001088 return boxedOpCode != null ? boxedOpCode : OP_NONE;
Svet Ganovb9d71a62015-04-30 10:38:13 -07001089 }
1090
1091 /**
Jason Monk1c7c3192014-06-26 12:52:18 -04001092 * Retrieve whether the op allows the system (and system ui) to
1093 * bypass the user restriction.
1094 * @hide
1095 */
1096 public static boolean opAllowSystemBypassRestriction(int op) {
1097 return sOpAllowSystemRestrictionBypass[op];
1098 }
1099
1100 /**
David Braunf5d83192013-09-16 13:43:51 -07001101 * Retrieve the default mode for the operation.
1102 * @hide
1103 */
1104 public static int opToDefaultMode(int op) {
1105 return sOpDefaultMode[op];
1106 }
1107
1108 /**
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001109 * Retrieve whether the op allows itself to be reset.
1110 * @hide
1111 */
1112 public static boolean opAllowsReset(int op) {
1113 return !sOpDisableReset[op];
1114 }
1115
1116 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001117 * Class holding all of the operation information associated with an app.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001118 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001119 */
Dianne Hackborn35654b62013-01-14 17:38:02 -08001120 public static class PackageOps implements Parcelable {
1121 private final String mPackageName;
1122 private final int mUid;
1123 private final List<OpEntry> mEntries;
1124
1125 public PackageOps(String packageName, int uid, List<OpEntry> entries) {
1126 mPackageName = packageName;
1127 mUid = uid;
1128 mEntries = entries;
1129 }
1130
1131 public String getPackageName() {
1132 return mPackageName;
1133 }
1134
1135 public int getUid() {
1136 return mUid;
1137 }
1138
1139 public List<OpEntry> getOps() {
1140 return mEntries;
1141 }
1142
1143 @Override
1144 public int describeContents() {
1145 return 0;
1146 }
1147
1148 @Override
1149 public void writeToParcel(Parcel dest, int flags) {
1150 dest.writeString(mPackageName);
1151 dest.writeInt(mUid);
1152 dest.writeInt(mEntries.size());
1153 for (int i=0; i<mEntries.size(); i++) {
1154 mEntries.get(i).writeToParcel(dest, flags);
1155 }
1156 }
1157
1158 PackageOps(Parcel source) {
1159 mPackageName = source.readString();
1160 mUid = source.readInt();
1161 mEntries = new ArrayList<OpEntry>();
1162 final int N = source.readInt();
1163 for (int i=0; i<N; i++) {
1164 mEntries.add(OpEntry.CREATOR.createFromParcel(source));
1165 }
1166 }
1167
1168 public static final Creator<PackageOps> CREATOR = new Creator<PackageOps>() {
1169 @Override public PackageOps createFromParcel(Parcel source) {
1170 return new PackageOps(source);
1171 }
1172
1173 @Override public PackageOps[] newArray(int size) {
1174 return new PackageOps[size];
1175 }
1176 };
1177 }
1178
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001179 /**
1180 * Class holding the information about one unique operation of an application.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001181 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001182 */
Dianne Hackborn35654b62013-01-14 17:38:02 -08001183 public static class OpEntry implements Parcelable {
1184 private final int mOp;
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001185 private final int mMode;
Dianne Hackborn35654b62013-01-14 17:38:02 -08001186 private final long mTime;
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001187 private final long mRejectTime;
Dianne Hackborn35654b62013-01-14 17:38:02 -08001188 private final int mDuration;
Svet Ganov99b60432015-06-27 13:15:22 -07001189 private final int mProxyUid;
1190 private final String mProxyPackageName;
Dianne Hackborn35654b62013-01-14 17:38:02 -08001191
Svet Ganov99b60432015-06-27 13:15:22 -07001192 public OpEntry(int op, int mode, long time, long rejectTime, int duration,
1193 int proxyUid, String proxyPackage) {
Dianne Hackborn35654b62013-01-14 17:38:02 -08001194 mOp = op;
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001195 mMode = mode;
Dianne Hackborn35654b62013-01-14 17:38:02 -08001196 mTime = time;
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001197 mRejectTime = rejectTime;
Dianne Hackborn35654b62013-01-14 17:38:02 -08001198 mDuration = duration;
Svet Ganov99b60432015-06-27 13:15:22 -07001199 mProxyUid = proxyUid;
1200 mProxyPackageName = proxyPackage;
Dianne Hackborn35654b62013-01-14 17:38:02 -08001201 }
1202
1203 public int getOp() {
1204 return mOp;
1205 }
1206
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001207 public int getMode() {
1208 return mMode;
1209 }
1210
Dianne Hackborn35654b62013-01-14 17:38:02 -08001211 public long getTime() {
1212 return mTime;
1213 }
1214
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001215 public long getRejectTime() {
1216 return mRejectTime;
1217 }
1218
Dianne Hackborn35654b62013-01-14 17:38:02 -08001219 public boolean isRunning() {
1220 return mDuration == -1;
1221 }
1222
1223 public int getDuration() {
1224 return mDuration == -1 ? (int)(System.currentTimeMillis()-mTime) : mDuration;
1225 }
1226
Svet Ganov99b60432015-06-27 13:15:22 -07001227 public int getProxyUid() {
1228 return mProxyUid;
1229 }
1230
1231 public String getProxyPackageName() {
1232 return mProxyPackageName;
1233 }
1234
Dianne Hackborn35654b62013-01-14 17:38:02 -08001235 @Override
1236 public int describeContents() {
1237 return 0;
1238 }
1239
1240 @Override
1241 public void writeToParcel(Parcel dest, int flags) {
1242 dest.writeInt(mOp);
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001243 dest.writeInt(mMode);
Dianne Hackborn35654b62013-01-14 17:38:02 -08001244 dest.writeLong(mTime);
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001245 dest.writeLong(mRejectTime);
Dianne Hackborn35654b62013-01-14 17:38:02 -08001246 dest.writeInt(mDuration);
Svet Ganov99b60432015-06-27 13:15:22 -07001247 dest.writeInt(mProxyUid);
1248 dest.writeString(mProxyPackageName);
Dianne Hackborn35654b62013-01-14 17:38:02 -08001249 }
1250
1251 OpEntry(Parcel source) {
1252 mOp = source.readInt();
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001253 mMode = source.readInt();
Dianne Hackborn35654b62013-01-14 17:38:02 -08001254 mTime = source.readLong();
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001255 mRejectTime = source.readLong();
Dianne Hackborn35654b62013-01-14 17:38:02 -08001256 mDuration = source.readInt();
Svet Ganov99b60432015-06-27 13:15:22 -07001257 mProxyUid = source.readInt();
1258 mProxyPackageName = source.readString();
Dianne Hackborn35654b62013-01-14 17:38:02 -08001259 }
1260
1261 public static final Creator<OpEntry> CREATOR = new Creator<OpEntry>() {
1262 @Override public OpEntry createFromParcel(Parcel source) {
1263 return new OpEntry(source);
1264 }
1265
1266 @Override public OpEntry[] newArray(int size) {
1267 return new OpEntry[size];
1268 }
1269 };
1270 }
1271
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001272 /**
1273 * Callback for notification of changes to operation state.
1274 */
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001275 public interface OnOpChangedListener {
1276 public void onOpChanged(String op, String packageName);
1277 }
1278
1279 /**
1280 * Callback for notification of changes to operation state.
1281 * This allows you to see the raw op codes instead of strings.
1282 * @hide
1283 */
1284 public static class OnOpChangedInternalListener implements OnOpChangedListener {
1285 public void onOpChanged(String op, String packageName) { }
1286 public void onOpChanged(int op, String packageName) { }
Dianne Hackbornc2293022013-02-06 23:14:49 -08001287 }
1288
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001289 AppOpsManager(Context context, IAppOpsService service) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001290 mContext = context;
1291 mService = service;
1292 }
1293
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001294 /**
1295 * Retrieve current operation state for all applications.
1296 *
1297 * @param ops The set of operations you are interested in, or null if you want all of them.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001298 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001299 */
Dianne Hackborn35654b62013-01-14 17:38:02 -08001300 public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) {
1301 try {
1302 return mService.getPackagesForOps(ops);
1303 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001304 throw e.rethrowFromSystemServer();
Dianne Hackborn35654b62013-01-14 17:38:02 -08001305 }
Dianne Hackborn35654b62013-01-14 17:38:02 -08001306 }
1307
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001308 /**
1309 * Retrieve current operation state for one application.
1310 *
1311 * @param uid The uid of the application of interest.
1312 * @param packageName The name of the application of interest.
1313 * @param ops The set of operations you are interested in, or null if you want all of them.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001314 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001315 */
Dianne Hackborn72e39832013-01-18 18:36:09 -08001316 public List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, int[] ops) {
1317 try {
1318 return mService.getOpsForPackage(uid, packageName, ops);
1319 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001320 throw e.rethrowFromSystemServer();
Dianne Hackborn72e39832013-01-18 18:36:09 -08001321 }
Dianne Hackborn72e39832013-01-18 18:36:09 -08001322 }
1323
Svet Ganovae0e03a2016-02-25 18:22:10 -08001324 /**
1325 * Sets given app op in the specified mode for app ops in the UID.
1326 * This applies to all apps currently in the UID or installed in
1327 * this UID in the future.
1328 *
1329 * @param code The app op.
1330 * @param uid The UID for which to set the app.
1331 * @param mode The app op mode to set.
1332 * @hide
1333 */
Svet Ganov2af57082015-07-30 08:44:20 -07001334 public void setUidMode(int code, int uid, int mode) {
1335 try {
1336 mService.setUidMode(code, uid, mode);
1337 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001338 throw e.rethrowFromSystemServer();
Svet Ganov2af57082015-07-30 08:44:20 -07001339 }
1340 }
1341
Svet Ganovae0e03a2016-02-25 18:22:10 -08001342 /**
1343 * Sets given app op in the specified mode for app ops in the UID.
1344 * This applies to all apps currently in the UID or installed in
1345 * this UID in the future.
1346 *
1347 * @param appOp The app op.
1348 * @param uid The UID for which to set the app.
1349 * @param mode The app op mode to set.
1350 * @hide
1351 */
1352 @SystemApi
1353 public void setUidMode(String appOp, int uid, int mode) {
1354 try {
1355 mService.setUidMode(AppOpsManager.strOpToOp(appOp), uid, mode);
1356 } catch (RemoteException e) {
1357 throw e.rethrowFromSystemServer();
1358 }
1359 }
1360
Svet Ganov2af57082015-07-30 08:44:20 -07001361 /** @hide */
Svet Ganov9cea80cd2016-02-16 11:47:00 -08001362 public void setUserRestriction(int code, boolean restricted, IBinder token) {
Ruben Brunk29931bc2016-03-11 00:24:26 -08001363 setUserRestriction(code, restricted, token, /*exceptionPackages*/null);
1364 }
1365
1366 /** @hide */
1367 public void setUserRestriction(int code, boolean restricted, IBinder token,
1368 String[] exceptionPackages) {
Svetoslav Ganove33f6132016-06-01 16:25:31 -07001369 setUserRestrictionForUser(code, restricted, token, exceptionPackages, mContext.getUserId());
1370 }
1371
1372 /** @hide */
1373 public void setUserRestrictionForUser(int code, boolean restricted, IBinder token,
1374 String[] exceptionPackages, int userId) {
Svet Ganov9cea80cd2016-02-16 11:47:00 -08001375 try {
Svetoslav Ganove33f6132016-06-01 16:25:31 -07001376 mService.setUserRestriction(code, restricted, token, userId, exceptionPackages);
Svet Ganov9cea80cd2016-02-16 11:47:00 -08001377 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001378 throw e.rethrowFromSystemServer();
Svet Ganov9cea80cd2016-02-16 11:47:00 -08001379 }
1380 }
1381
1382 /** @hide */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001383 public void setMode(int code, int uid, String packageName, int mode) {
1384 try {
1385 mService.setMode(code, uid, packageName, mode);
1386 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001387 throw e.rethrowFromSystemServer();
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001388 }
1389 }
1390
John Spurlock1af30c72014-03-10 08:33:35 -04001391 /**
1392 * Set a non-persisted restriction on an audio operation at a stream-level.
1393 * Restrictions are temporary additional constraints imposed on top of the persisted rules
1394 * defined by {@link #setMode}.
1395 *
1396 * @param code The operation to restrict.
John Spurlock7b414672014-07-18 13:02:39 -04001397 * @param usage The {@link android.media.AudioAttributes} usage value.
John Spurlock1af30c72014-03-10 08:33:35 -04001398 * @param mode The restriction mode (MODE_IGNORED,MODE_ERRORED) or MODE_ALLOWED to unrestrict.
1399 * @param exceptionPackages Optional list of packages to exclude from the restriction.
1400 * @hide
1401 */
John Spurlock7b414672014-07-18 13:02:39 -04001402 public void setRestriction(int code, @AttributeUsage int usage, int mode,
1403 String[] exceptionPackages) {
John Spurlock1af30c72014-03-10 08:33:35 -04001404 try {
1405 final int uid = Binder.getCallingUid();
John Spurlock7b414672014-07-18 13:02:39 -04001406 mService.setAudioRestriction(code, usage, uid, mode, exceptionPackages);
John Spurlock1af30c72014-03-10 08:33:35 -04001407 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001408 throw e.rethrowFromSystemServer();
John Spurlock1af30c72014-03-10 08:33:35 -04001409 }
1410 }
1411
Dianne Hackborn607b4142013-08-02 18:10:10 -07001412 /** @hide */
1413 public void resetAllModes() {
1414 try {
Dianne Hackborn7b7c58b2014-12-02 18:32:20 -08001415 mService.resetAllModes(UserHandle.myUserId(), null);
Dianne Hackborn607b4142013-08-02 18:10:10 -07001416 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001417 throw e.rethrowFromSystemServer();
Dianne Hackborn607b4142013-08-02 18:10:10 -07001418 }
1419 }
1420
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001421 /**
Svet Ganovfbf01f72015-04-28 18:39:06 -07001422 * Gets the app op name associated with a given permission.
1423 * The app op name is one of the public constants defined
1424 * in this class such as {@link #OPSTR_COARSE_LOCATION}.
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001425 * This API is intended to be used for mapping runtime
1426 * permissions to the corresponding app op.
Svet Ganovfbf01f72015-04-28 18:39:06 -07001427 *
1428 * @param permission The permission.
1429 * @return The app op associated with the permission or null.
Svet Ganovfbf01f72015-04-28 18:39:06 -07001430 */
Svet Ganovfbf01f72015-04-28 18:39:06 -07001431 public static String permissionToOp(String permission) {
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001432 final Integer opCode = sRuntimePermToOp.get(permission);
Svet Ganovb9d71a62015-04-30 10:38:13 -07001433 if (opCode == null) {
1434 return null;
1435 }
1436 return sOpToString[opCode];
Svet Ganovfbf01f72015-04-28 18:39:06 -07001437 }
1438
1439 /**
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001440 * Monitor for changes to the operating mode for the given op in the given app package.
Dianne Hackborne4cb66f2013-10-02 10:34:02 -07001441 * @param op The operation to monitor, one of OPSTR_*.
1442 * @param packageName The name of the application to monitor.
1443 * @param callback Where to report changes.
1444 */
1445 public void startWatchingMode(String op, String packageName,
1446 final OnOpChangedListener callback) {
1447 startWatchingMode(strOpToOp(op), packageName, callback);
1448 }
1449
1450 /**
1451 * Monitor for changes to the operating mode for the given op in the given app package.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001452 * @param op The operation to monitor, one of OP_*.
1453 * @param packageName The name of the application to monitor.
1454 * @param callback Where to report changes.
Dianne Hackborne4cb66f2013-10-02 10:34:02 -07001455 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001456 */
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001457 public void startWatchingMode(int op, String packageName, final OnOpChangedListener callback) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08001458 synchronized (mModeWatchers) {
1459 IAppOpsCallback cb = mModeWatchers.get(callback);
1460 if (cb == null) {
1461 cb = new IAppOpsCallback.Stub() {
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001462 public void opChanged(int op, int uid, String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001463 if (callback instanceof OnOpChangedInternalListener) {
1464 ((OnOpChangedInternalListener)callback).onOpChanged(op, packageName);
1465 }
1466 if (sOpToString[op] != null) {
1467 callback.onOpChanged(sOpToString[op], packageName);
1468 }
Dianne Hackbornc2293022013-02-06 23:14:49 -08001469 }
1470 };
1471 mModeWatchers.put(callback, cb);
1472 }
1473 try {
1474 mService.startWatchingMode(op, packageName, cb);
1475 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001476 throw e.rethrowFromSystemServer();
Dianne Hackbornc2293022013-02-06 23:14:49 -08001477 }
1478 }
1479 }
1480
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001481 /**
1482 * Stop monitoring that was previously started with {@link #startWatchingMode}. All
1483 * monitoring associated with this callback will be removed.
1484 */
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001485 public void stopWatchingMode(OnOpChangedListener callback) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08001486 synchronized (mModeWatchers) {
1487 IAppOpsCallback cb = mModeWatchers.get(callback);
1488 if (cb != null) {
1489 try {
1490 mService.stopWatchingMode(cb);
1491 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001492 throw e.rethrowFromSystemServer();
Dianne Hackbornc2293022013-02-06 23:14:49 -08001493 }
1494 }
1495 }
1496 }
1497
Dianne Hackborn95d78532013-09-11 09:51:14 -07001498 private String buildSecurityExceptionMsg(int op, int uid, String packageName) {
1499 return packageName + " from uid " + uid + " not allowed to perform " + sOpNames[op];
1500 }
1501
Adam Lesinskib5cf61b2014-08-18 16:10:28 -07001502 /**
1503 * {@hide}
1504 */
1505 public static int strOpToOp(String op) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001506 Integer val = sOpStrToOp.get(op);
1507 if (val == null) {
1508 throw new IllegalArgumentException("Unknown operation string: " + op);
1509 }
1510 return val;
1511 }
1512
1513 /**
1514 * Do a quick check for whether an application might be able to perform an operation.
1515 * This is <em>not</em> a security check; you must use {@link #noteOp(String, int, String)}
1516 * or {@link #startOp(String, int, String)} for your actual security checks, which also
1517 * ensure that the given uid and package name are consistent. This function can just be
1518 * used for a quick check to see if an operation has been disabled for the application,
1519 * as an early reject of some work. This does not modify the time stamp or other data
1520 * about the operation.
1521 * @param op The operation to check. One of the OPSTR_* constants.
1522 * @param uid The user id of the application attempting to perform the operation.
1523 * @param packageName The name of the application attempting to perform the operation.
1524 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1525 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1526 * causing the app to crash).
1527 * @throws SecurityException If the app has been configured to crash on this op.
1528 */
1529 public int checkOp(String op, int uid, String packageName) {
1530 return checkOp(strOpToOp(op), uid, packageName);
1531 }
1532
1533 /**
John Spurlock925b85e2014-03-10 16:52:11 -04001534 * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001535 * returns {@link #MODE_ERRORED}.
1536 */
1537 public int checkOpNoThrow(String op, int uid, String packageName) {
1538 return checkOpNoThrow(strOpToOp(op), uid, packageName);
1539 }
1540
1541 /**
1542 * Make note of an application performing an operation. Note that you must pass
1543 * in both the uid and name of the application to be checked; this function will verify
1544 * that these two match, and if not, return {@link #MODE_IGNORED}. If this call
1545 * succeeds, the last execution time of the operation for this app will be updated to
1546 * the current time.
1547 * @param op The operation to note. One of the OPSTR_* constants.
1548 * @param uid The user id of the application attempting to perform the operation.
1549 * @param packageName The name of the application attempting to perform the operation.
1550 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1551 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1552 * causing the app to crash).
1553 * @throws SecurityException If the app has been configured to crash on this op.
1554 */
1555 public int noteOp(String op, int uid, String packageName) {
1556 return noteOp(strOpToOp(op), uid, packageName);
1557 }
1558
1559 /**
1560 * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
1561 * returns {@link #MODE_ERRORED}.
1562 */
1563 public int noteOpNoThrow(String op, int uid, String packageName) {
1564 return noteOpNoThrow(strOpToOp(op), uid, packageName);
1565 }
1566
1567 /**
Svet Ganov99b60432015-06-27 13:15:22 -07001568 * Make note of an application performing an operation on behalf of another
1569 * application when handling an IPC. Note that you must pass the package name
1570 * of the application that is being proxied while its UID will be inferred from
1571 * the IPC state; this function will verify that the calling uid and proxied
1572 * package name match, and if not, return {@link #MODE_IGNORED}. If this call
1573 * succeeds, the last execution time of the operation for the proxied app and
1574 * your app will be updated to the current time.
1575 * @param op The operation to note. One of the OPSTR_* constants.
1576 * @param proxiedPackageName The name of the application calling into the proxy application.
1577 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1578 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1579 * causing the app to crash).
1580 * @throws SecurityException If the app has been configured to crash on this op.
1581 */
1582 public int noteProxyOp(String op, String proxiedPackageName) {
1583 return noteProxyOp(strOpToOp(op), proxiedPackageName);
1584 }
1585
1586 /**
1587 * Like {@link #noteProxyOp(String, String)} but instead
1588 * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
1589 */
1590 public int noteProxyOpNoThrow(String op, String proxiedPackageName) {
1591 return noteProxyOpNoThrow(strOpToOp(op), proxiedPackageName);
1592 }
1593
1594 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001595 * Report that an application has started executing a long-running operation. Note that you
1596 * must pass in both the uid and name of the application to be checked; this function will
1597 * verify that these two match, and if not, return {@link #MODE_IGNORED}. If this call
1598 * succeeds, the last execution time of the operation for this app will be updated to
1599 * the current time and the operation will be marked as "running". In this case you must
1600 * later call {@link #finishOp(String, int, String)} to report when the application is no
1601 * longer performing the operation.
1602 * @param op The operation to start. One of the OPSTR_* constants.
1603 * @param uid The user id of the application attempting to perform the operation.
1604 * @param packageName The name of the application attempting to perform the operation.
1605 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1606 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1607 * causing the app to crash).
1608 * @throws SecurityException If the app has been configured to crash on this op.
1609 */
1610 public int startOp(String op, int uid, String packageName) {
1611 return startOp(strOpToOp(op), uid, packageName);
1612 }
1613
1614 /**
1615 * Like {@link #startOp} but instead of throwing a {@link SecurityException} it
1616 * returns {@link #MODE_ERRORED}.
1617 */
1618 public int startOpNoThrow(String op, int uid, String packageName) {
1619 return startOpNoThrow(strOpToOp(op), uid, packageName);
1620 }
1621
1622 /**
1623 * Report that an application is no longer performing an operation that had previously
1624 * been started with {@link #startOp(String, int, String)}. There is no validation of input
1625 * or result; the parameters supplied here must be the exact same ones previously passed
1626 * in when starting the operation.
1627 */
1628 public void finishOp(String op, int uid, String packageName) {
1629 finishOp(strOpToOp(op), uid, packageName);
1630 }
1631
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001632 /**
1633 * Do a quick check for whether an application might be able to perform an operation.
1634 * This is <em>not</em> a security check; you must use {@link #noteOp(int, int, String)}
1635 * or {@link #startOp(int, int, String)} for your actual security checks, which also
1636 * ensure that the given uid and package name are consistent. This function can just be
1637 * used for a quick check to see if an operation has been disabled for the application,
1638 * as an early reject of some work. This does not modify the time stamp or other data
1639 * about the operation.
1640 * @param op The operation to check. One of the OP_* constants.
1641 * @param uid The user id of the application attempting to perform the operation.
1642 * @param packageName The name of the application attempting to perform the operation.
1643 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1644 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1645 * causing the app to crash).
1646 * @throws SecurityException If the app has been configured to crash on this op.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001647 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001648 */
Dianne Hackborn35654b62013-01-14 17:38:02 -08001649 public int checkOp(int op, int uid, String packageName) {
1650 try {
1651 int mode = mService.checkOperation(op, uid, packageName);
1652 if (mode == MODE_ERRORED) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07001653 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborn35654b62013-01-14 17:38:02 -08001654 }
1655 return mode;
1656 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001657 throw e.rethrowFromSystemServer();
Dianne Hackborn35654b62013-01-14 17:38:02 -08001658 }
Dianne Hackborn35654b62013-01-14 17:38:02 -08001659 }
1660
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001661 /**
1662 * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
1663 * returns {@link #MODE_ERRORED}.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001664 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001665 */
Dianne Hackborn35654b62013-01-14 17:38:02 -08001666 public int checkOpNoThrow(int op, int uid, String packageName) {
1667 try {
1668 return mService.checkOperation(op, uid, packageName);
1669 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001670 throw e.rethrowFromSystemServer();
Dianne Hackborn35654b62013-01-14 17:38:02 -08001671 }
Dianne Hackborn35654b62013-01-14 17:38:02 -08001672 }
1673
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001674 /**
Jeff Sharkey911d7f42013-09-05 18:11:45 -07001675 * Do a quick check to validate if a package name belongs to a UID.
1676 *
1677 * @throws SecurityException if the package name doesn't belong to the given
1678 * UID, or if ownership cannot be verified.
1679 */
1680 public void checkPackage(int uid, String packageName) {
1681 try {
1682 if (mService.checkPackage(uid, packageName) != MODE_ALLOWED) {
1683 throw new SecurityException(
1684 "Package " + packageName + " does not belong to " + uid);
1685 }
1686 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001687 throw e.rethrowFromSystemServer();
Jeff Sharkey911d7f42013-09-05 18:11:45 -07001688 }
1689 }
1690
1691 /**
John Spurlock1af30c72014-03-10 08:33:35 -04001692 * Like {@link #checkOp} but at a stream-level for audio operations.
1693 * @hide
1694 */
1695 public int checkAudioOp(int op, int stream, int uid, String packageName) {
1696 try {
1697 final int mode = mService.checkAudioOperation(op, stream, uid, packageName);
1698 if (mode == MODE_ERRORED) {
1699 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
1700 }
1701 return mode;
1702 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001703 throw e.rethrowFromSystemServer();
John Spurlock1af30c72014-03-10 08:33:35 -04001704 }
John Spurlock1af30c72014-03-10 08:33:35 -04001705 }
1706
1707 /**
1708 * Like {@link #checkAudioOp} but instead of throwing a {@link SecurityException} it
1709 * returns {@link #MODE_ERRORED}.
1710 * @hide
1711 */
1712 public int checkAudioOpNoThrow(int op, int stream, int uid, String packageName) {
1713 try {
1714 return mService.checkAudioOperation(op, stream, uid, packageName);
1715 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001716 throw e.rethrowFromSystemServer();
John Spurlock1af30c72014-03-10 08:33:35 -04001717 }
John Spurlock1af30c72014-03-10 08:33:35 -04001718 }
1719
1720 /**
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001721 * Make note of an application performing an operation. Note that you must pass
1722 * in both the uid and name of the application to be checked; this function will verify
1723 * that these two match, and if not, return {@link #MODE_IGNORED}. If this call
1724 * succeeds, the last execution time of the operation for this app will be updated to
1725 * the current time.
1726 * @param op The operation to note. One of the OP_* constants.
1727 * @param uid The user id of the application attempting to perform the operation.
1728 * @param packageName The name of the application attempting to perform the operation.
1729 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1730 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1731 * causing the app to crash).
1732 * @throws SecurityException If the app has been configured to crash on this op.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001733 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001734 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001735 public int noteOp(int op, int uid, String packageName) {
1736 try {
1737 int mode = mService.noteOperation(op, uid, packageName);
1738 if (mode == MODE_ERRORED) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07001739 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001740 }
1741 return mode;
1742 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001743 throw e.rethrowFromSystemServer();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001744 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001745 }
1746
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001747 /**
Svet Ganov99b60432015-06-27 13:15:22 -07001748 * Make note of an application performing an operation on behalf of another
1749 * application when handling an IPC. Note that you must pass the package name
1750 * of the application that is being proxied while its UID will be inferred from
1751 * the IPC state; this function will verify that the calling uid and proxied
1752 * package name match, and if not, return {@link #MODE_IGNORED}. If this call
1753 * succeeds, the last execution time of the operation for the proxied app and
1754 * your app will be updated to the current time.
1755 * @param op The operation to note. One of the OPSTR_* constants.
1756 * @param proxiedPackageName The name of the application calling into the proxy application.
1757 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1758 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1759 * causing the app to crash).
1760 * @throws SecurityException If the proxy or proxied app has been configured to
1761 * crash on this op.
1762 *
1763 * @hide
1764 */
1765 public int noteProxyOp(int op, String proxiedPackageName) {
1766 int mode = noteProxyOpNoThrow(op, proxiedPackageName);
1767 if (mode == MODE_ERRORED) {
1768 throw new SecurityException("Proxy package " + mContext.getOpPackageName()
1769 + " from uid " + Process.myUid() + " or calling package "
1770 + proxiedPackageName + " from uid " + Binder.getCallingUid()
1771 + " not allowed to perform " + sOpNames[op]);
1772 }
1773 return mode;
1774 }
1775
1776 /**
1777 * Like {@link #noteProxyOp(int, String)} but instead
1778 * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
1779 * @hide
1780 */
1781 public int noteProxyOpNoThrow(int op, String proxiedPackageName) {
1782 try {
1783 return mService.noteProxyOperation(op, mContext.getOpPackageName(),
1784 Binder.getCallingUid(), proxiedPackageName);
1785 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001786 throw e.rethrowFromSystemServer();
Svet Ganov99b60432015-06-27 13:15:22 -07001787 }
Svet Ganov99b60432015-06-27 13:15:22 -07001788 }
1789
1790 /**
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001791 * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
1792 * returns {@link #MODE_ERRORED}.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001793 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001794 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001795 public int noteOpNoThrow(int op, int uid, String packageName) {
1796 try {
1797 return mService.noteOperation(op, uid, packageName);
1798 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001799 throw e.rethrowFromSystemServer();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001800 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001801 }
1802
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001803 /** @hide */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001804 public int noteOp(int op) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07001805 return noteOp(op, Process.myUid(), mContext.getOpPackageName());
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001806 }
1807
Dianne Hackborne98f5db2013-07-17 17:23:25 -07001808 /** @hide */
1809 public static IBinder getToken(IAppOpsService service) {
1810 synchronized (AppOpsManager.class) {
1811 if (sToken != null) {
1812 return sToken;
1813 }
1814 try {
1815 sToken = service.getToken(new Binder());
1816 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001817 throw e.rethrowFromSystemServer();
Dianne Hackborne98f5db2013-07-17 17:23:25 -07001818 }
1819 return sToken;
1820 }
1821 }
1822
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001823 /**
1824 * Report that an application has started executing a long-running operation. Note that you
1825 * must pass in both the uid and name of the application to be checked; this function will
1826 * verify that these two match, and if not, return {@link #MODE_IGNORED}. If this call
1827 * succeeds, the last execution time of the operation for this app will be updated to
1828 * the current time and the operation will be marked as "running". In this case you must
1829 * later call {@link #finishOp(int, int, String)} to report when the application is no
1830 * longer performing the operation.
1831 * @param op The operation to start. One of the OP_* constants.
1832 * @param uid The user id of the application attempting to perform the operation.
1833 * @param packageName The name of the application attempting to perform the operation.
1834 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1835 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1836 * causing the app to crash).
1837 * @throws SecurityException If the app has been configured to crash on this op.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001838 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001839 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001840 public int startOp(int op, int uid, String packageName) {
1841 try {
Dianne Hackborne98f5db2013-07-17 17:23:25 -07001842 int mode = mService.startOperation(getToken(mService), op, uid, packageName);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001843 if (mode == MODE_ERRORED) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07001844 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001845 }
1846 return mode;
1847 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001848 throw e.rethrowFromSystemServer();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001849 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001850 }
1851
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001852 /**
1853 * Like {@link #startOp} but instead of throwing a {@link SecurityException} it
1854 * returns {@link #MODE_ERRORED}.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001855 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001856 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001857 public int startOpNoThrow(int op, int uid, String packageName) {
1858 try {
Dianne Hackborne98f5db2013-07-17 17:23:25 -07001859 return mService.startOperation(getToken(mService), op, uid, packageName);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001860 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001861 throw e.rethrowFromSystemServer();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001862 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001863 }
1864
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001865 /** @hide */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001866 public int startOp(int op) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07001867 return startOp(op, Process.myUid(), mContext.getOpPackageName());
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001868 }
1869
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001870 /**
1871 * Report that an application is no longer performing an operation that had previously
1872 * been started with {@link #startOp(int, int, String)}. There is no validation of input
1873 * or result; the parameters supplied here must be the exact same ones previously passed
1874 * in when starting the operation.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001875 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001876 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001877 public void finishOp(int op, int uid, String packageName) {
1878 try {
Dianne Hackborne98f5db2013-07-17 17:23:25 -07001879 mService.finishOperation(getToken(mService), op, uid, packageName);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001880 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001881 throw e.rethrowFromSystemServer();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001882 }
1883 }
1884
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001885 /** @hide */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001886 public void finishOp(int op) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07001887 finishOp(op, Process.myUid(), mContext.getOpPackageName());
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001888 }
1889}