blob: 24ebb33a7cda5d1d54dfe2d2ea146eb702e40c7b [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;
Jason Monk1c7c3192014-06-26 12:52:18 -0400218 /** @hide */
Svet Ganov16a16892015-04-16 10:32:04 -0700219 public static final int _NUM_OP = 52;
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800220
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700221 /** Access to coarse location information. */
222 public static final String OPSTR_COARSE_LOCATION =
223 "android:coarse_location";
224 /** Access to fine location information. */
225 public static final String OPSTR_FINE_LOCATION =
226 "android:fine_location";
227 /** Continually monitoring location data. */
228 public static final String OPSTR_MONITOR_LOCATION
229 = "android:monitor_location";
230 /** Continually monitoring location data with a relatively high power request. */
231 public static final String OPSTR_MONITOR_HIGH_POWER_LOCATION
232 = "android:monitor_location_high_power";
Dianne Hackborn5064e7c2014-09-02 10:57:16 -0700233 /** Access to {@link android.app.usage.UsageStatsManager}. */
234 public static final String OPSTR_GET_USAGE_STATS
235 = "android:get_usage_stats";
Jeff Davidson05542602014-08-11 14:07:27 -0700236 /** Activate a VPN connection without user intervention. @hide */
237 @SystemApi
238 public static final String OPSTR_ACTIVATE_VPN = "android:activate_vpn";
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700239
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800240 /**
241 * This maps each operation to the operation that serves as the
242 * switch to determine whether it is allowed. Generally this is
243 * a 1:1 mapping, but for some things (like location) that have
244 * multiple low-level operations being tracked that should be
David Christie0b837452013-07-29 16:02:13 -0700245 * presented to the user as one switch then this can be used to
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800246 * make them all controlled by the same single operation.
247 */
248 private static int[] sOpToSwitch = new int[] {
249 OP_COARSE_LOCATION,
250 OP_COARSE_LOCATION,
251 OP_COARSE_LOCATION,
252 OP_VIBRATE,
253 OP_READ_CONTACTS,
254 OP_WRITE_CONTACTS,
255 OP_READ_CALL_LOG,
256 OP_WRITE_CALL_LOG,
257 OP_READ_CALENDAR,
258 OP_WRITE_CALENDAR,
259 OP_COARSE_LOCATION,
260 OP_POST_NOTIFICATION,
261 OP_COARSE_LOCATION,
262 OP_CALL_PHONE,
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800263 OP_READ_SMS,
264 OP_WRITE_SMS,
David Braun18966a82013-09-10 13:14:46 -0700265 OP_RECEIVE_SMS,
266 OP_RECEIVE_SMS,
267 OP_RECEIVE_SMS,
268 OP_RECEIVE_SMS,
269 OP_SEND_SMS,
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800270 OP_READ_SMS,
271 OP_WRITE_SMS,
Dianne Hackborn961321f2013-02-05 17:22:41 -0800272 OP_WRITE_SETTINGS,
Dianne Hackbornc2293022013-02-06 23:14:49 -0800273 OP_SYSTEM_ALERT_WINDOW,
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500274 OP_ACCESS_NOTIFICATIONS,
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800275 OP_CAMERA,
276 OP_RECORD_AUDIO,
277 OP_PLAY_AUDIO,
Dianne Hackbornefcc1a22013-02-25 18:02:35 -0800278 OP_READ_CLIPBOARD,
279 OP_WRITE_CLIPBOARD,
Dianne Hackbornba50b97c2013-04-30 15:04:46 -0700280 OP_TAKE_MEDIA_BUTTONS,
281 OP_TAKE_AUDIO_FOCUS,
282 OP_AUDIO_MASTER_VOLUME,
283 OP_AUDIO_VOICE_VOLUME,
284 OP_AUDIO_RING_VOLUME,
285 OP_AUDIO_MEDIA_VOLUME,
286 OP_AUDIO_ALARM_VOLUME,
287 OP_AUDIO_NOTIFICATION_VOLUME,
288 OP_AUDIO_BLUETOOTH_VOLUME,
Dianne Hackborn713df152013-05-17 11:27:57 -0700289 OP_WAKE_LOCK,
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700290 OP_COARSE_LOCATION,
David Christie0b837452013-07-29 16:02:13 -0700291 OP_COARSE_LOCATION,
Dianne Hackborne22b3b12014-05-07 18:06:44 -0700292 OP_GET_USAGE_STATS,
Jason Monk1c7c3192014-06-26 12:52:18 -0400293 OP_MUTE_MICROPHONE,
294 OP_TOAST_WINDOW,
Michael Wrightc39d47a2014-07-08 18:07:36 -0700295 OP_PROJECT_MEDIA,
Jeff Davidson05542602014-08-11 14:07:27 -0700296 OP_ACTIVATE_VPN,
Benjamin Franzf3ece362015-02-11 10:51:10 +0000297 OP_WRITE_WALLPAPER,
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700298 OP_ASSIST_STRUCTURE,
299 OP_ASSIST_SCREENSHOT,
Svet Ganov16a16892015-04-16 10:32:04 -0700300 OP_READ_PHONE_STATE
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800301 };
302
303 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700304 * This maps each operation to the public string constant for it.
305 * If it doesn't have a public string constant, it maps to null.
306 */
307 private static String[] sOpToString = new String[] {
308 OPSTR_COARSE_LOCATION,
309 OPSTR_FINE_LOCATION,
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 null,
346 null,
347 null,
348 null,
349 OPSTR_MONITOR_LOCATION,
350 OPSTR_MONITOR_HIGH_POWER_LOCATION,
Dianne Hackborn5064e7c2014-09-02 10:57:16 -0700351 OPSTR_GET_USAGE_STATS,
Emily Bernier22c921a2014-05-28 11:01:32 -0400352 null,
Jason Monk1c7c3192014-06-26 12:52:18 -0400353 null,
Michael Wrightc39d47a2014-07-08 18:07:36 -0700354 null,
Jeff Davidson05542602014-08-11 14:07:27 -0700355 OPSTR_ACTIVATE_VPN,
Benjamin Franzf3ece362015-02-11 10:51:10 +0000356 null,
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700357 null,
358 null,
Svet Ganov16a16892015-04-16 10:32:04 -0700359 null
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700360 };
361
362 /**
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800363 * This provides a simple name for each operation to be used
364 * in debug output.
365 */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800366 private static String[] sOpNames = new String[] {
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800367 "COARSE_LOCATION",
368 "FINE_LOCATION",
369 "GPS",
370 "VIBRATE",
371 "READ_CONTACTS",
372 "WRITE_CONTACTS",
373 "READ_CALL_LOG",
374 "WRITE_CALL_LOG",
375 "READ_CALENDAR",
376 "WRITE_CALENDAR",
377 "WIFI_SCAN",
378 "POST_NOTIFICATION",
379 "NEIGHBORING_CELLS",
380 "CALL_PHONE",
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800381 "READ_SMS",
382 "WRITE_SMS",
383 "RECEIVE_SMS",
384 "RECEIVE_EMERGECY_SMS",
385 "RECEIVE_MMS",
386 "RECEIVE_WAP_PUSH",
387 "SEND_SMS",
388 "READ_ICC_SMS",
389 "WRITE_ICC_SMS",
Dianne Hackborn961321f2013-02-05 17:22:41 -0800390 "WRITE_SETTINGS",
Dianne Hackbornc2293022013-02-06 23:14:49 -0800391 "SYSTEM_ALERT_WINDOW",
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500392 "ACCESS_NOTIFICATIONS",
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800393 "CAMERA",
394 "RECORD_AUDIO",
395 "PLAY_AUDIO",
Dianne Hackbornefcc1a22013-02-25 18:02:35 -0800396 "READ_CLIPBOARD",
397 "WRITE_CLIPBOARD",
Dianne Hackbornba50b97c2013-04-30 15:04:46 -0700398 "TAKE_MEDIA_BUTTONS",
399 "TAKE_AUDIO_FOCUS",
400 "AUDIO_MASTER_VOLUME",
401 "AUDIO_VOICE_VOLUME",
402 "AUDIO_RING_VOLUME",
403 "AUDIO_MEDIA_VOLUME",
404 "AUDIO_ALARM_VOLUME",
405 "AUDIO_NOTIFICATION_VOLUME",
406 "AUDIO_BLUETOOTH_VOLUME",
Dianne Hackborn713df152013-05-17 11:27:57 -0700407 "WAKE_LOCK",
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700408 "MONITOR_LOCATION",
David Christie0b837452013-07-29 16:02:13 -0700409 "MONITOR_HIGH_POWER_LOCATION",
Emily Bernier22c921a2014-05-28 11:01:32 -0400410 "GET_USAGE_STATS",
Michael Wrightc39d47a2014-07-08 18:07:36 -0700411 "MUTE_MICROPHONE",
Jason Monk1c7c3192014-06-26 12:52:18 -0400412 "TOAST_WINDOW",
Michael Wrightc39d47a2014-07-08 18:07:36 -0700413 "PROJECT_MEDIA",
Jeff Davidson05542602014-08-11 14:07:27 -0700414 "ACTIVATE_VPN",
Benjamin Franzf3ece362015-02-11 10:51:10 +0000415 "WRITE_WALLPAPER",
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700416 "ASSIST_STRUCTURE",
Svet Ganov16a16892015-04-16 10:32:04 -0700417 "ASSIST_SCREENSHOT",
418 "OP_READ_PHONE_STATE"
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800419 };
420
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800421 /**
422 * This optionally maps a permission to an operation. If there
423 * is no permission associated with an operation, it is null.
424 */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800425 private static String[] sOpPerms = new String[] {
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800426 android.Manifest.permission.ACCESS_COARSE_LOCATION,
427 android.Manifest.permission.ACCESS_FINE_LOCATION,
428 null,
429 android.Manifest.permission.VIBRATE,
430 android.Manifest.permission.READ_CONTACTS,
431 android.Manifest.permission.WRITE_CONTACTS,
432 android.Manifest.permission.READ_CALL_LOG,
433 android.Manifest.permission.WRITE_CALL_LOG,
434 android.Manifest.permission.READ_CALENDAR,
435 android.Manifest.permission.WRITE_CALENDAR,
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800436 android.Manifest.permission.ACCESS_WIFI_STATE,
Robert Craigf97616c2013-10-07 12:32:02 -0400437 null, // no permission required for notifications
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800438 null, // neighboring cells shares the coarse location perm
439 android.Manifest.permission.CALL_PHONE,
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800440 android.Manifest.permission.READ_SMS,
Svetoslav6c589572015-04-16 16:19:24 -0700441 null, // no permission required for writing sms
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800442 android.Manifest.permission.RECEIVE_SMS,
443 android.Manifest.permission.RECEIVE_EMERGENCY_BROADCAST,
444 android.Manifest.permission.RECEIVE_MMS,
445 android.Manifest.permission.RECEIVE_WAP_PUSH,
446 android.Manifest.permission.SEND_SMS,
447 android.Manifest.permission.READ_SMS,
Svetoslav6c589572015-04-16 16:19:24 -0700448 null, // no permission required for writing icc sms
Dianne Hackborn961321f2013-02-05 17:22:41 -0800449 android.Manifest.permission.WRITE_SETTINGS,
Dianne Hackbornc2293022013-02-06 23:14:49 -0800450 android.Manifest.permission.SYSTEM_ALERT_WINDOW,
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500451 android.Manifest.permission.ACCESS_NOTIFICATIONS,
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800452 android.Manifest.permission.CAMERA,
453 android.Manifest.permission.RECORD_AUDIO,
454 null, // no permission for playing audio
Dianne Hackbornefcc1a22013-02-25 18:02:35 -0800455 null, // no permission for reading clipboard
456 null, // no permission for writing clipboard
Dianne Hackbornba50b97c2013-04-30 15:04:46 -0700457 null, // no permission for taking media buttons
458 null, // no permission for taking audio focus
459 null, // no permission for changing master volume
460 null, // no permission for changing voice volume
461 null, // no permission for changing ring volume
462 null, // no permission for changing media volume
463 null, // no permission for changing alarm volume
464 null, // no permission for changing notification volume
465 null, // no permission for changing bluetooth volume
Dianne Hackborn713df152013-05-17 11:27:57 -0700466 android.Manifest.permission.WAKE_LOCK,
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700467 null, // no permission for generic location monitoring
David Christie0b837452013-07-29 16:02:13 -0700468 null, // no permission for high power location monitoring
Dianne Hackborne22b3b12014-05-07 18:06:44 -0700469 android.Manifest.permission.PACKAGE_USAGE_STATS,
Emily Bernier22c921a2014-05-28 11:01:32 -0400470 null, // no permission for muting/unmuting microphone
Jason Monk1c7c3192014-06-26 12:52:18 -0400471 null, // no permission for displaying toasts
Michael Wrightc39d47a2014-07-08 18:07:36 -0700472 null, // no permission for projecting media
Jeff Davidson05542602014-08-11 14:07:27 -0700473 null, // no permission for activating vpn
Benjamin Franzf3ece362015-02-11 10:51:10 +0000474 null, // no permission for supporting wallpaper
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700475 null, // no permission for receiving assist structure
476 null, // no permission for receiving assist screenshot
Svet Ganov16a16892015-04-16 10:32:04 -0700477 Manifest.permission.READ_PHONE_STATE
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800478 };
479
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800480 /**
Jason Monk62062992014-05-06 09:55:28 -0400481 * Specifies whether an Op should be restricted by a user restriction.
482 * Each Op should be filled with a restriction string from UserManager or
483 * null to specify it is not affected by any user restriction.
484 */
485 private static String[] sOpRestrictions = new String[] {
Julia Reynolds9854d572014-07-02 14:46:02 -0400486 UserManager.DISALLOW_SHARE_LOCATION, //COARSE_LOCATION
487 UserManager.DISALLOW_SHARE_LOCATION, //FINE_LOCATION
488 UserManager.DISALLOW_SHARE_LOCATION, //GPS
Jason Monk62062992014-05-06 09:55:28 -0400489 null, //VIBRATE
490 null, //READ_CONTACTS
491 null, //WRITE_CONTACTS
Yorke Lee15f83c62014-08-13 14:14:29 -0700492 UserManager.DISALLOW_OUTGOING_CALLS, //READ_CALL_LOG
493 UserManager.DISALLOW_OUTGOING_CALLS, //WRITE_CALL_LOG
Jason Monk62062992014-05-06 09:55:28 -0400494 null, //READ_CALENDAR
495 null, //WRITE_CALENDAR
Julia Reynolds9854d572014-07-02 14:46:02 -0400496 UserManager.DISALLOW_SHARE_LOCATION, //WIFI_SCAN
Jason Monk62062992014-05-06 09:55:28 -0400497 null, //POST_NOTIFICATION
498 null, //NEIGHBORING_CELLS
499 null, //CALL_PHONE
Amith Yamasani41c1ded2014-08-05 11:15:05 -0700500 UserManager.DISALLOW_SMS, //READ_SMS
501 UserManager.DISALLOW_SMS, //WRITE_SMS
502 UserManager.DISALLOW_SMS, //RECEIVE_SMS
503 null, //RECEIVE_EMERGENCY_SMS
504 UserManager.DISALLOW_SMS, //RECEIVE_MMS
Jason Monk62062992014-05-06 09:55:28 -0400505 null, //RECEIVE_WAP_PUSH
Amith Yamasani41c1ded2014-08-05 11:15:05 -0700506 UserManager.DISALLOW_SMS, //SEND_SMS
507 UserManager.DISALLOW_SMS, //READ_ICC_SMS
508 UserManager.DISALLOW_SMS, //WRITE_ICC_SMS
Jason Monk62062992014-05-06 09:55:28 -0400509 null, //WRITE_SETTINGS
Jason Monk1c7c3192014-06-26 12:52:18 -0400510 UserManager.DISALLOW_CREATE_WINDOWS, //SYSTEM_ALERT_WINDOW
Jason Monk62062992014-05-06 09:55:28 -0400511 null, //ACCESS_NOTIFICATIONS
512 null, //CAMERA
513 null, //RECORD_AUDIO
514 null, //PLAY_AUDIO
515 null, //READ_CLIPBOARD
516 null, //WRITE_CLIPBOARD
517 null, //TAKE_MEDIA_BUTTONS
518 null, //TAKE_AUDIO_FOCUS
Emily Bernier45775c42014-05-16 15:12:04 -0400519 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MASTER_VOLUME
520 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_VOICE_VOLUME
521 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_RING_VOLUME
522 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MEDIA_VOLUME
523 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ALARM_VOLUME
524 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_NOTIFICATION_VOLUME
525 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_BLUETOOTH_VOLUME
Jason Monk62062992014-05-06 09:55:28 -0400526 null, //WAKE_LOCK
Julia Reynolds9854d572014-07-02 14:46:02 -0400527 UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_LOCATION
528 UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_HIGH_POWER_LOCATION
Jason Monk62062992014-05-06 09:55:28 -0400529 null, //GET_USAGE_STATS
Emily Bernier22c921a2014-05-28 11:01:32 -0400530 UserManager.DISALLOW_UNMUTE_MICROPHONE, // MUTE_MICROPHONE
Jason Monk1c7c3192014-06-26 12:52:18 -0400531 UserManager.DISALLOW_CREATE_WINDOWS, // TOAST_WINDOW
Michael Wrightc39d47a2014-07-08 18:07:36 -0700532 null, //PROJECT_MEDIA
Jeff Davidson05542602014-08-11 14:07:27 -0700533 UserManager.DISALLOW_CONFIG_VPN, // ACTIVATE_VPN
Benjamin Franzf3ece362015-02-11 10:51:10 +0000534 UserManager.DISALLOW_WALLPAPER, // WRITE_WALLPAPER
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700535 null, // ASSIST_STRUCTURE
536 null, // ASSIST_SCREENSHOT
Svet Ganov16a16892015-04-16 10:32:04 -0700537 null // READ_PHONE_STATE
Jason Monk1c7c3192014-06-26 12:52:18 -0400538 };
539
540 /**
541 * This specifies whether each option should allow the system
542 * (and system ui) to bypass the user restriction when active.
543 */
544 private static boolean[] sOpAllowSystemRestrictionBypass = new boolean[] {
545 false, //COARSE_LOCATION
546 false, //FINE_LOCATION
547 false, //GPS
548 false, //VIBRATE
549 false, //READ_CONTACTS
550 false, //WRITE_CONTACTS
551 false, //READ_CALL_LOG
552 false, //WRITE_CALL_LOG
553 false, //READ_CALENDAR
554 false, //WRITE_CALENDAR
Julia Reynolds9854d572014-07-02 14:46:02 -0400555 true, //WIFI_SCAN
Jason Monk1c7c3192014-06-26 12:52:18 -0400556 false, //POST_NOTIFICATION
557 false, //NEIGHBORING_CELLS
558 false, //CALL_PHONE
559 false, //READ_SMS
560 false, //WRITE_SMS
561 false, //RECEIVE_SMS
562 false, //RECEIVE_EMERGECY_SMS
563 false, //RECEIVE_MMS
564 false, //RECEIVE_WAP_PUSH
565 false, //SEND_SMS
566 false, //READ_ICC_SMS
567 false, //WRITE_ICC_SMS
568 false, //WRITE_SETTINGS
569 true, //SYSTEM_ALERT_WINDOW
570 false, //ACCESS_NOTIFICATIONS
571 false, //CAMERA
572 false, //RECORD_AUDIO
573 false, //PLAY_AUDIO
574 false, //READ_CLIPBOARD
575 false, //WRITE_CLIPBOARD
576 false, //TAKE_MEDIA_BUTTONS
577 false, //TAKE_AUDIO_FOCUS
578 false, //AUDIO_MASTER_VOLUME
579 false, //AUDIO_VOICE_VOLUME
580 false, //AUDIO_RING_VOLUME
581 false, //AUDIO_MEDIA_VOLUME
582 false, //AUDIO_ALARM_VOLUME
583 false, //AUDIO_NOTIFICATION_VOLUME
584 false, //AUDIO_BLUETOOTH_VOLUME
585 false, //WAKE_LOCK
586 false, //MONITOR_LOCATION
587 false, //MONITOR_HIGH_POWER_LOCATION
588 false, //GET_USAGE_STATS
Michael Wrightc39d47a2014-07-08 18:07:36 -0700589 false, //MUTE_MICROPHONE
590 true, //TOAST_WINDOW
591 false, //PROJECT_MEDIA
Jeff Davidson05542602014-08-11 14:07:27 -0700592 false, //ACTIVATE_VPN
Benjamin Franzf3ece362015-02-11 10:51:10 +0000593 false, //WALLPAPER
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700594 false, //ASSIST_STRUCTURE
595 false, //ASSIST_SCREENSHOT
Svet Ganov16a16892015-04-16 10:32:04 -0700596 false, //READ_PHONE_STATE
Jason Monk62062992014-05-06 09:55:28 -0400597 };
598
599 /**
David Braunf5d83192013-09-16 13:43:51 -0700600 * This specifies the default mode for each operation.
601 */
602 private static int[] sOpDefaultMode = new int[] {
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_ALLOWED,
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_IGNORED, // OP_WRITE_SMS
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,
637 AppOpsManager.MODE_ALLOWED,
638 AppOpsManager.MODE_ALLOWED,
639 AppOpsManager.MODE_ALLOWED,
640 AppOpsManager.MODE_ALLOWED,
641 AppOpsManager.MODE_ALLOWED,
642 AppOpsManager.MODE_ALLOWED,
643 AppOpsManager.MODE_ALLOWED,
644 AppOpsManager.MODE_ALLOWED,
645 AppOpsManager.MODE_ALLOWED,
Dianne Hackborn33f5ddd2014-07-21 15:35:45 -0700646 AppOpsManager.MODE_DEFAULT, // OP_GET_USAGE_STATS
Emily Bernier22c921a2014-05-28 11:01:32 -0400647 AppOpsManager.MODE_ALLOWED,
Jason Monk1c7c3192014-06-26 12:52:18 -0400648 AppOpsManager.MODE_ALLOWED,
Michael Wrightc39d47a2014-07-08 18:07:36 -0700649 AppOpsManager.MODE_IGNORED, // OP_PROJECT_MEDIA
Jeff Davidson05542602014-08-11 14:07:27 -0700650 AppOpsManager.MODE_IGNORED, // OP_ACTIVATE_VPN
Benjamin Franzf3ece362015-02-11 10:51:10 +0000651 AppOpsManager.MODE_ALLOWED,
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700652 AppOpsManager.MODE_ALLOWED,
653 AppOpsManager.MODE_ALLOWED,
Svet Ganov16a16892015-04-16 10:32:04 -0700654 AppOpsManager.MODE_ALLOWED
David Braunf5d83192013-09-16 13:43:51 -0700655 };
656
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700657 /**
658 * This specifies whether each option is allowed to be reset
659 * when resetting all app preferences. Disable reset for
660 * app ops that are under strong control of some part of the
661 * system (such as OP_WRITE_SMS, which should be allowed only
662 * for whichever app is selected as the current SMS app).
663 */
664 private static boolean[] sOpDisableReset = new boolean[] {
665 false,
666 false,
667 false,
668 false,
669 false,
670 false,
671 false,
672 false,
673 false,
674 false,
675 false,
676 false,
677 false,
678 false,
679 false,
680 true, // OP_WRITE_SMS
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,
698 false,
699 false,
700 false,
701 false,
702 false,
703 false,
704 false,
705 false,
706 false,
707 false,
Dianne Hackborne22b3b12014-05-07 18:06:44 -0700708 false,
Emily Bernier22c921a2014-05-28 11:01:32 -0400709 false,
Jason Monk1c7c3192014-06-26 12:52:18 -0400710 false,
Michael Wrightc39d47a2014-07-08 18:07:36 -0700711 false,
Jeff Davidson05542602014-08-11 14:07:27 -0700712 false,
Benjamin Franzf3ece362015-02-11 10:51:10 +0000713 false,
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700714 false,
715 false,
Svet Ganov16a16892015-04-16 10:32:04 -0700716 false
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700717 };
718
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700719 private static HashMap<String, Integer> sOpStrToOp = new HashMap<String, Integer>();
720
721 static {
722 if (sOpToSwitch.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700723 throw new IllegalStateException("sOpToSwitch length " + sOpToSwitch.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700724 + " should be " + _NUM_OP);
725 }
726 if (sOpToString.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700727 throw new IllegalStateException("sOpToString length " + sOpToString.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700728 + " should be " + _NUM_OP);
729 }
730 if (sOpNames.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700731 throw new IllegalStateException("sOpNames length " + sOpNames.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700732 + " should be " + _NUM_OP);
733 }
734 if (sOpPerms.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700735 throw new IllegalStateException("sOpPerms length " + sOpPerms.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700736 + " should be " + _NUM_OP);
737 }
738 if (sOpDefaultMode.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700739 throw new IllegalStateException("sOpDefaultMode length " + sOpDefaultMode.length
740 + " should be " + _NUM_OP);
741 }
742 if (sOpDisableReset.length != _NUM_OP) {
743 throw new IllegalStateException("sOpDisableReset length " + sOpDisableReset.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700744 + " should be " + _NUM_OP);
745 }
Jason Monk62062992014-05-06 09:55:28 -0400746 if (sOpRestrictions.length != _NUM_OP) {
747 throw new IllegalStateException("sOpRestrictions length " + sOpRestrictions.length
748 + " should be " + _NUM_OP);
749 }
Jason Monk1c7c3192014-06-26 12:52:18 -0400750 if (sOpAllowSystemRestrictionBypass.length != _NUM_OP) {
751 throw new IllegalStateException("sOpAllowSYstemRestrictionsBypass length "
752 + sOpRestrictions.length + " should be " + _NUM_OP);
753 }
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700754 for (int i=0; i<_NUM_OP; i++) {
755 if (sOpToString[i] != null) {
756 sOpStrToOp.put(sOpToString[i], i);
757 }
758 }
759 }
760
David Braunf5d83192013-09-16 13:43:51 -0700761 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800762 * Retrieve the op switch that controls the given operation.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700763 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800764 */
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800765 public static int opToSwitch(int op) {
766 return sOpToSwitch[op];
767 }
768
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800769 /**
770 * Retrieve a non-localized name for the operation, for debugging output.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700771 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800772 */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800773 public static String opToName(int op) {
Dianne Hackbornc2293022013-02-06 23:14:49 -0800774 if (op == OP_NONE) return "NONE";
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800775 return op < sOpNames.length ? sOpNames[op] : ("Unknown(" + op + ")");
776 }
777
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800778 /**
Dianne Hackborn7b7c58b2014-12-02 18:32:20 -0800779 * @hide
780 */
781 public static int strDebugOpToOp(String op) {
782 for (int i=0; i<sOpNames.length; i++) {
783 if (sOpNames[i].equals(op)) {
784 return i;
785 }
786 }
787 throw new IllegalArgumentException("Unknown operation string: " + op);
788 }
789
790 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800791 * Retrieve the permission associated with an operation, or null if there is not one.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700792 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800793 */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800794 public static String opToPermission(int op) {
795 return sOpPerms[op];
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800796 }
797
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800798 /**
Jason Monk62062992014-05-06 09:55:28 -0400799 * Retrieve the user restriction associated with an operation, or null if there is not one.
800 * @hide
801 */
802 public static String opToRestriction(int op) {
803 return sOpRestrictions[op];
804 }
805
806 /**
Jason Monk1c7c3192014-06-26 12:52:18 -0400807 * Retrieve whether the op allows the system (and system ui) to
808 * bypass the user restriction.
809 * @hide
810 */
811 public static boolean opAllowSystemBypassRestriction(int op) {
812 return sOpAllowSystemRestrictionBypass[op];
813 }
814
815 /**
David Braunf5d83192013-09-16 13:43:51 -0700816 * Retrieve the default mode for the operation.
817 * @hide
818 */
819 public static int opToDefaultMode(int op) {
820 return sOpDefaultMode[op];
821 }
822
823 /**
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700824 * Retrieve whether the op allows itself to be reset.
825 * @hide
826 */
827 public static boolean opAllowsReset(int op) {
828 return !sOpDisableReset[op];
829 }
830
831 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800832 * Class holding all of the operation information associated with an app.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700833 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800834 */
Dianne Hackborn35654b62013-01-14 17:38:02 -0800835 public static class PackageOps implements Parcelable {
836 private final String mPackageName;
837 private final int mUid;
838 private final List<OpEntry> mEntries;
839
840 public PackageOps(String packageName, int uid, List<OpEntry> entries) {
841 mPackageName = packageName;
842 mUid = uid;
843 mEntries = entries;
844 }
845
846 public String getPackageName() {
847 return mPackageName;
848 }
849
850 public int getUid() {
851 return mUid;
852 }
853
854 public List<OpEntry> getOps() {
855 return mEntries;
856 }
857
858 @Override
859 public int describeContents() {
860 return 0;
861 }
862
863 @Override
864 public void writeToParcel(Parcel dest, int flags) {
865 dest.writeString(mPackageName);
866 dest.writeInt(mUid);
867 dest.writeInt(mEntries.size());
868 for (int i=0; i<mEntries.size(); i++) {
869 mEntries.get(i).writeToParcel(dest, flags);
870 }
871 }
872
873 PackageOps(Parcel source) {
874 mPackageName = source.readString();
875 mUid = source.readInt();
876 mEntries = new ArrayList<OpEntry>();
877 final int N = source.readInt();
878 for (int i=0; i<N; i++) {
879 mEntries.add(OpEntry.CREATOR.createFromParcel(source));
880 }
881 }
882
883 public static final Creator<PackageOps> CREATOR = new Creator<PackageOps>() {
884 @Override public PackageOps createFromParcel(Parcel source) {
885 return new PackageOps(source);
886 }
887
888 @Override public PackageOps[] newArray(int size) {
889 return new PackageOps[size];
890 }
891 };
892 }
893
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800894 /**
895 * Class holding the information about one unique operation of an application.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700896 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800897 */
Dianne Hackborn35654b62013-01-14 17:38:02 -0800898 public static class OpEntry implements Parcelable {
899 private final int mOp;
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800900 private final int mMode;
Dianne Hackborn35654b62013-01-14 17:38:02 -0800901 private final long mTime;
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800902 private final long mRejectTime;
Dianne Hackborn35654b62013-01-14 17:38:02 -0800903 private final int mDuration;
904
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800905 public OpEntry(int op, int mode, long time, long rejectTime, int duration) {
Dianne Hackborn35654b62013-01-14 17:38:02 -0800906 mOp = op;
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800907 mMode = mode;
Dianne Hackborn35654b62013-01-14 17:38:02 -0800908 mTime = time;
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800909 mRejectTime = rejectTime;
Dianne Hackborn35654b62013-01-14 17:38:02 -0800910 mDuration = duration;
911 }
912
913 public int getOp() {
914 return mOp;
915 }
916
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800917 public int getMode() {
918 return mMode;
919 }
920
Dianne Hackborn35654b62013-01-14 17:38:02 -0800921 public long getTime() {
922 return mTime;
923 }
924
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800925 public long getRejectTime() {
926 return mRejectTime;
927 }
928
Dianne Hackborn35654b62013-01-14 17:38:02 -0800929 public boolean isRunning() {
930 return mDuration == -1;
931 }
932
933 public int getDuration() {
934 return mDuration == -1 ? (int)(System.currentTimeMillis()-mTime) : mDuration;
935 }
936
937 @Override
938 public int describeContents() {
939 return 0;
940 }
941
942 @Override
943 public void writeToParcel(Parcel dest, int flags) {
944 dest.writeInt(mOp);
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800945 dest.writeInt(mMode);
Dianne Hackborn35654b62013-01-14 17:38:02 -0800946 dest.writeLong(mTime);
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800947 dest.writeLong(mRejectTime);
Dianne Hackborn35654b62013-01-14 17:38:02 -0800948 dest.writeInt(mDuration);
949 }
950
951 OpEntry(Parcel source) {
952 mOp = source.readInt();
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800953 mMode = source.readInt();
Dianne Hackborn35654b62013-01-14 17:38:02 -0800954 mTime = source.readLong();
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800955 mRejectTime = source.readLong();
Dianne Hackborn35654b62013-01-14 17:38:02 -0800956 mDuration = source.readInt();
957 }
958
959 public static final Creator<OpEntry> CREATOR = new Creator<OpEntry>() {
960 @Override public OpEntry createFromParcel(Parcel source) {
961 return new OpEntry(source);
962 }
963
964 @Override public OpEntry[] newArray(int size) {
965 return new OpEntry[size];
966 }
967 };
968 }
969
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800970 /**
971 * Callback for notification of changes to operation state.
972 */
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700973 public interface OnOpChangedListener {
974 public void onOpChanged(String op, String packageName);
975 }
976
977 /**
978 * Callback for notification of changes to operation state.
979 * This allows you to see the raw op codes instead of strings.
980 * @hide
981 */
982 public static class OnOpChangedInternalListener implements OnOpChangedListener {
983 public void onOpChanged(String op, String packageName) { }
984 public void onOpChanged(int op, String packageName) { }
Dianne Hackbornc2293022013-02-06 23:14:49 -0800985 }
986
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700987 AppOpsManager(Context context, IAppOpsService service) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800988 mContext = context;
989 mService = service;
990 }
991
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800992 /**
993 * Retrieve current operation state for all applications.
994 *
995 * @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 -0700996 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800997 */
Dianne Hackborn35654b62013-01-14 17:38:02 -0800998 public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) {
999 try {
1000 return mService.getPackagesForOps(ops);
1001 } catch (RemoteException e) {
1002 }
1003 return null;
1004 }
1005
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001006 /**
1007 * Retrieve current operation state for one application.
1008 *
1009 * @param uid The uid of the application of interest.
1010 * @param packageName The name of the application of interest.
1011 * @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 -07001012 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001013 */
Dianne Hackborn72e39832013-01-18 18:36:09 -08001014 public List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, int[] ops) {
1015 try {
1016 return mService.getOpsForPackage(uid, packageName, ops);
1017 } catch (RemoteException e) {
1018 }
1019 return null;
1020 }
1021
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001022 /** @hide */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001023 public void setMode(int code, int uid, String packageName, int mode) {
1024 try {
1025 mService.setMode(code, uid, packageName, mode);
1026 } catch (RemoteException e) {
1027 }
1028 }
1029
John Spurlock1af30c72014-03-10 08:33:35 -04001030 /**
1031 * Set a non-persisted restriction on an audio operation at a stream-level.
1032 * Restrictions are temporary additional constraints imposed on top of the persisted rules
1033 * defined by {@link #setMode}.
1034 *
1035 * @param code The operation to restrict.
John Spurlock7b414672014-07-18 13:02:39 -04001036 * @param usage The {@link android.media.AudioAttributes} usage value.
John Spurlock1af30c72014-03-10 08:33:35 -04001037 * @param mode The restriction mode (MODE_IGNORED,MODE_ERRORED) or MODE_ALLOWED to unrestrict.
1038 * @param exceptionPackages Optional list of packages to exclude from the restriction.
1039 * @hide
1040 */
John Spurlock7b414672014-07-18 13:02:39 -04001041 public void setRestriction(int code, @AttributeUsage int usage, int mode,
1042 String[] exceptionPackages) {
John Spurlock1af30c72014-03-10 08:33:35 -04001043 try {
1044 final int uid = Binder.getCallingUid();
John Spurlock7b414672014-07-18 13:02:39 -04001045 mService.setAudioRestriction(code, usage, uid, mode, exceptionPackages);
John Spurlock1af30c72014-03-10 08:33:35 -04001046 } catch (RemoteException e) {
1047 }
1048 }
1049
Dianne Hackborn607b4142013-08-02 18:10:10 -07001050 /** @hide */
1051 public void resetAllModes() {
1052 try {
Dianne Hackborn7b7c58b2014-12-02 18:32:20 -08001053 mService.resetAllModes(UserHandle.myUserId(), null);
Dianne Hackborn607b4142013-08-02 18:10:10 -07001054 } catch (RemoteException e) {
1055 }
1056 }
1057
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001058 /**
1059 * Monitor for changes to the operating mode for the given op in the given app package.
Dianne Hackborne4cb66f2013-10-02 10:34:02 -07001060 * @param op The operation to monitor, one of OPSTR_*.
1061 * @param packageName The name of the application to monitor.
1062 * @param callback Where to report changes.
1063 */
1064 public void startWatchingMode(String op, String packageName,
1065 final OnOpChangedListener callback) {
1066 startWatchingMode(strOpToOp(op), packageName, callback);
1067 }
1068
1069 /**
1070 * Monitor for changes to the operating mode for the given op in the given app package.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001071 * @param op The operation to monitor, one of OP_*.
1072 * @param packageName The name of the application to monitor.
1073 * @param callback Where to report changes.
Dianne Hackborne4cb66f2013-10-02 10:34:02 -07001074 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001075 */
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001076 public void startWatchingMode(int op, String packageName, final OnOpChangedListener callback) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08001077 synchronized (mModeWatchers) {
1078 IAppOpsCallback cb = mModeWatchers.get(callback);
1079 if (cb == null) {
1080 cb = new IAppOpsCallback.Stub() {
1081 public void opChanged(int op, String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001082 if (callback instanceof OnOpChangedInternalListener) {
1083 ((OnOpChangedInternalListener)callback).onOpChanged(op, packageName);
1084 }
1085 if (sOpToString[op] != null) {
1086 callback.onOpChanged(sOpToString[op], packageName);
1087 }
Dianne Hackbornc2293022013-02-06 23:14:49 -08001088 }
1089 };
1090 mModeWatchers.put(callback, cb);
1091 }
1092 try {
1093 mService.startWatchingMode(op, packageName, cb);
1094 } catch (RemoteException e) {
1095 }
1096 }
1097 }
1098
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001099 /**
1100 * Stop monitoring that was previously started with {@link #startWatchingMode}. All
1101 * monitoring associated with this callback will be removed.
1102 */
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001103 public void stopWatchingMode(OnOpChangedListener callback) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08001104 synchronized (mModeWatchers) {
1105 IAppOpsCallback cb = mModeWatchers.get(callback);
1106 if (cb != null) {
1107 try {
1108 mService.stopWatchingMode(cb);
1109 } catch (RemoteException e) {
1110 }
1111 }
1112 }
1113 }
1114
Dianne Hackborn95d78532013-09-11 09:51:14 -07001115 private String buildSecurityExceptionMsg(int op, int uid, String packageName) {
1116 return packageName + " from uid " + uid + " not allowed to perform " + sOpNames[op];
1117 }
1118
Adam Lesinskib5cf61b2014-08-18 16:10:28 -07001119 /**
1120 * {@hide}
1121 */
1122 public static int strOpToOp(String op) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001123 Integer val = sOpStrToOp.get(op);
1124 if (val == null) {
1125 throw new IllegalArgumentException("Unknown operation string: " + op);
1126 }
1127 return val;
1128 }
1129
1130 /**
1131 * Do a quick check for whether an application might be able to perform an operation.
1132 * This is <em>not</em> a security check; you must use {@link #noteOp(String, int, String)}
1133 * or {@link #startOp(String, int, String)} for your actual security checks, which also
1134 * ensure that the given uid and package name are consistent. This function can just be
1135 * used for a quick check to see if an operation has been disabled for the application,
1136 * as an early reject of some work. This does not modify the time stamp or other data
1137 * about the operation.
1138 * @param op The operation to check. One of the OPSTR_* constants.
1139 * @param uid The user id of the application attempting to perform the operation.
1140 * @param packageName The name of the application attempting to perform the operation.
1141 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1142 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1143 * causing the app to crash).
1144 * @throws SecurityException If the app has been configured to crash on this op.
1145 */
1146 public int checkOp(String op, int uid, String packageName) {
1147 return checkOp(strOpToOp(op), uid, packageName);
1148 }
1149
1150 /**
John Spurlock925b85e2014-03-10 16:52:11 -04001151 * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001152 * returns {@link #MODE_ERRORED}.
1153 */
1154 public int checkOpNoThrow(String op, int uid, String packageName) {
1155 return checkOpNoThrow(strOpToOp(op), uid, packageName);
1156 }
1157
1158 /**
1159 * Make note of an application performing an operation. Note that you must pass
1160 * in both the uid and name of the application to be checked; this function will verify
1161 * that these two match, and if not, return {@link #MODE_IGNORED}. If this call
1162 * succeeds, the last execution time of the operation for this app will be updated to
1163 * the current time.
1164 * @param op The operation to note. One of the OPSTR_* constants.
1165 * @param uid The user id of the application attempting to perform the operation.
1166 * @param packageName The name of the application attempting to perform the operation.
1167 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1168 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1169 * causing the app to crash).
1170 * @throws SecurityException If the app has been configured to crash on this op.
1171 */
1172 public int noteOp(String op, int uid, String packageName) {
1173 return noteOp(strOpToOp(op), uid, packageName);
1174 }
1175
1176 /**
1177 * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
1178 * returns {@link #MODE_ERRORED}.
1179 */
1180 public int noteOpNoThrow(String op, int uid, String packageName) {
1181 return noteOpNoThrow(strOpToOp(op), uid, packageName);
1182 }
1183
1184 /**
1185 * Report that an application has started executing a long-running operation. Note that you
1186 * must pass in both the uid and name of the application to be checked; this function will
1187 * verify that these two match, and if not, return {@link #MODE_IGNORED}. If this call
1188 * succeeds, the last execution time of the operation for this app will be updated to
1189 * the current time and the operation will be marked as "running". In this case you must
1190 * later call {@link #finishOp(String, int, String)} to report when the application is no
1191 * longer performing the operation.
1192 * @param op The operation to start. One of the OPSTR_* constants.
1193 * @param uid The user id of the application attempting to perform the operation.
1194 * @param packageName The name of the application attempting to perform the operation.
1195 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1196 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1197 * causing the app to crash).
1198 * @throws SecurityException If the app has been configured to crash on this op.
1199 */
1200 public int startOp(String op, int uid, String packageName) {
1201 return startOp(strOpToOp(op), uid, packageName);
1202 }
1203
1204 /**
1205 * Like {@link #startOp} but instead of throwing a {@link SecurityException} it
1206 * returns {@link #MODE_ERRORED}.
1207 */
1208 public int startOpNoThrow(String op, int uid, String packageName) {
1209 return startOpNoThrow(strOpToOp(op), uid, packageName);
1210 }
1211
1212 /**
1213 * Report that an application is no longer performing an operation that had previously
1214 * been started with {@link #startOp(String, int, String)}. There is no validation of input
1215 * or result; the parameters supplied here must be the exact same ones previously passed
1216 * in when starting the operation.
1217 */
1218 public void finishOp(String op, int uid, String packageName) {
1219 finishOp(strOpToOp(op), uid, packageName);
1220 }
1221
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001222 /**
1223 * Do a quick check for whether an application might be able to perform an operation.
1224 * This is <em>not</em> a security check; you must use {@link #noteOp(int, int, String)}
1225 * or {@link #startOp(int, int, String)} for your actual security checks, which also
1226 * ensure that the given uid and package name are consistent. This function can just be
1227 * used for a quick check to see if an operation has been disabled for the application,
1228 * as an early reject of some work. This does not modify the time stamp or other data
1229 * about the operation.
1230 * @param op The operation to check. One of the OP_* constants.
1231 * @param uid The user id of the application attempting to perform the operation.
1232 * @param packageName The name of the application attempting to perform the operation.
1233 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1234 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1235 * causing the app to crash).
1236 * @throws SecurityException If the app has been configured to crash on this op.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001237 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001238 */
Dianne Hackborn35654b62013-01-14 17:38:02 -08001239 public int checkOp(int op, int uid, String packageName) {
1240 try {
1241 int mode = mService.checkOperation(op, uid, packageName);
1242 if (mode == MODE_ERRORED) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07001243 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborn35654b62013-01-14 17:38:02 -08001244 }
1245 return mode;
1246 } catch (RemoteException e) {
1247 }
1248 return MODE_IGNORED;
1249 }
1250
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001251 /**
1252 * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
1253 * returns {@link #MODE_ERRORED}.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001254 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001255 */
Dianne Hackborn35654b62013-01-14 17:38:02 -08001256 public int checkOpNoThrow(int op, int uid, String packageName) {
1257 try {
1258 return mService.checkOperation(op, uid, packageName);
1259 } catch (RemoteException e) {
1260 }
1261 return MODE_IGNORED;
1262 }
1263
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001264 /**
Jeff Sharkey911d7f42013-09-05 18:11:45 -07001265 * Do a quick check to validate if a package name belongs to a UID.
1266 *
1267 * @throws SecurityException if the package name doesn't belong to the given
1268 * UID, or if ownership cannot be verified.
1269 */
1270 public void checkPackage(int uid, String packageName) {
1271 try {
1272 if (mService.checkPackage(uid, packageName) != MODE_ALLOWED) {
1273 throw new SecurityException(
1274 "Package " + packageName + " does not belong to " + uid);
1275 }
1276 } catch (RemoteException e) {
1277 throw new SecurityException("Unable to verify package ownership", e);
1278 }
1279 }
1280
1281 /**
John Spurlock1af30c72014-03-10 08:33:35 -04001282 * Like {@link #checkOp} but at a stream-level for audio operations.
1283 * @hide
1284 */
1285 public int checkAudioOp(int op, int stream, int uid, String packageName) {
1286 try {
1287 final int mode = mService.checkAudioOperation(op, stream, uid, packageName);
1288 if (mode == MODE_ERRORED) {
1289 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
1290 }
1291 return mode;
1292 } catch (RemoteException e) {
1293 }
1294 return MODE_IGNORED;
1295 }
1296
1297 /**
1298 * Like {@link #checkAudioOp} but instead of throwing a {@link SecurityException} it
1299 * returns {@link #MODE_ERRORED}.
1300 * @hide
1301 */
1302 public int checkAudioOpNoThrow(int op, int stream, int uid, String packageName) {
1303 try {
1304 return mService.checkAudioOperation(op, stream, uid, packageName);
1305 } catch (RemoteException e) {
1306 }
1307 return MODE_IGNORED;
1308 }
1309
1310 /**
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001311 * Make note of an application performing an operation. Note that you must pass
1312 * in both the uid and name of the application to be checked; this function will verify
1313 * that these two match, and if not, return {@link #MODE_IGNORED}. If this call
1314 * succeeds, the last execution time of the operation for this app will be updated to
1315 * the current time.
1316 * @param op The operation to note. One of the OP_* constants.
1317 * @param uid The user id of the application attempting to perform the operation.
1318 * @param packageName The name of the application attempting to perform the operation.
1319 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1320 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1321 * causing the app to crash).
1322 * @throws SecurityException If the app has been configured to crash on this op.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001323 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001324 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001325 public int noteOp(int op, int uid, String packageName) {
1326 try {
1327 int mode = mService.noteOperation(op, uid, packageName);
1328 if (mode == MODE_ERRORED) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07001329 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001330 }
1331 return mode;
1332 } catch (RemoteException e) {
1333 }
1334 return MODE_IGNORED;
1335 }
1336
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001337 /**
1338 * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
1339 * returns {@link #MODE_ERRORED}.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001340 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001341 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001342 public int noteOpNoThrow(int op, int uid, String packageName) {
1343 try {
1344 return mService.noteOperation(op, uid, packageName);
1345 } catch (RemoteException e) {
1346 }
1347 return MODE_IGNORED;
1348 }
1349
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001350 /** @hide */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001351 public int noteOp(int op) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07001352 return noteOp(op, Process.myUid(), mContext.getOpPackageName());
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001353 }
1354
Dianne Hackborne98f5db2013-07-17 17:23:25 -07001355 /** @hide */
1356 public static IBinder getToken(IAppOpsService service) {
1357 synchronized (AppOpsManager.class) {
1358 if (sToken != null) {
1359 return sToken;
1360 }
1361 try {
1362 sToken = service.getToken(new Binder());
1363 } catch (RemoteException e) {
1364 // System is dead, whatevs.
1365 }
1366 return sToken;
1367 }
1368 }
1369
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001370 /**
1371 * Report that an application has started executing a long-running operation. Note that you
1372 * must pass in both the uid and name of the application to be checked; this function will
1373 * verify that these two match, and if not, return {@link #MODE_IGNORED}. If this call
1374 * succeeds, the last execution time of the operation for this app will be updated to
1375 * the current time and the operation will be marked as "running". In this case you must
1376 * later call {@link #finishOp(int, int, String)} to report when the application is no
1377 * longer performing the operation.
1378 * @param op The operation to start. One of the OP_* 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.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001385 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001386 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001387 public int startOp(int op, int uid, String packageName) {
1388 try {
Dianne Hackborne98f5db2013-07-17 17:23:25 -07001389 int mode = mService.startOperation(getToken(mService), op, uid, packageName);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001390 if (mode == MODE_ERRORED) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07001391 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001392 }
1393 return mode;
1394 } catch (RemoteException e) {
1395 }
1396 return MODE_IGNORED;
1397 }
1398
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001399 /**
1400 * Like {@link #startOp} but instead of throwing a {@link SecurityException} it
1401 * returns {@link #MODE_ERRORED}.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001402 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001403 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001404 public int startOpNoThrow(int op, int uid, String packageName) {
1405 try {
Dianne Hackborne98f5db2013-07-17 17:23:25 -07001406 return mService.startOperation(getToken(mService), op, uid, packageName);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001407 } catch (RemoteException e) {
1408 }
1409 return MODE_IGNORED;
1410 }
1411
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001412 /** @hide */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001413 public int startOp(int op) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07001414 return startOp(op, Process.myUid(), mContext.getOpPackageName());
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001415 }
1416
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001417 /**
1418 * Report that an application is no longer performing an operation that had previously
1419 * been started with {@link #startOp(int, int, String)}. There is no validation of input
1420 * or result; the parameters supplied here must be the exact same ones previously passed
1421 * in when starting the operation.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001422 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001423 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001424 public void finishOp(int op, int uid, String packageName) {
1425 try {
Dianne Hackborne98f5db2013-07-17 17:23:25 -07001426 mService.finishOperation(getToken(mService), op, uid, packageName);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001427 } catch (RemoteException e) {
1428 }
1429 }
1430
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001431 /** @hide */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001432 public void finishOp(int op) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07001433 finishOp(op, Process.myUid(), mContext.getOpPackageName());
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001434 }
1435}