blob: 3fb50dbc4951b0c20959a0c2d44c4507bf99275a [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
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700108 // - add rows to sOpToSwitch, sOpToString, sOpNames, sOpPerms, sOpDefaultMode
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;
Jason Monk1c7c3192014-06-26 12:52:18 -0400236 /** @hide */
Svet Ganov921c7df2015-06-29 21:51:41 -0700237 public static final int _NUM_OP = 61;
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800238
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700239 /** Access to coarse location information. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700240 public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700241 /** Access to fine location information. */
242 public static final String OPSTR_FINE_LOCATION =
243 "android:fine_location";
244 /** Continually monitoring location data. */
245 public static final String OPSTR_MONITOR_LOCATION
246 = "android:monitor_location";
247 /** Continually monitoring location data with a relatively high power request. */
248 public static final String OPSTR_MONITOR_HIGH_POWER_LOCATION
249 = "android:monitor_location_high_power";
Dianne Hackborn5064e7c2014-09-02 10:57:16 -0700250 /** Access to {@link android.app.usage.UsageStatsManager}. */
251 public static final String OPSTR_GET_USAGE_STATS
252 = "android:get_usage_stats";
Jeff Davidson05542602014-08-11 14:07:27 -0700253 /** Activate a VPN connection without user intervention. @hide */
254 @SystemApi
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700255 public static final String OPSTR_ACTIVATE_VPN
256 = "android:activate_vpn";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700257 /** Allows an application to read the user's contacts data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700258 public static final String OPSTR_READ_CONTACTS
259 = "android:read_contacts";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700260 /** Allows an application to write to the user's contacts data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700261 public static final String OPSTR_WRITE_CONTACTS
262 = "android:write_contacts";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700263 /** Allows an application to read the user's call log. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700264 public static final String OPSTR_READ_CALL_LOG
265 = "android:read_call_log";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700266 /** Allows an application to write to the user's call log. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700267 public static final String OPSTR_WRITE_CALL_LOG
268 = "android:write_call_log";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700269 /** Allows an application to read the user's calendar data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700270 public static final String OPSTR_READ_CALENDAR
271 = "android:read_calendar";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700272 /** Allows an application to write to the user's calendar data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700273 public static final String OPSTR_WRITE_CALENDAR
274 = "android:write_calendar";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700275 /** Allows an application to initiate a phone call. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700276 public static final String OPSTR_CALL_PHONE
277 = "android:call_phone";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700278 /** Allows an application to read SMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700279 public static final String OPSTR_READ_SMS
280 = "android:read_sms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700281 /** Allows an application to receive SMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700282 public static final String OPSTR_RECEIVE_SMS
283 = "android:receive_sms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700284 /** Allows an application to receive MMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700285 public static final String OPSTR_RECEIVE_MMS
286 = "android:receive_mms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700287 /** Allows an application to receive WAP push messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700288 public static final String OPSTR_RECEIVE_WAP_PUSH
289 = "android:receive_wap_push";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700290 /** Allows an application to send SMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700291 public static final String OPSTR_SEND_SMS
292 = "android:send_sms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700293 /** Required to be able to access the camera device. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700294 public static final String OPSTR_CAMERA
295 = "android:camera";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700296 /** Required to be able to access the microphone device. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700297 public static final String OPSTR_RECORD_AUDIO
298 = "android:record_audio";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700299 /** Required to access phone state related information. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700300 public static final String OPSTR_READ_PHONE_STATE
301 = "android:read_phone_state";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700302 /** Required to access phone state related information. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700303 public static final String OPSTR_ADD_VOICEMAIL
304 = "android:add_voicemail";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700305 /** Access APIs for SIP calling over VOIP or WiFi */
Svet Ganovb9d71a62015-04-30 10:38:13 -0700306 public static final String OPSTR_USE_SIP
307 = "android:use_sip";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700308 /** Use the fingerprint API. */
Svet Ganovb9d71a62015-04-30 10:38:13 -0700309 public static final String OPSTR_USE_FINGERPRINT
310 = "android:use_fingerprint";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700311 /** Access to body sensors such as heart rate, etc. */
Svet Ganovb9d71a62015-04-30 10:38:13 -0700312 public static final String OPSTR_BODY_SENSORS
313 = "android:body_sensors";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700314 /** Read previously received cell broadcast messages. */
Svet Ganovede43162015-05-02 17:42:44 -0700315 public static final String OPSTR_READ_CELL_BROADCASTS
316 = "android:read_cell_broadcasts";
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700317 /** Inject mock location into the system. */
318 public static final String OPSTR_MOCK_LOCATION
319 = "android:mock_location";
Svet Ganov921c7df2015-06-29 21:51:41 -0700320 /** Read external storage. */
321 public static final String OPSTR_READ_EXTERNAL_STORAGE
322 = "android:read_external_storage";
323 /** Write external storage. */
324 public static final String OPSTR_WRITE_EXTERNAL_STORAGE
325 = "android:write_external_storage";
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700326
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800327 /**
328 * This maps each operation to the operation that serves as the
329 * switch to determine whether it is allowed. Generally this is
330 * a 1:1 mapping, but for some things (like location) that have
331 * multiple low-level operations being tracked that should be
David Christie0b837452013-07-29 16:02:13 -0700332 * presented to the user as one switch then this can be used to
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800333 * make them all controlled by the same single operation.
334 */
335 private static int[] sOpToSwitch = new int[] {
336 OP_COARSE_LOCATION,
337 OP_COARSE_LOCATION,
338 OP_COARSE_LOCATION,
339 OP_VIBRATE,
340 OP_READ_CONTACTS,
341 OP_WRITE_CONTACTS,
342 OP_READ_CALL_LOG,
343 OP_WRITE_CALL_LOG,
344 OP_READ_CALENDAR,
345 OP_WRITE_CALENDAR,
346 OP_COARSE_LOCATION,
347 OP_POST_NOTIFICATION,
348 OP_COARSE_LOCATION,
349 OP_CALL_PHONE,
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800350 OP_READ_SMS,
351 OP_WRITE_SMS,
David Braun18966a82013-09-10 13:14:46 -0700352 OP_RECEIVE_SMS,
353 OP_RECEIVE_SMS,
354 OP_RECEIVE_SMS,
355 OP_RECEIVE_SMS,
356 OP_SEND_SMS,
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800357 OP_READ_SMS,
358 OP_WRITE_SMS,
Dianne Hackborn961321f2013-02-05 17:22:41 -0800359 OP_WRITE_SETTINGS,
Dianne Hackbornc2293022013-02-06 23:14:49 -0800360 OP_SYSTEM_ALERT_WINDOW,
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500361 OP_ACCESS_NOTIFICATIONS,
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800362 OP_CAMERA,
363 OP_RECORD_AUDIO,
364 OP_PLAY_AUDIO,
Dianne Hackbornefcc1a22013-02-25 18:02:35 -0800365 OP_READ_CLIPBOARD,
366 OP_WRITE_CLIPBOARD,
Dianne Hackbornba50b97c2013-04-30 15:04:46 -0700367 OP_TAKE_MEDIA_BUTTONS,
368 OP_TAKE_AUDIO_FOCUS,
369 OP_AUDIO_MASTER_VOLUME,
370 OP_AUDIO_VOICE_VOLUME,
371 OP_AUDIO_RING_VOLUME,
372 OP_AUDIO_MEDIA_VOLUME,
373 OP_AUDIO_ALARM_VOLUME,
374 OP_AUDIO_NOTIFICATION_VOLUME,
375 OP_AUDIO_BLUETOOTH_VOLUME,
Dianne Hackborn713df152013-05-17 11:27:57 -0700376 OP_WAKE_LOCK,
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700377 OP_COARSE_LOCATION,
David Christie0b837452013-07-29 16:02:13 -0700378 OP_COARSE_LOCATION,
Dianne Hackborne22b3b12014-05-07 18:06:44 -0700379 OP_GET_USAGE_STATS,
Jason Monk1c7c3192014-06-26 12:52:18 -0400380 OP_MUTE_MICROPHONE,
381 OP_TOAST_WINDOW,
Michael Wrightc39d47a2014-07-08 18:07:36 -0700382 OP_PROJECT_MEDIA,
Jeff Davidson05542602014-08-11 14:07:27 -0700383 OP_ACTIVATE_VPN,
Benjamin Franzf3ece362015-02-11 10:51:10 +0000384 OP_WRITE_WALLPAPER,
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700385 OP_ASSIST_STRUCTURE,
386 OP_ASSIST_SCREENSHOT,
Svet Ganovc3300092015-04-17 09:07:22 -0700387 OP_READ_PHONE_STATE,
Svetoslav5335b672015-04-29 12:00:51 -0700388 OP_ADD_VOICEMAIL,
Svetoslavc656e6f2015-04-29 14:08:16 -0700389 OP_USE_SIP,
Svetoslav4af76a52015-04-29 15:29:46 -0700390 OP_PROCESS_OUTGOING_CALLS,
Svet Ganovb9d71a62015-04-30 10:38:13 -0700391 OP_USE_FINGERPRINT,
Svet Ganovede43162015-05-02 17:42:44 -0700392 OP_BODY_SENSORS,
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700393 OP_READ_CELL_BROADCASTS,
Svet Ganov921c7df2015-06-29 21:51:41 -0700394 OP_MOCK_LOCATION,
395 OP_READ_EXTERNAL_STORAGE,
396 OP_WRITE_EXTERNAL_STORAGE
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800397 };
398
399 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700400 * This maps each operation to the public string constant for it.
401 * If it doesn't have a public string constant, it maps to null.
402 */
403 private static String[] sOpToString = new String[] {
404 OPSTR_COARSE_LOCATION,
405 OPSTR_FINE_LOCATION,
406 null,
407 null,
Svet Ganovb9d71a62015-04-30 10:38:13 -0700408 OPSTR_READ_CONTACTS,
409 OPSTR_WRITE_CONTACTS,
410 OPSTR_READ_CALL_LOG,
411 OPSTR_WRITE_CALL_LOG,
412 OPSTR_READ_CALENDAR,
413 OPSTR_WRITE_CALENDAR,
414 null,
415 null,
416 null,
417 OPSTR_CALL_PHONE,
418 OPSTR_READ_SMS,
419 null,
420 OPSTR_RECEIVE_SMS,
421 null,
422 OPSTR_RECEIVE_MMS,
423 OPSTR_RECEIVE_WAP_PUSH,
424 OPSTR_SEND_SMS,
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700425 null,
426 null,
427 null,
428 null,
429 null,
Svet Ganovb9d71a62015-04-30 10:38:13 -0700430 OPSTR_CAMERA,
431 OPSTR_RECORD_AUDIO,
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700432 null,
433 null,
434 null,
435 null,
436 null,
437 null,
438 null,
439 null,
440 null,
441 null,
442 null,
443 null,
444 null,
445 OPSTR_MONITOR_LOCATION,
446 OPSTR_MONITOR_HIGH_POWER_LOCATION,
Dianne Hackborn5064e7c2014-09-02 10:57:16 -0700447 OPSTR_GET_USAGE_STATS,
Emily Bernier22c921a2014-05-28 11:01:32 -0400448 null,
Jason Monk1c7c3192014-06-26 12:52:18 -0400449 null,
Michael Wrightc39d47a2014-07-08 18:07:36 -0700450 null,
Jeff Davidson05542602014-08-11 14:07:27 -0700451 OPSTR_ACTIVATE_VPN,
Benjamin Franzf3ece362015-02-11 10:51:10 +0000452 null,
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700453 null,
454 null,
Svet Ganovb9d71a62015-04-30 10:38:13 -0700455 OPSTR_READ_PHONE_STATE,
456 OPSTR_ADD_VOICEMAIL,
457 OPSTR_USE_SIP,
Svet Ganovc3300092015-04-17 09:07:22 -0700458 null,
Svet Ganovb9d71a62015-04-30 10:38:13 -0700459 OPSTR_USE_FINGERPRINT,
Svet Ganovede43162015-05-02 17:42:44 -0700460 OPSTR_BODY_SENSORS,
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700461 OPSTR_READ_CELL_BROADCASTS,
Svet Ganov921c7df2015-06-29 21:51:41 -0700462 OPSTR_MOCK_LOCATION,
463 OPSTR_READ_EXTERNAL_STORAGE,
464 OPSTR_WRITE_EXTERNAL_STORAGE
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700465 };
466
467 /**
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800468 * This provides a simple name for each operation to be used
469 * in debug output.
470 */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800471 private static String[] sOpNames = new String[] {
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800472 "COARSE_LOCATION",
473 "FINE_LOCATION",
474 "GPS",
475 "VIBRATE",
476 "READ_CONTACTS",
477 "WRITE_CONTACTS",
478 "READ_CALL_LOG",
479 "WRITE_CALL_LOG",
480 "READ_CALENDAR",
481 "WRITE_CALENDAR",
482 "WIFI_SCAN",
483 "POST_NOTIFICATION",
484 "NEIGHBORING_CELLS",
485 "CALL_PHONE",
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800486 "READ_SMS",
487 "WRITE_SMS",
488 "RECEIVE_SMS",
489 "RECEIVE_EMERGECY_SMS",
490 "RECEIVE_MMS",
491 "RECEIVE_WAP_PUSH",
492 "SEND_SMS",
493 "READ_ICC_SMS",
494 "WRITE_ICC_SMS",
Dianne Hackborn961321f2013-02-05 17:22:41 -0800495 "WRITE_SETTINGS",
Dianne Hackbornc2293022013-02-06 23:14:49 -0800496 "SYSTEM_ALERT_WINDOW",
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500497 "ACCESS_NOTIFICATIONS",
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800498 "CAMERA",
499 "RECORD_AUDIO",
500 "PLAY_AUDIO",
Dianne Hackbornefcc1a22013-02-25 18:02:35 -0800501 "READ_CLIPBOARD",
502 "WRITE_CLIPBOARD",
Dianne Hackbornba50b97c2013-04-30 15:04:46 -0700503 "TAKE_MEDIA_BUTTONS",
504 "TAKE_AUDIO_FOCUS",
505 "AUDIO_MASTER_VOLUME",
506 "AUDIO_VOICE_VOLUME",
507 "AUDIO_RING_VOLUME",
508 "AUDIO_MEDIA_VOLUME",
509 "AUDIO_ALARM_VOLUME",
510 "AUDIO_NOTIFICATION_VOLUME",
511 "AUDIO_BLUETOOTH_VOLUME",
Dianne Hackborn713df152013-05-17 11:27:57 -0700512 "WAKE_LOCK",
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700513 "MONITOR_LOCATION",
David Christie0b837452013-07-29 16:02:13 -0700514 "MONITOR_HIGH_POWER_LOCATION",
Emily Bernier22c921a2014-05-28 11:01:32 -0400515 "GET_USAGE_STATS",
Michael Wrightc39d47a2014-07-08 18:07:36 -0700516 "MUTE_MICROPHONE",
Jason Monk1c7c3192014-06-26 12:52:18 -0400517 "TOAST_WINDOW",
Michael Wrightc39d47a2014-07-08 18:07:36 -0700518 "PROJECT_MEDIA",
Jeff Davidson05542602014-08-11 14:07:27 -0700519 "ACTIVATE_VPN",
Benjamin Franzf3ece362015-02-11 10:51:10 +0000520 "WRITE_WALLPAPER",
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700521 "ASSIST_STRUCTURE",
Svet Ganov16a16892015-04-16 10:32:04 -0700522 "ASSIST_SCREENSHOT",
Svet Ganovc3300092015-04-17 09:07:22 -0700523 "OP_READ_PHONE_STATE",
Svetoslav5335b672015-04-29 12:00:51 -0700524 "ADD_VOICEMAIL",
Svetoslavc656e6f2015-04-29 14:08:16 -0700525 "USE_SIP",
Svetoslav4af76a52015-04-29 15:29:46 -0700526 "PROCESS_OUTGOING_CALLS",
Svet Ganovb9d71a62015-04-30 10:38:13 -0700527 "USE_FINGERPRINT",
Svet Ganovede43162015-05-02 17:42:44 -0700528 "BODY_SENSORS",
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700529 "READ_CELL_BROADCASTS",
Svet Ganov921c7df2015-06-29 21:51:41 -0700530 "MOCK_LOCATION",
531 "OPSTR_READ_EXTERNAL_STORAGE",
532 "OPSTR_WRITE_EXTERNAL_STORAGE",
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800533 };
534
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800535 /**
536 * This optionally maps a permission to an operation. If there
537 * is no permission associated with an operation, it is null.
538 */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800539 private static String[] sOpPerms = new String[] {
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800540 android.Manifest.permission.ACCESS_COARSE_LOCATION,
541 android.Manifest.permission.ACCESS_FINE_LOCATION,
542 null,
543 android.Manifest.permission.VIBRATE,
544 android.Manifest.permission.READ_CONTACTS,
545 android.Manifest.permission.WRITE_CONTACTS,
546 android.Manifest.permission.READ_CALL_LOG,
547 android.Manifest.permission.WRITE_CALL_LOG,
548 android.Manifest.permission.READ_CALENDAR,
549 android.Manifest.permission.WRITE_CALENDAR,
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800550 android.Manifest.permission.ACCESS_WIFI_STATE,
Robert Craigf97616c2013-10-07 12:32:02 -0400551 null, // no permission required for notifications
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800552 null, // neighboring cells shares the coarse location perm
553 android.Manifest.permission.CALL_PHONE,
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800554 android.Manifest.permission.READ_SMS,
Svetoslav6c589572015-04-16 16:19:24 -0700555 null, // no permission required for writing sms
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800556 android.Manifest.permission.RECEIVE_SMS,
557 android.Manifest.permission.RECEIVE_EMERGENCY_BROADCAST,
558 android.Manifest.permission.RECEIVE_MMS,
559 android.Manifest.permission.RECEIVE_WAP_PUSH,
560 android.Manifest.permission.SEND_SMS,
561 android.Manifest.permission.READ_SMS,
Svetoslav6c589572015-04-16 16:19:24 -0700562 null, // no permission required for writing icc sms
Dianne Hackborn961321f2013-02-05 17:22:41 -0800563 android.Manifest.permission.WRITE_SETTINGS,
Dianne Hackbornc2293022013-02-06 23:14:49 -0800564 android.Manifest.permission.SYSTEM_ALERT_WINDOW,
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500565 android.Manifest.permission.ACCESS_NOTIFICATIONS,
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800566 android.Manifest.permission.CAMERA,
567 android.Manifest.permission.RECORD_AUDIO,
568 null, // no permission for playing audio
Dianne Hackbornefcc1a22013-02-25 18:02:35 -0800569 null, // no permission for reading clipboard
570 null, // no permission for writing clipboard
Dianne Hackbornba50b97c2013-04-30 15:04:46 -0700571 null, // no permission for taking media buttons
572 null, // no permission for taking audio focus
573 null, // no permission for changing master volume
574 null, // no permission for changing voice volume
575 null, // no permission for changing ring volume
576 null, // no permission for changing media volume
577 null, // no permission for changing alarm volume
578 null, // no permission for changing notification volume
579 null, // no permission for changing bluetooth volume
Dianne Hackborn713df152013-05-17 11:27:57 -0700580 android.Manifest.permission.WAKE_LOCK,
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700581 null, // no permission for generic location monitoring
David Christie0b837452013-07-29 16:02:13 -0700582 null, // no permission for high power location monitoring
Dianne Hackborne22b3b12014-05-07 18:06:44 -0700583 android.Manifest.permission.PACKAGE_USAGE_STATS,
Emily Bernier22c921a2014-05-28 11:01:32 -0400584 null, // no permission for muting/unmuting microphone
Jason Monk1c7c3192014-06-26 12:52:18 -0400585 null, // no permission for displaying toasts
Michael Wrightc39d47a2014-07-08 18:07:36 -0700586 null, // no permission for projecting media
Jeff Davidson05542602014-08-11 14:07:27 -0700587 null, // no permission for activating vpn
Benjamin Franzf3ece362015-02-11 10:51:10 +0000588 null, // no permission for supporting wallpaper
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700589 null, // no permission for receiving assist structure
590 null, // no permission for receiving assist screenshot
Svet Ganovc3300092015-04-17 09:07:22 -0700591 Manifest.permission.READ_PHONE_STATE,
Svetoslav5335b672015-04-29 12:00:51 -0700592 Manifest.permission.ADD_VOICEMAIL,
Svetoslavc656e6f2015-04-29 14:08:16 -0700593 Manifest.permission.USE_SIP,
Svetoslav4af76a52015-04-29 15:29:46 -0700594 Manifest.permission.PROCESS_OUTGOING_CALLS,
Svet Ganovb9d71a62015-04-30 10:38:13 -0700595 Manifest.permission.USE_FINGERPRINT,
Svet Ganovede43162015-05-02 17:42:44 -0700596 Manifest.permission.BODY_SENSORS,
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700597 Manifest.permission.READ_CELL_BROADCASTS,
Svet Ganov921c7df2015-06-29 21:51:41 -0700598 null,
599 Manifest.permission.READ_EXTERNAL_STORAGE,
600 Manifest.permission.WRITE_EXTERNAL_STORAGE,
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800601 };
602
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800603 /**
Jason Monk62062992014-05-06 09:55:28 -0400604 * Specifies whether an Op should be restricted by a user restriction.
605 * Each Op should be filled with a restriction string from UserManager or
606 * null to specify it is not affected by any user restriction.
607 */
608 private static String[] sOpRestrictions = new String[] {
Julia Reynolds9854d572014-07-02 14:46:02 -0400609 UserManager.DISALLOW_SHARE_LOCATION, //COARSE_LOCATION
610 UserManager.DISALLOW_SHARE_LOCATION, //FINE_LOCATION
611 UserManager.DISALLOW_SHARE_LOCATION, //GPS
Jason Monk62062992014-05-06 09:55:28 -0400612 null, //VIBRATE
613 null, //READ_CONTACTS
614 null, //WRITE_CONTACTS
Yorke Lee15f83c62014-08-13 14:14:29 -0700615 UserManager.DISALLOW_OUTGOING_CALLS, //READ_CALL_LOG
616 UserManager.DISALLOW_OUTGOING_CALLS, //WRITE_CALL_LOG
Jason Monk62062992014-05-06 09:55:28 -0400617 null, //READ_CALENDAR
618 null, //WRITE_CALENDAR
Julia Reynolds9854d572014-07-02 14:46:02 -0400619 UserManager.DISALLOW_SHARE_LOCATION, //WIFI_SCAN
Jason Monk62062992014-05-06 09:55:28 -0400620 null, //POST_NOTIFICATION
621 null, //NEIGHBORING_CELLS
622 null, //CALL_PHONE
Amith Yamasani41c1ded2014-08-05 11:15:05 -0700623 UserManager.DISALLOW_SMS, //READ_SMS
624 UserManager.DISALLOW_SMS, //WRITE_SMS
625 UserManager.DISALLOW_SMS, //RECEIVE_SMS
626 null, //RECEIVE_EMERGENCY_SMS
627 UserManager.DISALLOW_SMS, //RECEIVE_MMS
Jason Monk62062992014-05-06 09:55:28 -0400628 null, //RECEIVE_WAP_PUSH
Amith Yamasani41c1ded2014-08-05 11:15:05 -0700629 UserManager.DISALLOW_SMS, //SEND_SMS
630 UserManager.DISALLOW_SMS, //READ_ICC_SMS
631 UserManager.DISALLOW_SMS, //WRITE_ICC_SMS
Jason Monk62062992014-05-06 09:55:28 -0400632 null, //WRITE_SETTINGS
Jason Monk1c7c3192014-06-26 12:52:18 -0400633 UserManager.DISALLOW_CREATE_WINDOWS, //SYSTEM_ALERT_WINDOW
Jason Monk62062992014-05-06 09:55:28 -0400634 null, //ACCESS_NOTIFICATIONS
635 null, //CAMERA
Fyodor Kupolovb5013302015-04-17 17:59:14 -0700636 UserManager.DISALLOW_RECORD_AUDIO, //RECORD_AUDIO
Jason Monk62062992014-05-06 09:55:28 -0400637 null, //PLAY_AUDIO
638 null, //READ_CLIPBOARD
639 null, //WRITE_CLIPBOARD
640 null, //TAKE_MEDIA_BUTTONS
641 null, //TAKE_AUDIO_FOCUS
Emily Bernier45775c42014-05-16 15:12:04 -0400642 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MASTER_VOLUME
643 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_VOICE_VOLUME
644 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_RING_VOLUME
645 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MEDIA_VOLUME
646 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ALARM_VOLUME
647 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_NOTIFICATION_VOLUME
648 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_BLUETOOTH_VOLUME
Jason Monk62062992014-05-06 09:55:28 -0400649 null, //WAKE_LOCK
Julia Reynolds9854d572014-07-02 14:46:02 -0400650 UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_LOCATION
651 UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_HIGH_POWER_LOCATION
Jason Monk62062992014-05-06 09:55:28 -0400652 null, //GET_USAGE_STATS
Emily Bernier22c921a2014-05-28 11:01:32 -0400653 UserManager.DISALLOW_UNMUTE_MICROPHONE, // MUTE_MICROPHONE
Jason Monk1c7c3192014-06-26 12:52:18 -0400654 UserManager.DISALLOW_CREATE_WINDOWS, // TOAST_WINDOW
Michael Wrightc39d47a2014-07-08 18:07:36 -0700655 null, //PROJECT_MEDIA
Jeff Davidson05542602014-08-11 14:07:27 -0700656 UserManager.DISALLOW_CONFIG_VPN, // ACTIVATE_VPN
Benjamin Franzf3ece362015-02-11 10:51:10 +0000657 UserManager.DISALLOW_WALLPAPER, // WRITE_WALLPAPER
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700658 null, // ASSIST_STRUCTURE
659 null, // ASSIST_SCREENSHOT
Svet Ganovc3300092015-04-17 09:07:22 -0700660 null, // READ_PHONE_STATE
Svetoslav5335b672015-04-29 12:00:51 -0700661 null, // ADD_VOICEMAIL
Svetoslavc656e6f2015-04-29 14:08:16 -0700662 null, // USE_SIP
Svetoslav4af76a52015-04-29 15:29:46 -0700663 null, // PROCESS_OUTGOING_CALLS
Svet Ganovb9d71a62015-04-30 10:38:13 -0700664 null, // USE_FINGERPRINT
Svet Ganovede43162015-05-02 17:42:44 -0700665 null, // BODY_SENSORS
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700666 null, // READ_CELL_BROADCASTS
Svet Ganov921c7df2015-06-29 21:51:41 -0700667 null, // MOCK_LOCATION
668 null, // READ_EXTERNAL_STORAGE
669 null // WRITE_EXTERNAL_STORAGE
Jason Monk1c7c3192014-06-26 12:52:18 -0400670 };
671
672 /**
673 * This specifies whether each option should allow the system
674 * (and system ui) to bypass the user restriction when active.
675 */
676 private static boolean[] sOpAllowSystemRestrictionBypass = new boolean[] {
677 false, //COARSE_LOCATION
678 false, //FINE_LOCATION
679 false, //GPS
680 false, //VIBRATE
681 false, //READ_CONTACTS
682 false, //WRITE_CONTACTS
683 false, //READ_CALL_LOG
684 false, //WRITE_CALL_LOG
685 false, //READ_CALENDAR
686 false, //WRITE_CALENDAR
Julia Reynolds9854d572014-07-02 14:46:02 -0400687 true, //WIFI_SCAN
Jason Monk1c7c3192014-06-26 12:52:18 -0400688 false, //POST_NOTIFICATION
689 false, //NEIGHBORING_CELLS
690 false, //CALL_PHONE
691 false, //READ_SMS
692 false, //WRITE_SMS
693 false, //RECEIVE_SMS
694 false, //RECEIVE_EMERGECY_SMS
695 false, //RECEIVE_MMS
696 false, //RECEIVE_WAP_PUSH
697 false, //SEND_SMS
698 false, //READ_ICC_SMS
699 false, //WRITE_ICC_SMS
700 false, //WRITE_SETTINGS
701 true, //SYSTEM_ALERT_WINDOW
702 false, //ACCESS_NOTIFICATIONS
703 false, //CAMERA
704 false, //RECORD_AUDIO
705 false, //PLAY_AUDIO
706 false, //READ_CLIPBOARD
707 false, //WRITE_CLIPBOARD
708 false, //TAKE_MEDIA_BUTTONS
709 false, //TAKE_AUDIO_FOCUS
710 false, //AUDIO_MASTER_VOLUME
711 false, //AUDIO_VOICE_VOLUME
712 false, //AUDIO_RING_VOLUME
713 false, //AUDIO_MEDIA_VOLUME
714 false, //AUDIO_ALARM_VOLUME
715 false, //AUDIO_NOTIFICATION_VOLUME
716 false, //AUDIO_BLUETOOTH_VOLUME
717 false, //WAKE_LOCK
718 false, //MONITOR_LOCATION
719 false, //MONITOR_HIGH_POWER_LOCATION
720 false, //GET_USAGE_STATS
Michael Wrightc39d47a2014-07-08 18:07:36 -0700721 false, //MUTE_MICROPHONE
722 true, //TOAST_WINDOW
723 false, //PROJECT_MEDIA
Jeff Davidson05542602014-08-11 14:07:27 -0700724 false, //ACTIVATE_VPN
Benjamin Franzf3ece362015-02-11 10:51:10 +0000725 false, //WALLPAPER
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700726 false, //ASSIST_STRUCTURE
727 false, //ASSIST_SCREENSHOT
Svet Ganov16a16892015-04-16 10:32:04 -0700728 false, //READ_PHONE_STATE
Svetoslav5335b672015-04-29 12:00:51 -0700729 false, //ADD_VOICEMAIL
Svetoslavc656e6f2015-04-29 14:08:16 -0700730 false, // USE_SIP
Svetoslav4af76a52015-04-29 15:29:46 -0700731 false, // PROCESS_OUTGOING_CALLS
Svet Ganovb9d71a62015-04-30 10:38:13 -0700732 false, // USE_FINGERPRINT
Svet Ganovede43162015-05-02 17:42:44 -0700733 false, // BODY_SENSORS
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700734 false, // READ_CELL_BROADCASTS
Svet Ganov921c7df2015-06-29 21:51:41 -0700735 false, // MOCK_LOCATION
736 false, // READ_EXTERNAL_STORAGE
737 false // WRITE_EXTERNAL_STORAGE
Jason Monk62062992014-05-06 09:55:28 -0400738 };
739
740 /**
David Braunf5d83192013-09-16 13:43:51 -0700741 * This specifies the default mode for each operation.
742 */
743 private static int[] sOpDefaultMode = new int[] {
744 AppOpsManager.MODE_ALLOWED,
745 AppOpsManager.MODE_ALLOWED,
746 AppOpsManager.MODE_ALLOWED,
747 AppOpsManager.MODE_ALLOWED,
748 AppOpsManager.MODE_ALLOWED,
749 AppOpsManager.MODE_ALLOWED,
750 AppOpsManager.MODE_ALLOWED,
751 AppOpsManager.MODE_ALLOWED,
752 AppOpsManager.MODE_ALLOWED,
753 AppOpsManager.MODE_ALLOWED,
754 AppOpsManager.MODE_ALLOWED,
755 AppOpsManager.MODE_ALLOWED,
756 AppOpsManager.MODE_ALLOWED,
757 AppOpsManager.MODE_ALLOWED,
758 AppOpsManager.MODE_ALLOWED,
759 AppOpsManager.MODE_IGNORED, // OP_WRITE_SMS
760 AppOpsManager.MODE_ALLOWED,
761 AppOpsManager.MODE_ALLOWED,
762 AppOpsManager.MODE_ALLOWED,
763 AppOpsManager.MODE_ALLOWED,
764 AppOpsManager.MODE_ALLOWED,
765 AppOpsManager.MODE_ALLOWED,
766 AppOpsManager.MODE_ALLOWED,
767 AppOpsManager.MODE_ALLOWED,
Billy Lau060275f2015-07-15 22:29:19 +0100768 AppOpsManager.MODE_DEFAULT, // OP_SYSTEM_ALERT_WINDOW
David Braunf5d83192013-09-16 13:43:51 -0700769 AppOpsManager.MODE_ALLOWED,
770 AppOpsManager.MODE_ALLOWED,
771 AppOpsManager.MODE_ALLOWED,
772 AppOpsManager.MODE_ALLOWED,
773 AppOpsManager.MODE_ALLOWED,
774 AppOpsManager.MODE_ALLOWED,
775 AppOpsManager.MODE_ALLOWED,
776 AppOpsManager.MODE_ALLOWED,
777 AppOpsManager.MODE_ALLOWED,
778 AppOpsManager.MODE_ALLOWED,
779 AppOpsManager.MODE_ALLOWED,
780 AppOpsManager.MODE_ALLOWED,
781 AppOpsManager.MODE_ALLOWED,
782 AppOpsManager.MODE_ALLOWED,
783 AppOpsManager.MODE_ALLOWED,
784 AppOpsManager.MODE_ALLOWED,
785 AppOpsManager.MODE_ALLOWED,
786 AppOpsManager.MODE_ALLOWED,
Dianne Hackborn33f5ddd2014-07-21 15:35:45 -0700787 AppOpsManager.MODE_DEFAULT, // OP_GET_USAGE_STATS
Emily Bernier22c921a2014-05-28 11:01:32 -0400788 AppOpsManager.MODE_ALLOWED,
Jason Monk1c7c3192014-06-26 12:52:18 -0400789 AppOpsManager.MODE_ALLOWED,
Michael Wrightc39d47a2014-07-08 18:07:36 -0700790 AppOpsManager.MODE_IGNORED, // OP_PROJECT_MEDIA
Jeff Davidson05542602014-08-11 14:07:27 -0700791 AppOpsManager.MODE_IGNORED, // OP_ACTIVATE_VPN
Benjamin Franzf3ece362015-02-11 10:51:10 +0000792 AppOpsManager.MODE_ALLOWED,
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700793 AppOpsManager.MODE_ALLOWED,
794 AppOpsManager.MODE_ALLOWED,
Svet Ganovc3300092015-04-17 09:07:22 -0700795 AppOpsManager.MODE_ALLOWED,
Svetoslav5335b672015-04-29 12:00:51 -0700796 AppOpsManager.MODE_ALLOWED,
Svetoslavc656e6f2015-04-29 14:08:16 -0700797 AppOpsManager.MODE_ALLOWED,
Svetoslav4af76a52015-04-29 15:29:46 -0700798 AppOpsManager.MODE_ALLOWED,
Svet Ganovb9d71a62015-04-30 10:38:13 -0700799 AppOpsManager.MODE_ALLOWED,
Svet Ganovede43162015-05-02 17:42:44 -0700800 AppOpsManager.MODE_ALLOWED,
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700801 AppOpsManager.MODE_ALLOWED,
Svet Ganov921c7df2015-06-29 21:51:41 -0700802 AppOpsManager.MODE_ERRORED, // OP_MOCK_LOCATION
803 AppOpsManager.MODE_ALLOWED,
804 AppOpsManager.MODE_ALLOWED
David Braunf5d83192013-09-16 13:43:51 -0700805 };
806
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700807 /**
808 * This specifies whether each option is allowed to be reset
809 * when resetting all app preferences. Disable reset for
810 * app ops that are under strong control of some part of the
811 * system (such as OP_WRITE_SMS, which should be allowed only
812 * for whichever app is selected as the current SMS app).
813 */
814 private static boolean[] sOpDisableReset = new boolean[] {
815 false,
816 false,
817 false,
818 false,
819 false,
820 false,
821 false,
822 false,
823 false,
824 false,
825 false,
826 false,
827 false,
828 false,
829 false,
830 true, // OP_WRITE_SMS
831 false,
832 false,
833 false,
834 false,
835 false,
836 false,
837 false,
838 false,
839 false,
840 false,
841 false,
842 false,
843 false,
844 false,
845 false,
846 false,
847 false,
848 false,
849 false,
850 false,
851 false,
852 false,
853 false,
854 false,
855 false,
856 false,
857 false,
Dianne Hackborne22b3b12014-05-07 18:06:44 -0700858 false,
Emily Bernier22c921a2014-05-28 11:01:32 -0400859 false,
Jason Monk1c7c3192014-06-26 12:52:18 -0400860 false,
Michael Wrightc39d47a2014-07-08 18:07:36 -0700861 false,
Jeff Davidson05542602014-08-11 14:07:27 -0700862 false,
Benjamin Franzf3ece362015-02-11 10:51:10 +0000863 false,
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700864 false,
865 false,
Svet Ganovc3300092015-04-17 09:07:22 -0700866 false,
Svetoslav5335b672015-04-29 12:00:51 -0700867 false,
Svetoslavc656e6f2015-04-29 14:08:16 -0700868 false,
Svetoslav4af76a52015-04-29 15:29:46 -0700869 false,
Svet Ganovb9d71a62015-04-30 10:38:13 -0700870 false,
Svet Ganovede43162015-05-02 17:42:44 -0700871 false,
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700872 false,
Svet Ganov921c7df2015-06-29 21:51:41 -0700873 false,
874 false,
Svet Ganov16a16892015-04-16 10:32:04 -0700875 false
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700876 };
877
Svet Ganovfbf01f72015-04-28 18:39:06 -0700878 /**
Svet Ganovb9d71a62015-04-30 10:38:13 -0700879 * Mapping from an app op name to the app op code.
Svet Ganovfbf01f72015-04-28 18:39:06 -0700880 */
Svet Ganovb9d71a62015-04-30 10:38:13 -0700881 private static HashMap<String, Integer> sOpStrToOp = new HashMap<>();
Svet Ganovfbf01f72015-04-28 18:39:06 -0700882
Svet Ganovb9d71a62015-04-30 10:38:13 -0700883 /**
884 * Mapping from a permission to the corresponding app op.
885 */
886 private static HashMap<String, Integer> sPermToOp = new HashMap<>();
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700887
888 static {
889 if (sOpToSwitch.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700890 throw new IllegalStateException("sOpToSwitch length " + sOpToSwitch.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700891 + " should be " + _NUM_OP);
892 }
893 if (sOpToString.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700894 throw new IllegalStateException("sOpToString length " + sOpToString.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700895 + " should be " + _NUM_OP);
896 }
897 if (sOpNames.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700898 throw new IllegalStateException("sOpNames length " + sOpNames.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700899 + " should be " + _NUM_OP);
900 }
901 if (sOpPerms.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700902 throw new IllegalStateException("sOpPerms length " + sOpPerms.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700903 + " should be " + _NUM_OP);
904 }
905 if (sOpDefaultMode.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700906 throw new IllegalStateException("sOpDefaultMode length " + sOpDefaultMode.length
907 + " should be " + _NUM_OP);
908 }
909 if (sOpDisableReset.length != _NUM_OP) {
910 throw new IllegalStateException("sOpDisableReset length " + sOpDisableReset.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700911 + " should be " + _NUM_OP);
912 }
Jason Monk62062992014-05-06 09:55:28 -0400913 if (sOpRestrictions.length != _NUM_OP) {
914 throw new IllegalStateException("sOpRestrictions length " + sOpRestrictions.length
915 + " should be " + _NUM_OP);
916 }
Jason Monk1c7c3192014-06-26 12:52:18 -0400917 if (sOpAllowSystemRestrictionBypass.length != _NUM_OP) {
918 throw new IllegalStateException("sOpAllowSYstemRestrictionsBypass length "
919 + sOpRestrictions.length + " should be " + _NUM_OP);
920 }
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700921 for (int i=0; i<_NUM_OP; i++) {
922 if (sOpToString[i] != null) {
923 sOpStrToOp.put(sOpToString[i], i);
924 }
925 }
Svet Ganovb9d71a62015-04-30 10:38:13 -0700926 for (int i=0; i<_NUM_OP; i++) {
927 if (sOpPerms[i] != null) {
928 sPermToOp.put(sOpPerms[i], i);
929 }
930 }
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700931 }
932
David Braunf5d83192013-09-16 13:43:51 -0700933 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800934 * Retrieve the op switch that controls the given operation.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700935 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800936 */
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800937 public static int opToSwitch(int op) {
938 return sOpToSwitch[op];
939 }
940
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800941 /**
942 * Retrieve a non-localized name for the operation, for debugging output.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700943 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800944 */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800945 public static String opToName(int op) {
Dianne Hackbornc2293022013-02-06 23:14:49 -0800946 if (op == OP_NONE) return "NONE";
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800947 return op < sOpNames.length ? sOpNames[op] : ("Unknown(" + op + ")");
948 }
949
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800950 /**
Dianne Hackborn7b7c58b2014-12-02 18:32:20 -0800951 * @hide
952 */
953 public static int strDebugOpToOp(String op) {
954 for (int i=0; i<sOpNames.length; i++) {
955 if (sOpNames[i].equals(op)) {
956 return i;
957 }
958 }
959 throw new IllegalArgumentException("Unknown operation string: " + op);
960 }
961
962 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800963 * Retrieve the permission associated with an operation, or null if there is not one.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700964 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800965 */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800966 public static String opToPermission(int op) {
967 return sOpPerms[op];
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800968 }
969
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800970 /**
Jason Monk62062992014-05-06 09:55:28 -0400971 * Retrieve the user restriction associated with an operation, or null if there is not one.
972 * @hide
973 */
974 public static String opToRestriction(int op) {
975 return sOpRestrictions[op];
976 }
977
978 /**
Svet Ganovb9d71a62015-04-30 10:38:13 -0700979 * Retrieve the app op code for a permission, or null if there is not one.
980 * @hide
981 */
982 public static int permissionToOpCode(String permission) {
Svet Ganov019d2302015-05-04 11:07:38 -0700983 Integer boxedOpCode = sPermToOp.get(permission);
984 return boxedOpCode != null ? boxedOpCode : OP_NONE;
Svet Ganovb9d71a62015-04-30 10:38:13 -0700985 }
986
987 /**
Jason Monk1c7c3192014-06-26 12:52:18 -0400988 * Retrieve whether the op allows the system (and system ui) to
989 * bypass the user restriction.
990 * @hide
991 */
992 public static boolean opAllowSystemBypassRestriction(int op) {
993 return sOpAllowSystemRestrictionBypass[op];
994 }
995
996 /**
David Braunf5d83192013-09-16 13:43:51 -0700997 * Retrieve the default mode for the operation.
998 * @hide
999 */
1000 public static int opToDefaultMode(int op) {
1001 return sOpDefaultMode[op];
1002 }
1003
1004 /**
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001005 * Retrieve whether the op allows itself to be reset.
1006 * @hide
1007 */
1008 public static boolean opAllowsReset(int op) {
1009 return !sOpDisableReset[op];
1010 }
1011
1012 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001013 * Class holding all of the operation information associated with an app.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001014 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001015 */
Dianne Hackborn35654b62013-01-14 17:38:02 -08001016 public static class PackageOps implements Parcelable {
1017 private final String mPackageName;
1018 private final int mUid;
1019 private final List<OpEntry> mEntries;
1020
1021 public PackageOps(String packageName, int uid, List<OpEntry> entries) {
1022 mPackageName = packageName;
1023 mUid = uid;
1024 mEntries = entries;
1025 }
1026
1027 public String getPackageName() {
1028 return mPackageName;
1029 }
1030
1031 public int getUid() {
1032 return mUid;
1033 }
1034
1035 public List<OpEntry> getOps() {
1036 return mEntries;
1037 }
1038
1039 @Override
1040 public int describeContents() {
1041 return 0;
1042 }
1043
1044 @Override
1045 public void writeToParcel(Parcel dest, int flags) {
1046 dest.writeString(mPackageName);
1047 dest.writeInt(mUid);
1048 dest.writeInt(mEntries.size());
1049 for (int i=0; i<mEntries.size(); i++) {
1050 mEntries.get(i).writeToParcel(dest, flags);
1051 }
1052 }
1053
1054 PackageOps(Parcel source) {
1055 mPackageName = source.readString();
1056 mUid = source.readInt();
1057 mEntries = new ArrayList<OpEntry>();
1058 final int N = source.readInt();
1059 for (int i=0; i<N; i++) {
1060 mEntries.add(OpEntry.CREATOR.createFromParcel(source));
1061 }
1062 }
1063
1064 public static final Creator<PackageOps> CREATOR = new Creator<PackageOps>() {
1065 @Override public PackageOps createFromParcel(Parcel source) {
1066 return new PackageOps(source);
1067 }
1068
1069 @Override public PackageOps[] newArray(int size) {
1070 return new PackageOps[size];
1071 }
1072 };
1073 }
1074
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001075 /**
1076 * Class holding the information about one unique operation of an application.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001077 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001078 */
Dianne Hackborn35654b62013-01-14 17:38:02 -08001079 public static class OpEntry implements Parcelable {
1080 private final int mOp;
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001081 private final int mMode;
Dianne Hackborn35654b62013-01-14 17:38:02 -08001082 private final long mTime;
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001083 private final long mRejectTime;
Dianne Hackborn35654b62013-01-14 17:38:02 -08001084 private final int mDuration;
Svet Ganov99b60432015-06-27 13:15:22 -07001085 private final int mProxyUid;
1086 private final String mProxyPackageName;
Dianne Hackborn35654b62013-01-14 17:38:02 -08001087
Svet Ganov99b60432015-06-27 13:15:22 -07001088 public OpEntry(int op, int mode, long time, long rejectTime, int duration,
1089 int proxyUid, String proxyPackage) {
Dianne Hackborn35654b62013-01-14 17:38:02 -08001090 mOp = op;
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001091 mMode = mode;
Dianne Hackborn35654b62013-01-14 17:38:02 -08001092 mTime = time;
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001093 mRejectTime = rejectTime;
Dianne Hackborn35654b62013-01-14 17:38:02 -08001094 mDuration = duration;
Svet Ganov99b60432015-06-27 13:15:22 -07001095 mProxyUid = proxyUid;
1096 mProxyPackageName = proxyPackage;
Dianne Hackborn35654b62013-01-14 17:38:02 -08001097 }
1098
1099 public int getOp() {
1100 return mOp;
1101 }
1102
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001103 public int getMode() {
1104 return mMode;
1105 }
1106
Dianne Hackborn35654b62013-01-14 17:38:02 -08001107 public long getTime() {
1108 return mTime;
1109 }
1110
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001111 public long getRejectTime() {
1112 return mRejectTime;
1113 }
1114
Dianne Hackborn35654b62013-01-14 17:38:02 -08001115 public boolean isRunning() {
1116 return mDuration == -1;
1117 }
1118
1119 public int getDuration() {
1120 return mDuration == -1 ? (int)(System.currentTimeMillis()-mTime) : mDuration;
1121 }
1122
Svet Ganov99b60432015-06-27 13:15:22 -07001123 public int getProxyUid() {
1124 return mProxyUid;
1125 }
1126
1127 public String getProxyPackageName() {
1128 return mProxyPackageName;
1129 }
1130
Dianne Hackborn35654b62013-01-14 17:38:02 -08001131 @Override
1132 public int describeContents() {
1133 return 0;
1134 }
1135
1136 @Override
1137 public void writeToParcel(Parcel dest, int flags) {
1138 dest.writeInt(mOp);
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001139 dest.writeInt(mMode);
Dianne Hackborn35654b62013-01-14 17:38:02 -08001140 dest.writeLong(mTime);
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001141 dest.writeLong(mRejectTime);
Dianne Hackborn35654b62013-01-14 17:38:02 -08001142 dest.writeInt(mDuration);
Svet Ganov99b60432015-06-27 13:15:22 -07001143 dest.writeInt(mProxyUid);
1144 dest.writeString(mProxyPackageName);
Dianne Hackborn35654b62013-01-14 17:38:02 -08001145 }
1146
1147 OpEntry(Parcel source) {
1148 mOp = source.readInt();
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001149 mMode = source.readInt();
Dianne Hackborn35654b62013-01-14 17:38:02 -08001150 mTime = source.readLong();
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001151 mRejectTime = source.readLong();
Dianne Hackborn35654b62013-01-14 17:38:02 -08001152 mDuration = source.readInt();
Svet Ganov99b60432015-06-27 13:15:22 -07001153 mProxyUid = source.readInt();
1154 mProxyPackageName = source.readString();
Dianne Hackborn35654b62013-01-14 17:38:02 -08001155 }
1156
1157 public static final Creator<OpEntry> CREATOR = new Creator<OpEntry>() {
1158 @Override public OpEntry createFromParcel(Parcel source) {
1159 return new OpEntry(source);
1160 }
1161
1162 @Override public OpEntry[] newArray(int size) {
1163 return new OpEntry[size];
1164 }
1165 };
1166 }
1167
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001168 /**
1169 * Callback for notification of changes to operation state.
1170 */
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001171 public interface OnOpChangedListener {
1172 public void onOpChanged(String op, String packageName);
1173 }
1174
1175 /**
1176 * Callback for notification of changes to operation state.
1177 * This allows you to see the raw op codes instead of strings.
1178 * @hide
1179 */
1180 public static class OnOpChangedInternalListener implements OnOpChangedListener {
1181 public void onOpChanged(String op, String packageName) { }
1182 public void onOpChanged(int op, String packageName) { }
Dianne Hackbornc2293022013-02-06 23:14:49 -08001183 }
1184
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001185 AppOpsManager(Context context, IAppOpsService service) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001186 mContext = context;
1187 mService = service;
1188 }
1189
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001190 /**
1191 * Retrieve current operation state for all applications.
1192 *
1193 * @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 -07001194 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001195 */
Dianne Hackborn35654b62013-01-14 17:38:02 -08001196 public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) {
1197 try {
1198 return mService.getPackagesForOps(ops);
1199 } catch (RemoteException e) {
1200 }
1201 return null;
1202 }
1203
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001204 /**
1205 * Retrieve current operation state for one application.
1206 *
1207 * @param uid The uid of the application of interest.
1208 * @param packageName The name of the application of interest.
1209 * @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 -07001210 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001211 */
Dianne Hackborn72e39832013-01-18 18:36:09 -08001212 public List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, int[] ops) {
1213 try {
1214 return mService.getOpsForPackage(uid, packageName, ops);
1215 } catch (RemoteException e) {
1216 }
1217 return null;
1218 }
1219
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001220 /** @hide */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001221 public void setMode(int code, int uid, String packageName, int mode) {
1222 try {
1223 mService.setMode(code, uid, packageName, mode);
1224 } catch (RemoteException e) {
1225 }
1226 }
1227
John Spurlock1af30c72014-03-10 08:33:35 -04001228 /**
1229 * Set a non-persisted restriction on an audio operation at a stream-level.
1230 * Restrictions are temporary additional constraints imposed on top of the persisted rules
1231 * defined by {@link #setMode}.
1232 *
1233 * @param code The operation to restrict.
John Spurlock7b414672014-07-18 13:02:39 -04001234 * @param usage The {@link android.media.AudioAttributes} usage value.
John Spurlock1af30c72014-03-10 08:33:35 -04001235 * @param mode The restriction mode (MODE_IGNORED,MODE_ERRORED) or MODE_ALLOWED to unrestrict.
1236 * @param exceptionPackages Optional list of packages to exclude from the restriction.
1237 * @hide
1238 */
John Spurlock7b414672014-07-18 13:02:39 -04001239 public void setRestriction(int code, @AttributeUsage int usage, int mode,
1240 String[] exceptionPackages) {
John Spurlock1af30c72014-03-10 08:33:35 -04001241 try {
1242 final int uid = Binder.getCallingUid();
John Spurlock7b414672014-07-18 13:02:39 -04001243 mService.setAudioRestriction(code, usage, uid, mode, exceptionPackages);
John Spurlock1af30c72014-03-10 08:33:35 -04001244 } catch (RemoteException e) {
1245 }
1246 }
1247
Dianne Hackborn607b4142013-08-02 18:10:10 -07001248 /** @hide */
1249 public void resetAllModes() {
1250 try {
Dianne Hackborn7b7c58b2014-12-02 18:32:20 -08001251 mService.resetAllModes(UserHandle.myUserId(), null);
Dianne Hackborn607b4142013-08-02 18:10:10 -07001252 } catch (RemoteException e) {
1253 }
1254 }
1255
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001256 /**
Svet Ganovfbf01f72015-04-28 18:39:06 -07001257 * Gets the app op name associated with a given permission.
1258 * The app op name is one of the public constants defined
1259 * in this class such as {@link #OPSTR_COARSE_LOCATION}.
1260 *
1261 * @param permission The permission.
1262 * @return The app op associated with the permission or null.
Svet Ganovfbf01f72015-04-28 18:39:06 -07001263 */
Svet Ganovfbf01f72015-04-28 18:39:06 -07001264 public static String permissionToOp(String permission) {
Svet Ganovb9d71a62015-04-30 10:38:13 -07001265 final Integer opCode = sPermToOp.get(permission);
1266 if (opCode == null) {
1267 return null;
1268 }
1269 return sOpToString[opCode];
Svet Ganovfbf01f72015-04-28 18:39:06 -07001270 }
1271
1272 /**
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001273 * Monitor for changes to the operating mode for the given op in the given app package.
Dianne Hackborne4cb66f2013-10-02 10:34:02 -07001274 * @param op The operation to monitor, one of OPSTR_*.
1275 * @param packageName The name of the application to monitor.
1276 * @param callback Where to report changes.
1277 */
1278 public void startWatchingMode(String op, String packageName,
1279 final OnOpChangedListener callback) {
1280 startWatchingMode(strOpToOp(op), packageName, callback);
1281 }
1282
1283 /**
1284 * Monitor for changes to the operating mode for the given op in the given app package.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001285 * @param op The operation to monitor, one of OP_*.
1286 * @param packageName The name of the application to monitor.
1287 * @param callback Where to report changes.
Dianne Hackborne4cb66f2013-10-02 10:34:02 -07001288 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001289 */
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001290 public void startWatchingMode(int op, String packageName, final OnOpChangedListener callback) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08001291 synchronized (mModeWatchers) {
1292 IAppOpsCallback cb = mModeWatchers.get(callback);
1293 if (cb == null) {
1294 cb = new IAppOpsCallback.Stub() {
1295 public void opChanged(int op, String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001296 if (callback instanceof OnOpChangedInternalListener) {
1297 ((OnOpChangedInternalListener)callback).onOpChanged(op, packageName);
1298 }
1299 if (sOpToString[op] != null) {
1300 callback.onOpChanged(sOpToString[op], packageName);
1301 }
Dianne Hackbornc2293022013-02-06 23:14:49 -08001302 }
1303 };
1304 mModeWatchers.put(callback, cb);
1305 }
1306 try {
1307 mService.startWatchingMode(op, packageName, cb);
1308 } catch (RemoteException e) {
1309 }
1310 }
1311 }
1312
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001313 /**
1314 * Stop monitoring that was previously started with {@link #startWatchingMode}. All
1315 * monitoring associated with this callback will be removed.
1316 */
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001317 public void stopWatchingMode(OnOpChangedListener callback) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08001318 synchronized (mModeWatchers) {
1319 IAppOpsCallback cb = mModeWatchers.get(callback);
1320 if (cb != null) {
1321 try {
1322 mService.stopWatchingMode(cb);
1323 } catch (RemoteException e) {
1324 }
1325 }
1326 }
1327 }
1328
Dianne Hackborn95d78532013-09-11 09:51:14 -07001329 private String buildSecurityExceptionMsg(int op, int uid, String packageName) {
1330 return packageName + " from uid " + uid + " not allowed to perform " + sOpNames[op];
1331 }
1332
Adam Lesinskib5cf61b2014-08-18 16:10:28 -07001333 /**
1334 * {@hide}
1335 */
1336 public static int strOpToOp(String op) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001337 Integer val = sOpStrToOp.get(op);
1338 if (val == null) {
1339 throw new IllegalArgumentException("Unknown operation string: " + op);
1340 }
1341 return val;
1342 }
1343
1344 /**
1345 * Do a quick check for whether an application might be able to perform an operation.
1346 * This is <em>not</em> a security check; you must use {@link #noteOp(String, int, String)}
1347 * or {@link #startOp(String, int, String)} for your actual security checks, which also
1348 * ensure that the given uid and package name are consistent. This function can just be
1349 * used for a quick check to see if an operation has been disabled for the application,
1350 * as an early reject of some work. This does not modify the time stamp or other data
1351 * about the operation.
1352 * @param op The operation to check. One of the OPSTR_* constants.
1353 * @param uid The user id of the application attempting to perform the operation.
1354 * @param packageName The name of the application attempting to perform the operation.
1355 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1356 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1357 * causing the app to crash).
1358 * @throws SecurityException If the app has been configured to crash on this op.
1359 */
1360 public int checkOp(String op, int uid, String packageName) {
1361 return checkOp(strOpToOp(op), uid, packageName);
1362 }
1363
1364 /**
John Spurlock925b85e2014-03-10 16:52:11 -04001365 * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001366 * returns {@link #MODE_ERRORED}.
1367 */
1368 public int checkOpNoThrow(String op, int uid, String packageName) {
1369 return checkOpNoThrow(strOpToOp(op), uid, packageName);
1370 }
1371
1372 /**
1373 * Make note of an application performing an operation. Note that you must pass
1374 * in both the uid and name of the application to be checked; this function will verify
1375 * that these two match, and if not, return {@link #MODE_IGNORED}. If this call
1376 * succeeds, the last execution time of the operation for this app will be updated to
1377 * the current time.
1378 * @param op The operation to note. One of the OPSTR_* constants.
1379 * @param uid The user id of the application attempting to perform the operation.
1380 * @param packageName The name of the application attempting to perform the operation.
1381 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1382 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1383 * causing the app to crash).
1384 * @throws SecurityException If the app has been configured to crash on this op.
1385 */
1386 public int noteOp(String op, int uid, String packageName) {
1387 return noteOp(strOpToOp(op), uid, packageName);
1388 }
1389
1390 /**
1391 * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
1392 * returns {@link #MODE_ERRORED}.
1393 */
1394 public int noteOpNoThrow(String op, int uid, String packageName) {
1395 return noteOpNoThrow(strOpToOp(op), uid, packageName);
1396 }
1397
1398 /**
Svet Ganov99b60432015-06-27 13:15:22 -07001399 * Make note of an application performing an operation on behalf of another
1400 * application when handling an IPC. Note that you must pass the package name
1401 * of the application that is being proxied while its UID will be inferred from
1402 * the IPC state; this function will verify that the calling uid and proxied
1403 * package name match, and if not, return {@link #MODE_IGNORED}. If this call
1404 * succeeds, the last execution time of the operation for the proxied app and
1405 * your app will be updated to the current time.
1406 * @param op The operation to note. One of the OPSTR_* constants.
1407 * @param proxiedPackageName The name of the application calling into the proxy application.
1408 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1409 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1410 * causing the app to crash).
1411 * @throws SecurityException If the app has been configured to crash on this op.
1412 */
1413 public int noteProxyOp(String op, String proxiedPackageName) {
1414 return noteProxyOp(strOpToOp(op), proxiedPackageName);
1415 }
1416
1417 /**
1418 * Like {@link #noteProxyOp(String, String)} but instead
1419 * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
1420 */
1421 public int noteProxyOpNoThrow(String op, String proxiedPackageName) {
1422 return noteProxyOpNoThrow(strOpToOp(op), proxiedPackageName);
1423 }
1424
1425 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001426 * Report that an application has started executing a long-running operation. Note that you
1427 * must pass in both the uid and name of the application to be checked; this function will
1428 * verify that these two match, and if not, return {@link #MODE_IGNORED}. If this call
1429 * succeeds, the last execution time of the operation for this app will be updated to
1430 * the current time and the operation will be marked as "running". In this case you must
1431 * later call {@link #finishOp(String, int, String)} to report when the application is no
1432 * longer performing the operation.
1433 * @param op The operation to start. One of the OPSTR_* constants.
1434 * @param uid The user id of the application attempting to perform the operation.
1435 * @param packageName The name of the application attempting to perform the operation.
1436 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1437 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1438 * causing the app to crash).
1439 * @throws SecurityException If the app has been configured to crash on this op.
1440 */
1441 public int startOp(String op, int uid, String packageName) {
1442 return startOp(strOpToOp(op), uid, packageName);
1443 }
1444
1445 /**
1446 * Like {@link #startOp} but instead of throwing a {@link SecurityException} it
1447 * returns {@link #MODE_ERRORED}.
1448 */
1449 public int startOpNoThrow(String op, int uid, String packageName) {
1450 return startOpNoThrow(strOpToOp(op), uid, packageName);
1451 }
1452
1453 /**
1454 * Report that an application is no longer performing an operation that had previously
1455 * been started with {@link #startOp(String, int, String)}. There is no validation of input
1456 * or result; the parameters supplied here must be the exact same ones previously passed
1457 * in when starting the operation.
1458 */
1459 public void finishOp(String op, int uid, String packageName) {
1460 finishOp(strOpToOp(op), uid, packageName);
1461 }
1462
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001463 /**
1464 * Do a quick check for whether an application might be able to perform an operation.
1465 * This is <em>not</em> a security check; you must use {@link #noteOp(int, int, String)}
1466 * or {@link #startOp(int, int, String)} for your actual security checks, which also
1467 * ensure that the given uid and package name are consistent. This function can just be
1468 * used for a quick check to see if an operation has been disabled for the application,
1469 * as an early reject of some work. This does not modify the time stamp or other data
1470 * about the operation.
1471 * @param op The operation to check. One of the OP_* constants.
1472 * @param uid The user id of the application attempting to perform the operation.
1473 * @param packageName The name of the application attempting to perform the operation.
1474 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1475 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1476 * causing the app to crash).
1477 * @throws SecurityException If the app has been configured to crash on this op.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001478 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001479 */
Dianne Hackborn35654b62013-01-14 17:38:02 -08001480 public int checkOp(int op, int uid, String packageName) {
1481 try {
1482 int mode = mService.checkOperation(op, uid, packageName);
1483 if (mode == MODE_ERRORED) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07001484 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborn35654b62013-01-14 17:38:02 -08001485 }
1486 return mode;
1487 } catch (RemoteException e) {
1488 }
1489 return MODE_IGNORED;
1490 }
1491
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001492 /**
1493 * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
1494 * returns {@link #MODE_ERRORED}.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001495 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001496 */
Dianne Hackborn35654b62013-01-14 17:38:02 -08001497 public int checkOpNoThrow(int op, int uid, String packageName) {
1498 try {
1499 return mService.checkOperation(op, uid, packageName);
1500 } catch (RemoteException e) {
1501 }
Svet Ganov99b60432015-06-27 13:15:22 -07001502 return MODE_ERRORED;
Dianne Hackborn35654b62013-01-14 17:38:02 -08001503 }
1504
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001505 /**
Jeff Sharkey911d7f42013-09-05 18:11:45 -07001506 * Do a quick check to validate if a package name belongs to a UID.
1507 *
1508 * @throws SecurityException if the package name doesn't belong to the given
1509 * UID, or if ownership cannot be verified.
1510 */
1511 public void checkPackage(int uid, String packageName) {
1512 try {
1513 if (mService.checkPackage(uid, packageName) != MODE_ALLOWED) {
1514 throw new SecurityException(
1515 "Package " + packageName + " does not belong to " + uid);
1516 }
1517 } catch (RemoteException e) {
1518 throw new SecurityException("Unable to verify package ownership", e);
1519 }
1520 }
1521
1522 /**
John Spurlock1af30c72014-03-10 08:33:35 -04001523 * Like {@link #checkOp} but at a stream-level for audio operations.
1524 * @hide
1525 */
1526 public int checkAudioOp(int op, int stream, int uid, String packageName) {
1527 try {
1528 final int mode = mService.checkAudioOperation(op, stream, uid, packageName);
1529 if (mode == MODE_ERRORED) {
1530 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
1531 }
1532 return mode;
1533 } catch (RemoteException e) {
1534 }
1535 return MODE_IGNORED;
1536 }
1537
1538 /**
1539 * Like {@link #checkAudioOp} but instead of throwing a {@link SecurityException} it
1540 * returns {@link #MODE_ERRORED}.
1541 * @hide
1542 */
1543 public int checkAudioOpNoThrow(int op, int stream, int uid, String packageName) {
1544 try {
1545 return mService.checkAudioOperation(op, stream, uid, packageName);
1546 } catch (RemoteException e) {
1547 }
Svet Ganov99b60432015-06-27 13:15:22 -07001548 return MODE_ERRORED;
John Spurlock1af30c72014-03-10 08:33:35 -04001549 }
1550
1551 /**
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001552 * Make note of an application performing an operation. Note that you must pass
1553 * in both the uid and name of the application to be checked; this function will verify
1554 * that these two match, and if not, return {@link #MODE_IGNORED}. If this call
1555 * succeeds, the last execution time of the operation for this app will be updated to
1556 * the current time.
1557 * @param op The operation to note. One of the OP_* constants.
1558 * @param uid The user id of the application attempting to perform the operation.
1559 * @param packageName The name of the application attempting to perform the operation.
1560 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1561 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1562 * causing the app to crash).
1563 * @throws SecurityException If the app has been configured to crash on this op.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001564 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001565 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001566 public int noteOp(int op, int uid, String packageName) {
1567 try {
1568 int mode = mService.noteOperation(op, uid, packageName);
1569 if (mode == MODE_ERRORED) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07001570 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001571 }
1572 return mode;
1573 } catch (RemoteException e) {
1574 }
1575 return MODE_IGNORED;
1576 }
1577
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001578 /**
Svet Ganov99b60432015-06-27 13:15:22 -07001579 * Make note of an application performing an operation on behalf of another
1580 * application when handling an IPC. Note that you must pass the package name
1581 * of the application that is being proxied while its UID will be inferred from
1582 * the IPC state; this function will verify that the calling uid and proxied
1583 * package name match, and if not, return {@link #MODE_IGNORED}. If this call
1584 * succeeds, the last execution time of the operation for the proxied app and
1585 * your app will be updated to the current time.
1586 * @param op The operation to note. One of the OPSTR_* constants.
1587 * @param proxiedPackageName The name of the application calling into the proxy application.
1588 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1589 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1590 * causing the app to crash).
1591 * @throws SecurityException If the proxy or proxied app has been configured to
1592 * crash on this op.
1593 *
1594 * @hide
1595 */
1596 public int noteProxyOp(int op, String proxiedPackageName) {
1597 int mode = noteProxyOpNoThrow(op, proxiedPackageName);
1598 if (mode == MODE_ERRORED) {
1599 throw new SecurityException("Proxy package " + mContext.getOpPackageName()
1600 + " from uid " + Process.myUid() + " or calling package "
1601 + proxiedPackageName + " from uid " + Binder.getCallingUid()
1602 + " not allowed to perform " + sOpNames[op]);
1603 }
1604 return mode;
1605 }
1606
1607 /**
1608 * Like {@link #noteProxyOp(int, String)} but instead
1609 * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
1610 * @hide
1611 */
1612 public int noteProxyOpNoThrow(int op, String proxiedPackageName) {
1613 try {
1614 return mService.noteProxyOperation(op, mContext.getOpPackageName(),
1615 Binder.getCallingUid(), proxiedPackageName);
1616 } catch (RemoteException e) {
1617 }
1618 return MODE_ERRORED;
1619 }
1620
1621 /**
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001622 * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
1623 * returns {@link #MODE_ERRORED}.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001624 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001625 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001626 public int noteOpNoThrow(int op, int uid, String packageName) {
1627 try {
1628 return mService.noteOperation(op, uid, packageName);
1629 } catch (RemoteException e) {
1630 }
Svet Ganov99b60432015-06-27 13:15:22 -07001631 return MODE_ERRORED;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001632 }
1633
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001634 /** @hide */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001635 public int noteOp(int op) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07001636 return noteOp(op, Process.myUid(), mContext.getOpPackageName());
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001637 }
1638
Dianne Hackborne98f5db2013-07-17 17:23:25 -07001639 /** @hide */
1640 public static IBinder getToken(IAppOpsService service) {
1641 synchronized (AppOpsManager.class) {
1642 if (sToken != null) {
1643 return sToken;
1644 }
1645 try {
1646 sToken = service.getToken(new Binder());
1647 } catch (RemoteException e) {
1648 // System is dead, whatevs.
1649 }
1650 return sToken;
1651 }
1652 }
1653
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001654 /**
1655 * Report that an application has started executing a long-running operation. Note that you
1656 * must pass in both the uid and name of the application to be checked; this function will
1657 * verify that these two match, and if not, return {@link #MODE_IGNORED}. If this call
1658 * succeeds, the last execution time of the operation for this app will be updated to
1659 * the current time and the operation will be marked as "running". In this case you must
1660 * later call {@link #finishOp(int, int, String)} to report when the application is no
1661 * longer performing the operation.
1662 * @param op The operation to start. One of the OP_* constants.
1663 * @param uid The user id of the application attempting to perform the operation.
1664 * @param packageName The name of the application attempting to perform the operation.
1665 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1666 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1667 * causing the app to crash).
1668 * @throws SecurityException If the app has been configured to crash on this op.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001669 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001670 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001671 public int startOp(int op, int uid, String packageName) {
1672 try {
Dianne Hackborne98f5db2013-07-17 17:23:25 -07001673 int mode = mService.startOperation(getToken(mService), op, uid, packageName);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001674 if (mode == MODE_ERRORED) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07001675 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001676 }
1677 return mode;
1678 } catch (RemoteException e) {
1679 }
1680 return MODE_IGNORED;
1681 }
1682
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001683 /**
1684 * Like {@link #startOp} but instead of throwing a {@link SecurityException} it
1685 * returns {@link #MODE_ERRORED}.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001686 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001687 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001688 public int startOpNoThrow(int op, int uid, String packageName) {
1689 try {
Dianne Hackborne98f5db2013-07-17 17:23:25 -07001690 return mService.startOperation(getToken(mService), op, uid, packageName);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001691 } catch (RemoteException e) {
1692 }
Svet Ganov99b60432015-06-27 13:15:22 -07001693 return MODE_ERRORED;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001694 }
1695
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001696 /** @hide */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001697 public int startOp(int op) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07001698 return startOp(op, Process.myUid(), mContext.getOpPackageName());
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001699 }
1700
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001701 /**
1702 * Report that an application is no longer performing an operation that had previously
1703 * been started with {@link #startOp(int, int, String)}. There is no validation of input
1704 * or result; the parameters supplied here must be the exact same ones previously passed
1705 * in when starting the operation.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001706 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001707 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001708 public void finishOp(int op, int uid, String packageName) {
1709 try {
Dianne Hackborne98f5db2013-07-17 17:23:25 -07001710 mService.finishOperation(getToken(mService), op, uid, packageName);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001711 } catch (RemoteException e) {
1712 }
1713 }
1714
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001715 /** @hide */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001716 public void finishOp(int op) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07001717 finishOp(op, Process.myUid(), mContext.getOpPackageName());
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001718 }
1719}