blob: 381c20c136f40f9f4618f6d75fe0ee5be8233abb [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
Jeff Davidson05542602014-08-11 14:07:27 -070019import android.annotation.SystemApi;
20import android.app.usage.UsageStatsManager;
21import android.content.Context;
John Spurlock7b414672014-07-18 13:02:39 -040022import android.media.AudioAttributes.AttributeUsage;
Dianne Hackborne98f5db2013-07-17 17:23:25 -070023import android.os.Binder;
24import android.os.IBinder;
Dianne Hackborn35654b62013-01-14 17:38:02 -080025import android.os.Parcel;
26import android.os.Parcelable;
Dianne Hackborna06de0f2012-12-11 16:34:47 -080027import android.os.Process;
28import android.os.RemoteException;
Dianne Hackborn7b7c58b2014-12-02 18:32:20 -080029import android.os.UserHandle;
Jeff Davidson05542602014-08-11 14:07:27 -070030import android.os.UserManager;
31import android.util.ArrayMap;
32
33import com.android.internal.app.IAppOpsCallback;
34import com.android.internal.app.IAppOpsService;
35
36import java.util.ArrayList;
37import java.util.HashMap;
38import java.util.List;
Dianne Hackborna06de0f2012-12-11 16:34:47 -080039
Dianne Hackbornd7d28e62013-02-12 14:59:53 -080040/**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070041 * API for interacting with "application operation" tracking.
Dianne Hackbornd7d28e62013-02-12 14:59:53 -080042 *
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070043 * <p>This API is not generally intended for third party application developers; most
John Spurlock925b85e2014-03-10 16:52:11 -040044 * features are only available to system applications. Obtain an instance of it through
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070045 * {@link Context#getSystemService(String) Context.getSystemService} with
46 * {@link Context#APP_OPS_SERVICE Context.APP_OPS_SERVICE}.</p>
Dianne Hackbornd7d28e62013-02-12 14:59:53 -080047 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -080048public class AppOpsManager {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070049 /**
50 * <p>App ops allows callers to:</p>
51 *
52 * <ul>
53 * <li> Note when operations are happening, and find out if they are allowed for the current
54 * caller.</li>
55 * <li> Disallow specific apps from doing specific operations.</li>
56 * <li> Collect all of the current information about operations that have been executed or
57 * are not being allowed.</li>
58 * <li> Monitor for changes in whether an operation is allowed.</li>
59 * </ul>
60 *
61 * <p>Each operation is identified by a single integer; these integers are a fixed set of
62 * operations, enumerated by the OP_* constants.
63 *
64 * <p></p>When checking operations, the result is a "mode" integer indicating the current
65 * setting for the operation under that caller: MODE_ALLOWED, MODE_IGNORED (don't execute
66 * the operation but fake its behavior enough so that the caller doesn't crash),
67 * MODE_ERRORED (throw a SecurityException back to the caller; the normal operation calls
68 * will do this for you).
69 */
70
Dianne Hackborna06de0f2012-12-11 16:34:47 -080071 final Context mContext;
72 final IAppOpsService mService;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070073 final ArrayMap<OnOpChangedListener, IAppOpsCallback> mModeWatchers
74 = new ArrayMap<OnOpChangedListener, IAppOpsCallback>();
Dianne Hackborna06de0f2012-12-11 16:34:47 -080075
Dianne Hackborne98f5db2013-07-17 17:23:25 -070076 static IBinder sToken;
77
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070078 /**
79 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is
80 * allowed to perform the given operation.
81 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -080082 public static final int MODE_ALLOWED = 0;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070083
84 /**
85 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is
86 * not allowed to perform the given operation, and this attempt should
87 * <em>silently fail</em> (it should not cause the app to crash).
88 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -080089 public static final int MODE_IGNORED = 1;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070090
91 /**
92 * Result from {@link #checkOpNoThrow}, {@link #noteOpNoThrow}, {@link #startOpNoThrow}: the
93 * given caller is not allowed to perform the given operation, and this attempt should
94 * cause it to have a fatal error, typically a {@link SecurityException}.
95 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -080096 public static final int MODE_ERRORED = 2;
97
Dianne Hackborn33f5ddd2014-07-21 15:35:45 -070098 /**
99 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller should
100 * use its default security check. This mode is not normally used; it should only be used
101 * with appop permissions, and callers must explicitly check for it and deal with it.
102 */
103 public static final int MODE_DEFAULT = 3;
104
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500105 // when adding one of these:
106 // - increment _NUM_OP
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700107 // - add rows to sOpToSwitch, sOpToString, sOpNames, sOpPerms, sOpDefaultMode
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500108 // - add descriptive strings to Settings/res/values/arrays.xml
David Christie0b837452013-07-29 16:02:13 -0700109 // - add the op to the appropriate template in AppOpsState.OpsTemplate (settings app)
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700110
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700111 /** @hide No operation specified. */
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800112 public static final int OP_NONE = -1;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700113 /** @hide Access to coarse location information. */
Dianne Hackborn35654b62013-01-14 17:38:02 -0800114 public static final int OP_COARSE_LOCATION = 0;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700115 /** @hide Access to fine location information. */
Dianne Hackborn35654b62013-01-14 17:38:02 -0800116 public static final int OP_FINE_LOCATION = 1;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700117 /** @hide Causing GPS to run. */
Dianne Hackborn35654b62013-01-14 17:38:02 -0800118 public static final int OP_GPS = 2;
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800119 /** @hide */
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700120 public static final int OP_VIBRATE = 3;
121 /** @hide */
122 public static final int OP_READ_CONTACTS = 4;
123 /** @hide */
124 public static final int OP_WRITE_CONTACTS = 5;
125 /** @hide */
126 public static final int OP_READ_CALL_LOG = 6;
127 /** @hide */
128 public static final int OP_WRITE_CALL_LOG = 7;
129 /** @hide */
130 public static final int OP_READ_CALENDAR = 8;
131 /** @hide */
132 public static final int OP_WRITE_CALENDAR = 9;
133 /** @hide */
134 public static final int OP_WIFI_SCAN = 10;
135 /** @hide */
136 public static final int OP_POST_NOTIFICATION = 11;
137 /** @hide */
138 public static final int OP_NEIGHBORING_CELLS = 12;
139 /** @hide */
140 public static final int OP_CALL_PHONE = 13;
141 /** @hide */
142 public static final int OP_READ_SMS = 14;
143 /** @hide */
144 public static final int OP_WRITE_SMS = 15;
145 /** @hide */
146 public static final int OP_RECEIVE_SMS = 16;
147 /** @hide */
148 public static final int OP_RECEIVE_EMERGECY_SMS = 17;
149 /** @hide */
150 public static final int OP_RECEIVE_MMS = 18;
151 /** @hide */
152 public static final int OP_RECEIVE_WAP_PUSH = 19;
153 /** @hide */
154 public static final int OP_SEND_SMS = 20;
155 /** @hide */
156 public static final int OP_READ_ICC_SMS = 21;
157 /** @hide */
158 public static final int OP_WRITE_ICC_SMS = 22;
159 /** @hide */
160 public static final int OP_WRITE_SETTINGS = 23;
161 /** @hide */
162 public static final int OP_SYSTEM_ALERT_WINDOW = 24;
163 /** @hide */
164 public static final int OP_ACCESS_NOTIFICATIONS = 25;
165 /** @hide */
166 public static final int OP_CAMERA = 26;
167 /** @hide */
168 public static final int OP_RECORD_AUDIO = 27;
169 /** @hide */
170 public static final int OP_PLAY_AUDIO = 28;
171 /** @hide */
172 public static final int OP_READ_CLIPBOARD = 29;
173 /** @hide */
174 public static final int OP_WRITE_CLIPBOARD = 30;
175 /** @hide */
176 public static final int OP_TAKE_MEDIA_BUTTONS = 31;
177 /** @hide */
178 public static final int OP_TAKE_AUDIO_FOCUS = 32;
179 /** @hide */
180 public static final int OP_AUDIO_MASTER_VOLUME = 33;
181 /** @hide */
182 public static final int OP_AUDIO_VOICE_VOLUME = 34;
183 /** @hide */
184 public static final int OP_AUDIO_RING_VOLUME = 35;
185 /** @hide */
186 public static final int OP_AUDIO_MEDIA_VOLUME = 36;
187 /** @hide */
188 public static final int OP_AUDIO_ALARM_VOLUME = 37;
189 /** @hide */
190 public static final int OP_AUDIO_NOTIFICATION_VOLUME = 38;
191 /** @hide */
192 public static final int OP_AUDIO_BLUETOOTH_VOLUME = 39;
193 /** @hide */
194 public static final int OP_WAKE_LOCK = 40;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700195 /** @hide Continually monitoring location data. */
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700196 public static final int OP_MONITOR_LOCATION = 41;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700197 /** @hide Continually monitoring location data with a relatively high power request. */
David Christie0b837452013-07-29 16:02:13 -0700198 public static final int OP_MONITOR_HIGH_POWER_LOCATION = 42;
Dianne Hackborne22b3b12014-05-07 18:06:44 -0700199 /** @hide Retrieve current usage stats via {@link UsageStatsManager}. */
200 public static final int OP_GET_USAGE_STATS = 43;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700201 /** @hide */
Emily Bernier22c921a2014-05-28 11:01:32 -0400202 public static final int OP_MUTE_MICROPHONE = 44;
203 /** @hide */
Jason Monk1c7c3192014-06-26 12:52:18 -0400204 public static final int OP_TOAST_WINDOW = 45;
Michael Wrightc39d47a2014-07-08 18:07:36 -0700205 /** @hide Capture the device's display contents and/or audio */
206 public static final int OP_PROJECT_MEDIA = 46;
Jeff Davidson05542602014-08-11 14:07:27 -0700207 /** @hide Activate a VPN connection without user intervention. */
208 public static final int OP_ACTIVATE_VPN = 47;
Benjamin Franzf3ece362015-02-11 10:51:10 +0000209 /** @hide Access the WallpaperManagerAPI to write wallpapers. */
210 public static final int OP_WRITE_WALLPAPER = 48;
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700211 /** @hide Received the assist structure from an app. */
212 public static final int OP_ASSIST_STRUCTURE = 49;
213 /** @hide Received a screenshot from assist. */
214 public static final int OP_ASSIST_SCREENSHOT = 50;
Jason Monk1c7c3192014-06-26 12:52:18 -0400215 /** @hide */
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700216 public static final int _NUM_OP = 51;
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800217
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700218 /** Access to coarse location information. */
219 public static final String OPSTR_COARSE_LOCATION =
220 "android:coarse_location";
221 /** Access to fine location information. */
222 public static final String OPSTR_FINE_LOCATION =
223 "android:fine_location";
224 /** Continually monitoring location data. */
225 public static final String OPSTR_MONITOR_LOCATION
226 = "android:monitor_location";
227 /** Continually monitoring location data with a relatively high power request. */
228 public static final String OPSTR_MONITOR_HIGH_POWER_LOCATION
229 = "android:monitor_location_high_power";
Dianne Hackborn5064e7c2014-09-02 10:57:16 -0700230 /** Access to {@link android.app.usage.UsageStatsManager}. */
231 public static final String OPSTR_GET_USAGE_STATS
232 = "android:get_usage_stats";
Jeff Davidson05542602014-08-11 14:07:27 -0700233 /** Activate a VPN connection without user intervention. @hide */
234 @SystemApi
235 public static final String OPSTR_ACTIVATE_VPN = "android:activate_vpn";
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700236
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800237 /**
238 * This maps each operation to the operation that serves as the
239 * switch to determine whether it is allowed. Generally this is
240 * a 1:1 mapping, but for some things (like location) that have
241 * multiple low-level operations being tracked that should be
David Christie0b837452013-07-29 16:02:13 -0700242 * presented to the user as one switch then this can be used to
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800243 * make them all controlled by the same single operation.
244 */
245 private static int[] sOpToSwitch = new int[] {
246 OP_COARSE_LOCATION,
247 OP_COARSE_LOCATION,
248 OP_COARSE_LOCATION,
249 OP_VIBRATE,
250 OP_READ_CONTACTS,
251 OP_WRITE_CONTACTS,
252 OP_READ_CALL_LOG,
253 OP_WRITE_CALL_LOG,
254 OP_READ_CALENDAR,
255 OP_WRITE_CALENDAR,
256 OP_COARSE_LOCATION,
257 OP_POST_NOTIFICATION,
258 OP_COARSE_LOCATION,
259 OP_CALL_PHONE,
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800260 OP_READ_SMS,
261 OP_WRITE_SMS,
David Braun18966a82013-09-10 13:14:46 -0700262 OP_RECEIVE_SMS,
263 OP_RECEIVE_SMS,
264 OP_RECEIVE_SMS,
265 OP_RECEIVE_SMS,
266 OP_SEND_SMS,
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800267 OP_READ_SMS,
268 OP_WRITE_SMS,
Dianne Hackborn961321f2013-02-05 17:22:41 -0800269 OP_WRITE_SETTINGS,
Dianne Hackbornc2293022013-02-06 23:14:49 -0800270 OP_SYSTEM_ALERT_WINDOW,
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500271 OP_ACCESS_NOTIFICATIONS,
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800272 OP_CAMERA,
273 OP_RECORD_AUDIO,
274 OP_PLAY_AUDIO,
Dianne Hackbornefcc1a22013-02-25 18:02:35 -0800275 OP_READ_CLIPBOARD,
276 OP_WRITE_CLIPBOARD,
Dianne Hackbornba50b97c2013-04-30 15:04:46 -0700277 OP_TAKE_MEDIA_BUTTONS,
278 OP_TAKE_AUDIO_FOCUS,
279 OP_AUDIO_MASTER_VOLUME,
280 OP_AUDIO_VOICE_VOLUME,
281 OP_AUDIO_RING_VOLUME,
282 OP_AUDIO_MEDIA_VOLUME,
283 OP_AUDIO_ALARM_VOLUME,
284 OP_AUDIO_NOTIFICATION_VOLUME,
285 OP_AUDIO_BLUETOOTH_VOLUME,
Dianne Hackborn713df152013-05-17 11:27:57 -0700286 OP_WAKE_LOCK,
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700287 OP_COARSE_LOCATION,
David Christie0b837452013-07-29 16:02:13 -0700288 OP_COARSE_LOCATION,
Dianne Hackborne22b3b12014-05-07 18:06:44 -0700289 OP_GET_USAGE_STATS,
Jason Monk1c7c3192014-06-26 12:52:18 -0400290 OP_MUTE_MICROPHONE,
291 OP_TOAST_WINDOW,
Michael Wrightc39d47a2014-07-08 18:07:36 -0700292 OP_PROJECT_MEDIA,
Jeff Davidson05542602014-08-11 14:07:27 -0700293 OP_ACTIVATE_VPN,
Benjamin Franzf3ece362015-02-11 10:51:10 +0000294 OP_WRITE_WALLPAPER,
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700295 OP_ASSIST_STRUCTURE,
296 OP_ASSIST_SCREENSHOT,
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800297 };
298
299 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700300 * This maps each operation to the public string constant for it.
301 * If it doesn't have a public string constant, it maps to null.
302 */
303 private static String[] sOpToString = new String[] {
304 OPSTR_COARSE_LOCATION,
305 OPSTR_FINE_LOCATION,
306 null,
307 null,
308 null,
309 null,
310 null,
311 null,
312 null,
313 null,
314 null,
315 null,
316 null,
317 null,
318 null,
319 null,
320 null,
321 null,
322 null,
323 null,
324 null,
325 null,
326 null,
327 null,
328 null,
329 null,
330 null,
331 null,
332 null,
333 null,
334 null,
335 null,
336 null,
337 null,
338 null,
339 null,
340 null,
341 null,
342 null,
343 null,
344 null,
345 OPSTR_MONITOR_LOCATION,
346 OPSTR_MONITOR_HIGH_POWER_LOCATION,
Dianne Hackborn5064e7c2014-09-02 10:57:16 -0700347 OPSTR_GET_USAGE_STATS,
Emily Bernier22c921a2014-05-28 11:01:32 -0400348 null,
Jason Monk1c7c3192014-06-26 12:52:18 -0400349 null,
Michael Wrightc39d47a2014-07-08 18:07:36 -0700350 null,
Jeff Davidson05542602014-08-11 14:07:27 -0700351 OPSTR_ACTIVATE_VPN,
Benjamin Franzf3ece362015-02-11 10:51:10 +0000352 null,
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700353 null,
354 null,
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700355 };
356
357 /**
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800358 * This provides a simple name for each operation to be used
359 * in debug output.
360 */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800361 private static String[] sOpNames = new String[] {
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800362 "COARSE_LOCATION",
363 "FINE_LOCATION",
364 "GPS",
365 "VIBRATE",
366 "READ_CONTACTS",
367 "WRITE_CONTACTS",
368 "READ_CALL_LOG",
369 "WRITE_CALL_LOG",
370 "READ_CALENDAR",
371 "WRITE_CALENDAR",
372 "WIFI_SCAN",
373 "POST_NOTIFICATION",
374 "NEIGHBORING_CELLS",
375 "CALL_PHONE",
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800376 "READ_SMS",
377 "WRITE_SMS",
378 "RECEIVE_SMS",
379 "RECEIVE_EMERGECY_SMS",
380 "RECEIVE_MMS",
381 "RECEIVE_WAP_PUSH",
382 "SEND_SMS",
383 "READ_ICC_SMS",
384 "WRITE_ICC_SMS",
Dianne Hackborn961321f2013-02-05 17:22:41 -0800385 "WRITE_SETTINGS",
Dianne Hackbornc2293022013-02-06 23:14:49 -0800386 "SYSTEM_ALERT_WINDOW",
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500387 "ACCESS_NOTIFICATIONS",
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800388 "CAMERA",
389 "RECORD_AUDIO",
390 "PLAY_AUDIO",
Dianne Hackbornefcc1a22013-02-25 18:02:35 -0800391 "READ_CLIPBOARD",
392 "WRITE_CLIPBOARD",
Dianne Hackbornba50b97c2013-04-30 15:04:46 -0700393 "TAKE_MEDIA_BUTTONS",
394 "TAKE_AUDIO_FOCUS",
395 "AUDIO_MASTER_VOLUME",
396 "AUDIO_VOICE_VOLUME",
397 "AUDIO_RING_VOLUME",
398 "AUDIO_MEDIA_VOLUME",
399 "AUDIO_ALARM_VOLUME",
400 "AUDIO_NOTIFICATION_VOLUME",
401 "AUDIO_BLUETOOTH_VOLUME",
Dianne Hackborn713df152013-05-17 11:27:57 -0700402 "WAKE_LOCK",
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700403 "MONITOR_LOCATION",
David Christie0b837452013-07-29 16:02:13 -0700404 "MONITOR_HIGH_POWER_LOCATION",
Emily Bernier22c921a2014-05-28 11:01:32 -0400405 "GET_USAGE_STATS",
Michael Wrightc39d47a2014-07-08 18:07:36 -0700406 "MUTE_MICROPHONE",
Jason Monk1c7c3192014-06-26 12:52:18 -0400407 "TOAST_WINDOW",
Michael Wrightc39d47a2014-07-08 18:07:36 -0700408 "PROJECT_MEDIA",
Jeff Davidson05542602014-08-11 14:07:27 -0700409 "ACTIVATE_VPN",
Benjamin Franzf3ece362015-02-11 10:51:10 +0000410 "WRITE_WALLPAPER",
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700411 "ASSIST_STRUCTURE",
412 "ASSIST_SCREENSHOT"
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800413 };
414
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800415 /**
416 * This optionally maps a permission to an operation. If there
417 * is no permission associated with an operation, it is null.
418 */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800419 private static String[] sOpPerms = new String[] {
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800420 android.Manifest.permission.ACCESS_COARSE_LOCATION,
421 android.Manifest.permission.ACCESS_FINE_LOCATION,
422 null,
423 android.Manifest.permission.VIBRATE,
424 android.Manifest.permission.READ_CONTACTS,
425 android.Manifest.permission.WRITE_CONTACTS,
426 android.Manifest.permission.READ_CALL_LOG,
427 android.Manifest.permission.WRITE_CALL_LOG,
428 android.Manifest.permission.READ_CALENDAR,
429 android.Manifest.permission.WRITE_CALENDAR,
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800430 android.Manifest.permission.ACCESS_WIFI_STATE,
Robert Craigf97616c2013-10-07 12:32:02 -0400431 null, // no permission required for notifications
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800432 null, // neighboring cells shares the coarse location perm
433 android.Manifest.permission.CALL_PHONE,
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800434 android.Manifest.permission.READ_SMS,
435 android.Manifest.permission.WRITE_SMS,
436 android.Manifest.permission.RECEIVE_SMS,
437 android.Manifest.permission.RECEIVE_EMERGENCY_BROADCAST,
438 android.Manifest.permission.RECEIVE_MMS,
439 android.Manifest.permission.RECEIVE_WAP_PUSH,
440 android.Manifest.permission.SEND_SMS,
441 android.Manifest.permission.READ_SMS,
442 android.Manifest.permission.WRITE_SMS,
Dianne Hackborn961321f2013-02-05 17:22:41 -0800443 android.Manifest.permission.WRITE_SETTINGS,
Dianne Hackbornc2293022013-02-06 23:14:49 -0800444 android.Manifest.permission.SYSTEM_ALERT_WINDOW,
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500445 android.Manifest.permission.ACCESS_NOTIFICATIONS,
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800446 android.Manifest.permission.CAMERA,
447 android.Manifest.permission.RECORD_AUDIO,
448 null, // no permission for playing audio
Dianne Hackbornefcc1a22013-02-25 18:02:35 -0800449 null, // no permission for reading clipboard
450 null, // no permission for writing clipboard
Dianne Hackbornba50b97c2013-04-30 15:04:46 -0700451 null, // no permission for taking media buttons
452 null, // no permission for taking audio focus
453 null, // no permission for changing master volume
454 null, // no permission for changing voice volume
455 null, // no permission for changing ring volume
456 null, // no permission for changing media volume
457 null, // no permission for changing alarm volume
458 null, // no permission for changing notification volume
459 null, // no permission for changing bluetooth volume
Dianne Hackborn713df152013-05-17 11:27:57 -0700460 android.Manifest.permission.WAKE_LOCK,
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700461 null, // no permission for generic location monitoring
David Christie0b837452013-07-29 16:02:13 -0700462 null, // no permission for high power location monitoring
Dianne Hackborne22b3b12014-05-07 18:06:44 -0700463 android.Manifest.permission.PACKAGE_USAGE_STATS,
Emily Bernier22c921a2014-05-28 11:01:32 -0400464 null, // no permission for muting/unmuting microphone
Jason Monk1c7c3192014-06-26 12:52:18 -0400465 null, // no permission for displaying toasts
Michael Wrightc39d47a2014-07-08 18:07:36 -0700466 null, // no permission for projecting media
Jeff Davidson05542602014-08-11 14:07:27 -0700467 null, // no permission for activating vpn
Benjamin Franzf3ece362015-02-11 10:51:10 +0000468 null, // no permission for supporting wallpaper
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700469 null, // no permission for receiving assist structure
470 null, // no permission for receiving assist screenshot
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800471 };
472
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800473 /**
Jason Monk62062992014-05-06 09:55:28 -0400474 * Specifies whether an Op should be restricted by a user restriction.
475 * Each Op should be filled with a restriction string from UserManager or
476 * null to specify it is not affected by any user restriction.
477 */
478 private static String[] sOpRestrictions = new String[] {
Julia Reynolds9854d572014-07-02 14:46:02 -0400479 UserManager.DISALLOW_SHARE_LOCATION, //COARSE_LOCATION
480 UserManager.DISALLOW_SHARE_LOCATION, //FINE_LOCATION
481 UserManager.DISALLOW_SHARE_LOCATION, //GPS
Jason Monk62062992014-05-06 09:55:28 -0400482 null, //VIBRATE
483 null, //READ_CONTACTS
484 null, //WRITE_CONTACTS
Yorke Lee15f83c62014-08-13 14:14:29 -0700485 UserManager.DISALLOW_OUTGOING_CALLS, //READ_CALL_LOG
486 UserManager.DISALLOW_OUTGOING_CALLS, //WRITE_CALL_LOG
Jason Monk62062992014-05-06 09:55:28 -0400487 null, //READ_CALENDAR
488 null, //WRITE_CALENDAR
Julia Reynolds9854d572014-07-02 14:46:02 -0400489 UserManager.DISALLOW_SHARE_LOCATION, //WIFI_SCAN
Jason Monk62062992014-05-06 09:55:28 -0400490 null, //POST_NOTIFICATION
491 null, //NEIGHBORING_CELLS
492 null, //CALL_PHONE
Amith Yamasani41c1ded2014-08-05 11:15:05 -0700493 UserManager.DISALLOW_SMS, //READ_SMS
494 UserManager.DISALLOW_SMS, //WRITE_SMS
495 UserManager.DISALLOW_SMS, //RECEIVE_SMS
496 null, //RECEIVE_EMERGENCY_SMS
497 UserManager.DISALLOW_SMS, //RECEIVE_MMS
Jason Monk62062992014-05-06 09:55:28 -0400498 null, //RECEIVE_WAP_PUSH
Amith Yamasani41c1ded2014-08-05 11:15:05 -0700499 UserManager.DISALLOW_SMS, //SEND_SMS
500 UserManager.DISALLOW_SMS, //READ_ICC_SMS
501 UserManager.DISALLOW_SMS, //WRITE_ICC_SMS
Jason Monk62062992014-05-06 09:55:28 -0400502 null, //WRITE_SETTINGS
Jason Monk1c7c3192014-06-26 12:52:18 -0400503 UserManager.DISALLOW_CREATE_WINDOWS, //SYSTEM_ALERT_WINDOW
Jason Monk62062992014-05-06 09:55:28 -0400504 null, //ACCESS_NOTIFICATIONS
505 null, //CAMERA
506 null, //RECORD_AUDIO
507 null, //PLAY_AUDIO
508 null, //READ_CLIPBOARD
509 null, //WRITE_CLIPBOARD
510 null, //TAKE_MEDIA_BUTTONS
511 null, //TAKE_AUDIO_FOCUS
Emily Bernier45775c42014-05-16 15:12:04 -0400512 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MASTER_VOLUME
513 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_VOICE_VOLUME
514 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_RING_VOLUME
515 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MEDIA_VOLUME
516 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ALARM_VOLUME
517 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_NOTIFICATION_VOLUME
518 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_BLUETOOTH_VOLUME
Jason Monk62062992014-05-06 09:55:28 -0400519 null, //WAKE_LOCK
Julia Reynolds9854d572014-07-02 14:46:02 -0400520 UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_LOCATION
521 UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_HIGH_POWER_LOCATION
Jason Monk62062992014-05-06 09:55:28 -0400522 null, //GET_USAGE_STATS
Emily Bernier22c921a2014-05-28 11:01:32 -0400523 UserManager.DISALLOW_UNMUTE_MICROPHONE, // MUTE_MICROPHONE
Jason Monk1c7c3192014-06-26 12:52:18 -0400524 UserManager.DISALLOW_CREATE_WINDOWS, // TOAST_WINDOW
Michael Wrightc39d47a2014-07-08 18:07:36 -0700525 null, //PROJECT_MEDIA
Jeff Davidson05542602014-08-11 14:07:27 -0700526 UserManager.DISALLOW_CONFIG_VPN, // ACTIVATE_VPN
Benjamin Franzf3ece362015-02-11 10:51:10 +0000527 UserManager.DISALLOW_WALLPAPER, // WRITE_WALLPAPER
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700528 null, // ASSIST_STRUCTURE
529 null, // ASSIST_SCREENSHOT
Jason Monk1c7c3192014-06-26 12:52:18 -0400530 };
531
532 /**
533 * This specifies whether each option should allow the system
534 * (and system ui) to bypass the user restriction when active.
535 */
536 private static boolean[] sOpAllowSystemRestrictionBypass = new boolean[] {
537 false, //COARSE_LOCATION
538 false, //FINE_LOCATION
539 false, //GPS
540 false, //VIBRATE
541 false, //READ_CONTACTS
542 false, //WRITE_CONTACTS
543 false, //READ_CALL_LOG
544 false, //WRITE_CALL_LOG
545 false, //READ_CALENDAR
546 false, //WRITE_CALENDAR
Julia Reynolds9854d572014-07-02 14:46:02 -0400547 true, //WIFI_SCAN
Jason Monk1c7c3192014-06-26 12:52:18 -0400548 false, //POST_NOTIFICATION
549 false, //NEIGHBORING_CELLS
550 false, //CALL_PHONE
551 false, //READ_SMS
552 false, //WRITE_SMS
553 false, //RECEIVE_SMS
554 false, //RECEIVE_EMERGECY_SMS
555 false, //RECEIVE_MMS
556 false, //RECEIVE_WAP_PUSH
557 false, //SEND_SMS
558 false, //READ_ICC_SMS
559 false, //WRITE_ICC_SMS
560 false, //WRITE_SETTINGS
561 true, //SYSTEM_ALERT_WINDOW
562 false, //ACCESS_NOTIFICATIONS
563 false, //CAMERA
564 false, //RECORD_AUDIO
565 false, //PLAY_AUDIO
566 false, //READ_CLIPBOARD
567 false, //WRITE_CLIPBOARD
568 false, //TAKE_MEDIA_BUTTONS
569 false, //TAKE_AUDIO_FOCUS
570 false, //AUDIO_MASTER_VOLUME
571 false, //AUDIO_VOICE_VOLUME
572 false, //AUDIO_RING_VOLUME
573 false, //AUDIO_MEDIA_VOLUME
574 false, //AUDIO_ALARM_VOLUME
575 false, //AUDIO_NOTIFICATION_VOLUME
576 false, //AUDIO_BLUETOOTH_VOLUME
577 false, //WAKE_LOCK
578 false, //MONITOR_LOCATION
579 false, //MONITOR_HIGH_POWER_LOCATION
580 false, //GET_USAGE_STATS
Michael Wrightc39d47a2014-07-08 18:07:36 -0700581 false, //MUTE_MICROPHONE
582 true, //TOAST_WINDOW
583 false, //PROJECT_MEDIA
Jeff Davidson05542602014-08-11 14:07:27 -0700584 false, //ACTIVATE_VPN
Benjamin Franzf3ece362015-02-11 10:51:10 +0000585 false, //WALLPAPER
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700586 false, //ASSIST_STRUCTURE
587 false, //ASSIST_SCREENSHOT
Jason Monk62062992014-05-06 09:55:28 -0400588 };
589
590 /**
David Braunf5d83192013-09-16 13:43:51 -0700591 * This specifies the default mode for each operation.
592 */
593 private static int[] sOpDefaultMode = new int[] {
594 AppOpsManager.MODE_ALLOWED,
595 AppOpsManager.MODE_ALLOWED,
596 AppOpsManager.MODE_ALLOWED,
597 AppOpsManager.MODE_ALLOWED,
598 AppOpsManager.MODE_ALLOWED,
599 AppOpsManager.MODE_ALLOWED,
600 AppOpsManager.MODE_ALLOWED,
601 AppOpsManager.MODE_ALLOWED,
602 AppOpsManager.MODE_ALLOWED,
603 AppOpsManager.MODE_ALLOWED,
604 AppOpsManager.MODE_ALLOWED,
605 AppOpsManager.MODE_ALLOWED,
606 AppOpsManager.MODE_ALLOWED,
607 AppOpsManager.MODE_ALLOWED,
608 AppOpsManager.MODE_ALLOWED,
609 AppOpsManager.MODE_IGNORED, // OP_WRITE_SMS
610 AppOpsManager.MODE_ALLOWED,
611 AppOpsManager.MODE_ALLOWED,
612 AppOpsManager.MODE_ALLOWED,
613 AppOpsManager.MODE_ALLOWED,
614 AppOpsManager.MODE_ALLOWED,
615 AppOpsManager.MODE_ALLOWED,
616 AppOpsManager.MODE_ALLOWED,
617 AppOpsManager.MODE_ALLOWED,
618 AppOpsManager.MODE_ALLOWED,
619 AppOpsManager.MODE_ALLOWED,
620 AppOpsManager.MODE_ALLOWED,
621 AppOpsManager.MODE_ALLOWED,
622 AppOpsManager.MODE_ALLOWED,
623 AppOpsManager.MODE_ALLOWED,
624 AppOpsManager.MODE_ALLOWED,
625 AppOpsManager.MODE_ALLOWED,
626 AppOpsManager.MODE_ALLOWED,
627 AppOpsManager.MODE_ALLOWED,
628 AppOpsManager.MODE_ALLOWED,
629 AppOpsManager.MODE_ALLOWED,
630 AppOpsManager.MODE_ALLOWED,
631 AppOpsManager.MODE_ALLOWED,
632 AppOpsManager.MODE_ALLOWED,
633 AppOpsManager.MODE_ALLOWED,
634 AppOpsManager.MODE_ALLOWED,
635 AppOpsManager.MODE_ALLOWED,
636 AppOpsManager.MODE_ALLOWED,
Dianne Hackborn33f5ddd2014-07-21 15:35:45 -0700637 AppOpsManager.MODE_DEFAULT, // OP_GET_USAGE_STATS
Emily Bernier22c921a2014-05-28 11:01:32 -0400638 AppOpsManager.MODE_ALLOWED,
Jason Monk1c7c3192014-06-26 12:52:18 -0400639 AppOpsManager.MODE_ALLOWED,
Michael Wrightc39d47a2014-07-08 18:07:36 -0700640 AppOpsManager.MODE_IGNORED, // OP_PROJECT_MEDIA
Jeff Davidson05542602014-08-11 14:07:27 -0700641 AppOpsManager.MODE_IGNORED, // OP_ACTIVATE_VPN
Benjamin Franzf3ece362015-02-11 10:51:10 +0000642 AppOpsManager.MODE_ALLOWED,
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700643 AppOpsManager.MODE_ALLOWED,
644 AppOpsManager.MODE_ALLOWED,
David Braunf5d83192013-09-16 13:43:51 -0700645 };
646
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700647 /**
648 * This specifies whether each option is allowed to be reset
649 * when resetting all app preferences. Disable reset for
650 * app ops that are under strong control of some part of the
651 * system (such as OP_WRITE_SMS, which should be allowed only
652 * for whichever app is selected as the current SMS app).
653 */
654 private static boolean[] sOpDisableReset = new boolean[] {
655 false,
656 false,
657 false,
658 false,
659 false,
660 false,
661 false,
662 false,
663 false,
664 false,
665 false,
666 false,
667 false,
668 false,
669 false,
670 true, // OP_WRITE_SMS
671 false,
672 false,
673 false,
674 false,
675 false,
676 false,
677 false,
678 false,
679 false,
680 false,
681 false,
682 false,
683 false,
684 false,
685 false,
686 false,
687 false,
688 false,
689 false,
690 false,
691 false,
692 false,
693 false,
694 false,
695 false,
696 false,
697 false,
Dianne Hackborne22b3b12014-05-07 18:06:44 -0700698 false,
Emily Bernier22c921a2014-05-28 11:01:32 -0400699 false,
Jason Monk1c7c3192014-06-26 12:52:18 -0400700 false,
Michael Wrightc39d47a2014-07-08 18:07:36 -0700701 false,
Jeff Davidson05542602014-08-11 14:07:27 -0700702 false,
Benjamin Franzf3ece362015-02-11 10:51:10 +0000703 false,
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700704 false,
705 false,
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700706 };
707
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700708 private static HashMap<String, Integer> sOpStrToOp = new HashMap<String, Integer>();
709
710 static {
711 if (sOpToSwitch.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700712 throw new IllegalStateException("sOpToSwitch length " + sOpToSwitch.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700713 + " should be " + _NUM_OP);
714 }
715 if (sOpToString.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700716 throw new IllegalStateException("sOpToString length " + sOpToString.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700717 + " should be " + _NUM_OP);
718 }
719 if (sOpNames.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700720 throw new IllegalStateException("sOpNames length " + sOpNames.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700721 + " should be " + _NUM_OP);
722 }
723 if (sOpPerms.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700724 throw new IllegalStateException("sOpPerms length " + sOpPerms.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700725 + " should be " + _NUM_OP);
726 }
727 if (sOpDefaultMode.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700728 throw new IllegalStateException("sOpDefaultMode length " + sOpDefaultMode.length
729 + " should be " + _NUM_OP);
730 }
731 if (sOpDisableReset.length != _NUM_OP) {
732 throw new IllegalStateException("sOpDisableReset length " + sOpDisableReset.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700733 + " should be " + _NUM_OP);
734 }
Jason Monk62062992014-05-06 09:55:28 -0400735 if (sOpRestrictions.length != _NUM_OP) {
736 throw new IllegalStateException("sOpRestrictions length " + sOpRestrictions.length
737 + " should be " + _NUM_OP);
738 }
Jason Monk1c7c3192014-06-26 12:52:18 -0400739 if (sOpAllowSystemRestrictionBypass.length != _NUM_OP) {
740 throw new IllegalStateException("sOpAllowSYstemRestrictionsBypass length "
741 + sOpRestrictions.length + " should be " + _NUM_OP);
742 }
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700743 for (int i=0; i<_NUM_OP; i++) {
744 if (sOpToString[i] != null) {
745 sOpStrToOp.put(sOpToString[i], i);
746 }
747 }
748 }
749
David Braunf5d83192013-09-16 13:43:51 -0700750 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800751 * Retrieve the op switch that controls the given operation.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700752 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800753 */
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800754 public static int opToSwitch(int op) {
755 return sOpToSwitch[op];
756 }
757
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800758 /**
759 * Retrieve a non-localized name for the operation, for debugging output.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700760 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800761 */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800762 public static String opToName(int op) {
Dianne Hackbornc2293022013-02-06 23:14:49 -0800763 if (op == OP_NONE) return "NONE";
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800764 return op < sOpNames.length ? sOpNames[op] : ("Unknown(" + op + ")");
765 }
766
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800767 /**
Dianne Hackborn7b7c58b2014-12-02 18:32:20 -0800768 * @hide
769 */
770 public static int strDebugOpToOp(String op) {
771 for (int i=0; i<sOpNames.length; i++) {
772 if (sOpNames[i].equals(op)) {
773 return i;
774 }
775 }
776 throw new IllegalArgumentException("Unknown operation string: " + op);
777 }
778
779 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800780 * Retrieve the permission associated with an operation, or null if there is not one.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700781 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800782 */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800783 public static String opToPermission(int op) {
784 return sOpPerms[op];
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800785 }
786
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800787 /**
Jason Monk62062992014-05-06 09:55:28 -0400788 * Retrieve the user restriction associated with an operation, or null if there is not one.
789 * @hide
790 */
791 public static String opToRestriction(int op) {
792 return sOpRestrictions[op];
793 }
794
795 /**
Jason Monk1c7c3192014-06-26 12:52:18 -0400796 * Retrieve whether the op allows the system (and system ui) to
797 * bypass the user restriction.
798 * @hide
799 */
800 public static boolean opAllowSystemBypassRestriction(int op) {
801 return sOpAllowSystemRestrictionBypass[op];
802 }
803
804 /**
David Braunf5d83192013-09-16 13:43:51 -0700805 * Retrieve the default mode for the operation.
806 * @hide
807 */
808 public static int opToDefaultMode(int op) {
809 return sOpDefaultMode[op];
810 }
811
812 /**
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700813 * Retrieve whether the op allows itself to be reset.
814 * @hide
815 */
816 public static boolean opAllowsReset(int op) {
817 return !sOpDisableReset[op];
818 }
819
820 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800821 * Class holding all of the operation information associated with an app.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700822 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800823 */
Dianne Hackborn35654b62013-01-14 17:38:02 -0800824 public static class PackageOps implements Parcelable {
825 private final String mPackageName;
826 private final int mUid;
827 private final List<OpEntry> mEntries;
828
829 public PackageOps(String packageName, int uid, List<OpEntry> entries) {
830 mPackageName = packageName;
831 mUid = uid;
832 mEntries = entries;
833 }
834
835 public String getPackageName() {
836 return mPackageName;
837 }
838
839 public int getUid() {
840 return mUid;
841 }
842
843 public List<OpEntry> getOps() {
844 return mEntries;
845 }
846
847 @Override
848 public int describeContents() {
849 return 0;
850 }
851
852 @Override
853 public void writeToParcel(Parcel dest, int flags) {
854 dest.writeString(mPackageName);
855 dest.writeInt(mUid);
856 dest.writeInt(mEntries.size());
857 for (int i=0; i<mEntries.size(); i++) {
858 mEntries.get(i).writeToParcel(dest, flags);
859 }
860 }
861
862 PackageOps(Parcel source) {
863 mPackageName = source.readString();
864 mUid = source.readInt();
865 mEntries = new ArrayList<OpEntry>();
866 final int N = source.readInt();
867 for (int i=0; i<N; i++) {
868 mEntries.add(OpEntry.CREATOR.createFromParcel(source));
869 }
870 }
871
872 public static final Creator<PackageOps> CREATOR = new Creator<PackageOps>() {
873 @Override public PackageOps createFromParcel(Parcel source) {
874 return new PackageOps(source);
875 }
876
877 @Override public PackageOps[] newArray(int size) {
878 return new PackageOps[size];
879 }
880 };
881 }
882
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800883 /**
884 * Class holding the information about one unique operation of an application.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700885 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800886 */
Dianne Hackborn35654b62013-01-14 17:38:02 -0800887 public static class OpEntry implements Parcelable {
888 private final int mOp;
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800889 private final int mMode;
Dianne Hackborn35654b62013-01-14 17:38:02 -0800890 private final long mTime;
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800891 private final long mRejectTime;
Dianne Hackborn35654b62013-01-14 17:38:02 -0800892 private final int mDuration;
893
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800894 public OpEntry(int op, int mode, long time, long rejectTime, int duration) {
Dianne Hackborn35654b62013-01-14 17:38:02 -0800895 mOp = op;
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800896 mMode = mode;
Dianne Hackborn35654b62013-01-14 17:38:02 -0800897 mTime = time;
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800898 mRejectTime = rejectTime;
Dianne Hackborn35654b62013-01-14 17:38:02 -0800899 mDuration = duration;
900 }
901
902 public int getOp() {
903 return mOp;
904 }
905
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800906 public int getMode() {
907 return mMode;
908 }
909
Dianne Hackborn35654b62013-01-14 17:38:02 -0800910 public long getTime() {
911 return mTime;
912 }
913
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800914 public long getRejectTime() {
915 return mRejectTime;
916 }
917
Dianne Hackborn35654b62013-01-14 17:38:02 -0800918 public boolean isRunning() {
919 return mDuration == -1;
920 }
921
922 public int getDuration() {
923 return mDuration == -1 ? (int)(System.currentTimeMillis()-mTime) : mDuration;
924 }
925
926 @Override
927 public int describeContents() {
928 return 0;
929 }
930
931 @Override
932 public void writeToParcel(Parcel dest, int flags) {
933 dest.writeInt(mOp);
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800934 dest.writeInt(mMode);
Dianne Hackborn35654b62013-01-14 17:38:02 -0800935 dest.writeLong(mTime);
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800936 dest.writeLong(mRejectTime);
Dianne Hackborn35654b62013-01-14 17:38:02 -0800937 dest.writeInt(mDuration);
938 }
939
940 OpEntry(Parcel source) {
941 mOp = source.readInt();
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800942 mMode = source.readInt();
Dianne Hackborn35654b62013-01-14 17:38:02 -0800943 mTime = source.readLong();
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800944 mRejectTime = source.readLong();
Dianne Hackborn35654b62013-01-14 17:38:02 -0800945 mDuration = source.readInt();
946 }
947
948 public static final Creator<OpEntry> CREATOR = new Creator<OpEntry>() {
949 @Override public OpEntry createFromParcel(Parcel source) {
950 return new OpEntry(source);
951 }
952
953 @Override public OpEntry[] newArray(int size) {
954 return new OpEntry[size];
955 }
956 };
957 }
958
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800959 /**
960 * Callback for notification of changes to operation state.
961 */
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700962 public interface OnOpChangedListener {
963 public void onOpChanged(String op, String packageName);
964 }
965
966 /**
967 * Callback for notification of changes to operation state.
968 * This allows you to see the raw op codes instead of strings.
969 * @hide
970 */
971 public static class OnOpChangedInternalListener implements OnOpChangedListener {
972 public void onOpChanged(String op, String packageName) { }
973 public void onOpChanged(int op, String packageName) { }
Dianne Hackbornc2293022013-02-06 23:14:49 -0800974 }
975
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700976 AppOpsManager(Context context, IAppOpsService service) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800977 mContext = context;
978 mService = service;
979 }
980
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800981 /**
982 * Retrieve current operation state for all applications.
983 *
984 * @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 -0700985 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800986 */
Dianne Hackborn35654b62013-01-14 17:38:02 -0800987 public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) {
988 try {
989 return mService.getPackagesForOps(ops);
990 } catch (RemoteException e) {
991 }
992 return null;
993 }
994
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800995 /**
996 * Retrieve current operation state for one application.
997 *
998 * @param uid The uid of the application of interest.
999 * @param packageName The name of the application of interest.
1000 * @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 -07001001 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001002 */
Dianne Hackborn72e39832013-01-18 18:36:09 -08001003 public List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, int[] ops) {
1004 try {
1005 return mService.getOpsForPackage(uid, packageName, ops);
1006 } catch (RemoteException e) {
1007 }
1008 return null;
1009 }
1010
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001011 /** @hide */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001012 public void setMode(int code, int uid, String packageName, int mode) {
1013 try {
1014 mService.setMode(code, uid, packageName, mode);
1015 } catch (RemoteException e) {
1016 }
1017 }
1018
John Spurlock1af30c72014-03-10 08:33:35 -04001019 /**
1020 * Set a non-persisted restriction on an audio operation at a stream-level.
1021 * Restrictions are temporary additional constraints imposed on top of the persisted rules
1022 * defined by {@link #setMode}.
1023 *
1024 * @param code The operation to restrict.
John Spurlock7b414672014-07-18 13:02:39 -04001025 * @param usage The {@link android.media.AudioAttributes} usage value.
John Spurlock1af30c72014-03-10 08:33:35 -04001026 * @param mode The restriction mode (MODE_IGNORED,MODE_ERRORED) or MODE_ALLOWED to unrestrict.
1027 * @param exceptionPackages Optional list of packages to exclude from the restriction.
1028 * @hide
1029 */
John Spurlock7b414672014-07-18 13:02:39 -04001030 public void setRestriction(int code, @AttributeUsage int usage, int mode,
1031 String[] exceptionPackages) {
John Spurlock1af30c72014-03-10 08:33:35 -04001032 try {
1033 final int uid = Binder.getCallingUid();
John Spurlock7b414672014-07-18 13:02:39 -04001034 mService.setAudioRestriction(code, usage, uid, mode, exceptionPackages);
John Spurlock1af30c72014-03-10 08:33:35 -04001035 } catch (RemoteException e) {
1036 }
1037 }
1038
Dianne Hackborn607b4142013-08-02 18:10:10 -07001039 /** @hide */
1040 public void resetAllModes() {
1041 try {
Dianne Hackborn7b7c58b2014-12-02 18:32:20 -08001042 mService.resetAllModes(UserHandle.myUserId(), null);
Dianne Hackborn607b4142013-08-02 18:10:10 -07001043 } catch (RemoteException e) {
1044 }
1045 }
1046
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001047 /**
1048 * Monitor for changes to the operating mode for the given op in the given app package.
Dianne Hackborne4cb66f2013-10-02 10:34:02 -07001049 * @param op The operation to monitor, one of OPSTR_*.
1050 * @param packageName The name of the application to monitor.
1051 * @param callback Where to report changes.
1052 */
1053 public void startWatchingMode(String op, String packageName,
1054 final OnOpChangedListener callback) {
1055 startWatchingMode(strOpToOp(op), packageName, callback);
1056 }
1057
1058 /**
1059 * Monitor for changes to the operating mode for the given op in the given app package.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001060 * @param op The operation to monitor, one of OP_*.
1061 * @param packageName The name of the application to monitor.
1062 * @param callback Where to report changes.
Dianne Hackborne4cb66f2013-10-02 10:34:02 -07001063 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001064 */
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001065 public void startWatchingMode(int op, String packageName, final OnOpChangedListener callback) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08001066 synchronized (mModeWatchers) {
1067 IAppOpsCallback cb = mModeWatchers.get(callback);
1068 if (cb == null) {
1069 cb = new IAppOpsCallback.Stub() {
1070 public void opChanged(int op, String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001071 if (callback instanceof OnOpChangedInternalListener) {
1072 ((OnOpChangedInternalListener)callback).onOpChanged(op, packageName);
1073 }
1074 if (sOpToString[op] != null) {
1075 callback.onOpChanged(sOpToString[op], packageName);
1076 }
Dianne Hackbornc2293022013-02-06 23:14:49 -08001077 }
1078 };
1079 mModeWatchers.put(callback, cb);
1080 }
1081 try {
1082 mService.startWatchingMode(op, packageName, cb);
1083 } catch (RemoteException e) {
1084 }
1085 }
1086 }
1087
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001088 /**
1089 * Stop monitoring that was previously started with {@link #startWatchingMode}. All
1090 * monitoring associated with this callback will be removed.
1091 */
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001092 public void stopWatchingMode(OnOpChangedListener callback) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08001093 synchronized (mModeWatchers) {
1094 IAppOpsCallback cb = mModeWatchers.get(callback);
1095 if (cb != null) {
1096 try {
1097 mService.stopWatchingMode(cb);
1098 } catch (RemoteException e) {
1099 }
1100 }
1101 }
1102 }
1103
Dianne Hackborn95d78532013-09-11 09:51:14 -07001104 private String buildSecurityExceptionMsg(int op, int uid, String packageName) {
1105 return packageName + " from uid " + uid + " not allowed to perform " + sOpNames[op];
1106 }
1107
Adam Lesinskib5cf61b2014-08-18 16:10:28 -07001108 /**
1109 * {@hide}
1110 */
1111 public static int strOpToOp(String op) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001112 Integer val = sOpStrToOp.get(op);
1113 if (val == null) {
1114 throw new IllegalArgumentException("Unknown operation string: " + op);
1115 }
1116 return val;
1117 }
1118
1119 /**
1120 * Do a quick check for whether an application might be able to perform an operation.
1121 * This is <em>not</em> a security check; you must use {@link #noteOp(String, int, String)}
1122 * or {@link #startOp(String, int, String)} for your actual security checks, which also
1123 * ensure that the given uid and package name are consistent. This function can just be
1124 * used for a quick check to see if an operation has been disabled for the application,
1125 * as an early reject of some work. This does not modify the time stamp or other data
1126 * about the operation.
1127 * @param op The operation to check. One of the OPSTR_* constants.
1128 * @param uid The user id of the application attempting to perform the operation.
1129 * @param packageName The name of the application attempting to perform the operation.
1130 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1131 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1132 * causing the app to crash).
1133 * @throws SecurityException If the app has been configured to crash on this op.
1134 */
1135 public int checkOp(String op, int uid, String packageName) {
1136 return checkOp(strOpToOp(op), uid, packageName);
1137 }
1138
1139 /**
John Spurlock925b85e2014-03-10 16:52:11 -04001140 * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001141 * returns {@link #MODE_ERRORED}.
1142 */
1143 public int checkOpNoThrow(String op, int uid, String packageName) {
1144 return checkOpNoThrow(strOpToOp(op), uid, packageName);
1145 }
1146
1147 /**
1148 * Make note of an application performing an operation. Note that you must pass
1149 * in both the uid and name of the application to be checked; this function will verify
1150 * that these two match, and if not, return {@link #MODE_IGNORED}. If this call
1151 * succeeds, the last execution time of the operation for this app will be updated to
1152 * the current time.
1153 * @param op The operation to note. One of the OPSTR_* constants.
1154 * @param uid The user id of the application attempting to perform the operation.
1155 * @param packageName The name of the application attempting to perform the operation.
1156 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1157 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1158 * causing the app to crash).
1159 * @throws SecurityException If the app has been configured to crash on this op.
1160 */
1161 public int noteOp(String op, int uid, String packageName) {
1162 return noteOp(strOpToOp(op), uid, packageName);
1163 }
1164
1165 /**
1166 * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
1167 * returns {@link #MODE_ERRORED}.
1168 */
1169 public int noteOpNoThrow(String op, int uid, String packageName) {
1170 return noteOpNoThrow(strOpToOp(op), uid, packageName);
1171 }
1172
1173 /**
1174 * Report that an application has started executing a long-running operation. Note that you
1175 * must pass in both the uid and name of the application to be checked; this function will
1176 * verify that these two match, and if not, return {@link #MODE_IGNORED}. If this call
1177 * succeeds, the last execution time of the operation for this app will be updated to
1178 * the current time and the operation will be marked as "running". In this case you must
1179 * later call {@link #finishOp(String, int, String)} to report when the application is no
1180 * longer performing the operation.
1181 * @param op The operation to start. One of the OPSTR_* constants.
1182 * @param uid The user id of the application attempting to perform the operation.
1183 * @param packageName The name of the application attempting to perform the operation.
1184 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1185 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1186 * causing the app to crash).
1187 * @throws SecurityException If the app has been configured to crash on this op.
1188 */
1189 public int startOp(String op, int uid, String packageName) {
1190 return startOp(strOpToOp(op), uid, packageName);
1191 }
1192
1193 /**
1194 * Like {@link #startOp} but instead of throwing a {@link SecurityException} it
1195 * returns {@link #MODE_ERRORED}.
1196 */
1197 public int startOpNoThrow(String op, int uid, String packageName) {
1198 return startOpNoThrow(strOpToOp(op), uid, packageName);
1199 }
1200
1201 /**
1202 * Report that an application is no longer performing an operation that had previously
1203 * been started with {@link #startOp(String, int, String)}. There is no validation of input
1204 * or result; the parameters supplied here must be the exact same ones previously passed
1205 * in when starting the operation.
1206 */
1207 public void finishOp(String op, int uid, String packageName) {
1208 finishOp(strOpToOp(op), uid, packageName);
1209 }
1210
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001211 /**
1212 * Do a quick check for whether an application might be able to perform an operation.
1213 * This is <em>not</em> a security check; you must use {@link #noteOp(int, int, String)}
1214 * or {@link #startOp(int, int, String)} for your actual security checks, which also
1215 * ensure that the given uid and package name are consistent. This function can just be
1216 * used for a quick check to see if an operation has been disabled for the application,
1217 * as an early reject of some work. This does not modify the time stamp or other data
1218 * about the operation.
1219 * @param op The operation to check. One of the OP_* constants.
1220 * @param uid The user id of the application attempting to perform the operation.
1221 * @param packageName The name of the application attempting to perform the operation.
1222 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1223 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1224 * causing the app to crash).
1225 * @throws SecurityException If the app has been configured to crash on this op.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001226 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001227 */
Dianne Hackborn35654b62013-01-14 17:38:02 -08001228 public int checkOp(int op, int uid, String packageName) {
1229 try {
1230 int mode = mService.checkOperation(op, uid, packageName);
1231 if (mode == MODE_ERRORED) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07001232 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborn35654b62013-01-14 17:38:02 -08001233 }
1234 return mode;
1235 } catch (RemoteException e) {
1236 }
1237 return MODE_IGNORED;
1238 }
1239
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001240 /**
1241 * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
1242 * returns {@link #MODE_ERRORED}.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001243 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001244 */
Dianne Hackborn35654b62013-01-14 17:38:02 -08001245 public int checkOpNoThrow(int op, int uid, String packageName) {
1246 try {
1247 return mService.checkOperation(op, uid, packageName);
1248 } catch (RemoteException e) {
1249 }
1250 return MODE_IGNORED;
1251 }
1252
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001253 /**
Jeff Sharkey911d7f42013-09-05 18:11:45 -07001254 * Do a quick check to validate if a package name belongs to a UID.
1255 *
1256 * @throws SecurityException if the package name doesn't belong to the given
1257 * UID, or if ownership cannot be verified.
1258 */
1259 public void checkPackage(int uid, String packageName) {
1260 try {
1261 if (mService.checkPackage(uid, packageName) != MODE_ALLOWED) {
1262 throw new SecurityException(
1263 "Package " + packageName + " does not belong to " + uid);
1264 }
1265 } catch (RemoteException e) {
1266 throw new SecurityException("Unable to verify package ownership", e);
1267 }
1268 }
1269
1270 /**
John Spurlock1af30c72014-03-10 08:33:35 -04001271 * Like {@link #checkOp} but at a stream-level for audio operations.
1272 * @hide
1273 */
1274 public int checkAudioOp(int op, int stream, int uid, String packageName) {
1275 try {
1276 final int mode = mService.checkAudioOperation(op, stream, uid, packageName);
1277 if (mode == MODE_ERRORED) {
1278 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
1279 }
1280 return mode;
1281 } catch (RemoteException e) {
1282 }
1283 return MODE_IGNORED;
1284 }
1285
1286 /**
1287 * Like {@link #checkAudioOp} but instead of throwing a {@link SecurityException} it
1288 * returns {@link #MODE_ERRORED}.
1289 * @hide
1290 */
1291 public int checkAudioOpNoThrow(int op, int stream, int uid, String packageName) {
1292 try {
1293 return mService.checkAudioOperation(op, stream, uid, packageName);
1294 } catch (RemoteException e) {
1295 }
1296 return MODE_IGNORED;
1297 }
1298
1299 /**
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001300 * Make note of an application performing an operation. Note that you must pass
1301 * in both the uid and name of the application to be checked; this function will verify
1302 * that these two match, and if not, return {@link #MODE_IGNORED}. If this call
1303 * succeeds, the last execution time of the operation for this app will be updated to
1304 * the current time.
1305 * @param op The operation to note. One of the OP_* constants.
1306 * @param uid The user id of the application attempting to perform the operation.
1307 * @param packageName The name of the application attempting to perform the operation.
1308 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1309 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1310 * causing the app to crash).
1311 * @throws SecurityException If the app has been configured to crash on this op.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001312 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001313 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001314 public int noteOp(int op, int uid, String packageName) {
1315 try {
1316 int mode = mService.noteOperation(op, uid, packageName);
1317 if (mode == MODE_ERRORED) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07001318 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001319 }
1320 return mode;
1321 } catch (RemoteException e) {
1322 }
1323 return MODE_IGNORED;
1324 }
1325
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001326 /**
1327 * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
1328 * returns {@link #MODE_ERRORED}.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001329 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001330 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001331 public int noteOpNoThrow(int op, int uid, String packageName) {
1332 try {
1333 return mService.noteOperation(op, uid, packageName);
1334 } catch (RemoteException e) {
1335 }
1336 return MODE_IGNORED;
1337 }
1338
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001339 /** @hide */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001340 public int noteOp(int op) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07001341 return noteOp(op, Process.myUid(), mContext.getOpPackageName());
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001342 }
1343
Dianne Hackborne98f5db2013-07-17 17:23:25 -07001344 /** @hide */
1345 public static IBinder getToken(IAppOpsService service) {
1346 synchronized (AppOpsManager.class) {
1347 if (sToken != null) {
1348 return sToken;
1349 }
1350 try {
1351 sToken = service.getToken(new Binder());
1352 } catch (RemoteException e) {
1353 // System is dead, whatevs.
1354 }
1355 return sToken;
1356 }
1357 }
1358
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001359 /**
1360 * Report that an application has started executing a long-running operation. Note that you
1361 * must pass in both the uid and name of the application to be checked; this function will
1362 * verify that these two match, and if not, return {@link #MODE_IGNORED}. If this call
1363 * succeeds, the last execution time of the operation for this app will be updated to
1364 * the current time and the operation will be marked as "running". In this case you must
1365 * later call {@link #finishOp(int, int, String)} to report when the application is no
1366 * longer performing the operation.
1367 * @param op The operation to start. One of the OP_* constants.
1368 * @param uid The user id of the application attempting to perform the operation.
1369 * @param packageName The name of the application attempting to perform the operation.
1370 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1371 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1372 * causing the app to crash).
1373 * @throws SecurityException If the app has been configured to crash on this op.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001374 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001375 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001376 public int startOp(int op, int uid, String packageName) {
1377 try {
Dianne Hackborne98f5db2013-07-17 17:23:25 -07001378 int mode = mService.startOperation(getToken(mService), op, uid, packageName);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001379 if (mode == MODE_ERRORED) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07001380 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001381 }
1382 return mode;
1383 } catch (RemoteException e) {
1384 }
1385 return MODE_IGNORED;
1386 }
1387
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001388 /**
1389 * Like {@link #startOp} but instead of throwing a {@link SecurityException} it
1390 * returns {@link #MODE_ERRORED}.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001391 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001392 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001393 public int startOpNoThrow(int op, int uid, String packageName) {
1394 try {
Dianne Hackborne98f5db2013-07-17 17:23:25 -07001395 return mService.startOperation(getToken(mService), op, uid, packageName);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001396 } catch (RemoteException e) {
1397 }
1398 return MODE_IGNORED;
1399 }
1400
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001401 /** @hide */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001402 public int startOp(int op) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07001403 return startOp(op, Process.myUid(), mContext.getOpPackageName());
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001404 }
1405
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001406 /**
1407 * Report that an application is no longer performing an operation that had previously
1408 * been started with {@link #startOp(int, int, String)}. There is no validation of input
1409 * or result; the parameters supplied here must be the exact same ones previously passed
1410 * in when starting the operation.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001411 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001412 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001413 public void finishOp(int op, int uid, String packageName) {
1414 try {
Dianne Hackborne98f5db2013-07-17 17:23:25 -07001415 mService.finishOperation(getToken(mService), op, uid, packageName);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001416 } catch (RemoteException e) {
1417 }
1418 }
1419
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001420 /** @hide */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001421 public void finishOp(int op) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07001422 finishOp(op, Process.myUid(), mContext.getOpPackageName());
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001423 }
1424}