blob: 223d528a6c1de4e49fac1b8ecb0c0a4105943a99 [file] [log] [blame]
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.app;
18
Svet Ganov16a16892015-04-16 10:32:04 -070019import android.Manifest;
Jeff Davidson05542602014-08-11 14:07:27 -070020import android.annotation.SystemApi;
21import android.app.usage.UsageStatsManager;
22import android.content.Context;
John Spurlock7b414672014-07-18 13:02:39 -040023import android.media.AudioAttributes.AttributeUsage;
Dianne Hackborne98f5db2013-07-17 17:23:25 -070024import android.os.Binder;
25import android.os.IBinder;
Dianne Hackborn35654b62013-01-14 17:38:02 -080026import android.os.Parcel;
27import android.os.Parcelable;
Dianne Hackborna06de0f2012-12-11 16:34:47 -080028import android.os.Process;
29import android.os.RemoteException;
Dianne Hackborn7b7c58b2014-12-02 18:32:20 -080030import android.os.UserHandle;
Jeff Davidson05542602014-08-11 14:07:27 -070031import android.os.UserManager;
32import android.util.ArrayMap;
33
34import com.android.internal.app.IAppOpsCallback;
35import com.android.internal.app.IAppOpsService;
36
37import java.util.ArrayList;
38import java.util.HashMap;
39import java.util.List;
Dianne Hackborna06de0f2012-12-11 16:34:47 -080040
Dianne Hackbornd7d28e62013-02-12 14:59:53 -080041/**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070042 * API for interacting with "application operation" tracking.
Dianne Hackbornd7d28e62013-02-12 14:59:53 -080043 *
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070044 * <p>This API is not generally intended for third party application developers; most
John Spurlock925b85e2014-03-10 16:52:11 -040045 * features are only available to system applications. Obtain an instance of it through
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070046 * {@link Context#getSystemService(String) Context.getSystemService} with
47 * {@link Context#APP_OPS_SERVICE Context.APP_OPS_SERVICE}.</p>
Dianne Hackbornd7d28e62013-02-12 14:59:53 -080048 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -080049public class AppOpsManager {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070050 /**
51 * <p>App ops allows callers to:</p>
52 *
53 * <ul>
54 * <li> Note when operations are happening, and find out if they are allowed for the current
55 * caller.</li>
56 * <li> Disallow specific apps from doing specific operations.</li>
57 * <li> Collect all of the current information about operations that have been executed or
58 * are not being allowed.</li>
59 * <li> Monitor for changes in whether an operation is allowed.</li>
60 * </ul>
61 *
62 * <p>Each operation is identified by a single integer; these integers are a fixed set of
63 * operations, enumerated by the OP_* constants.
64 *
65 * <p></p>When checking operations, the result is a "mode" integer indicating the current
66 * setting for the operation under that caller: MODE_ALLOWED, MODE_IGNORED (don't execute
67 * the operation but fake its behavior enough so that the caller doesn't crash),
68 * MODE_ERRORED (throw a SecurityException back to the caller; the normal operation calls
69 * will do this for you).
70 */
71
Dianne Hackborna06de0f2012-12-11 16:34:47 -080072 final Context mContext;
73 final IAppOpsService mService;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070074 final ArrayMap<OnOpChangedListener, IAppOpsCallback> mModeWatchers
75 = new ArrayMap<OnOpChangedListener, IAppOpsCallback>();
Dianne Hackborna06de0f2012-12-11 16:34:47 -080076
Dianne Hackborne98f5db2013-07-17 17:23:25 -070077 static IBinder sToken;
78
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070079 /**
80 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is
81 * allowed to perform the given operation.
82 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -080083 public static final int MODE_ALLOWED = 0;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070084
85 /**
86 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is
87 * not allowed to perform the given operation, and this attempt should
88 * <em>silently fail</em> (it should not cause the app to crash).
89 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -080090 public static final int MODE_IGNORED = 1;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070091
92 /**
93 * Result from {@link #checkOpNoThrow}, {@link #noteOpNoThrow}, {@link #startOpNoThrow}: the
94 * given caller is not allowed to perform the given operation, and this attempt should
95 * cause it to have a fatal error, typically a {@link SecurityException}.
96 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -080097 public static final int MODE_ERRORED = 2;
98
Dianne Hackborn33f5ddd2014-07-21 15:35:45 -070099 /**
100 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller should
101 * use its default security check. This mode is not normally used; it should only be used
102 * with appop permissions, and callers must explicitly check for it and deal with it.
103 */
104 public static final int MODE_DEFAULT = 3;
105
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500106 // when adding one of these:
107 // - increment _NUM_OP
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700108 // - add rows to sOpToSwitch, sOpToString, sOpNames, sOpPerms, sOpDefaultMode
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500109 // - add descriptive strings to Settings/res/values/arrays.xml
David Christie0b837452013-07-29 16:02:13 -0700110 // - add the op to the appropriate template in AppOpsState.OpsTemplate (settings app)
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700111
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700112 /** @hide No operation specified. */
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800113 public static final int OP_NONE = -1;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700114 /** @hide Access to coarse location information. */
Dianne Hackborn35654b62013-01-14 17:38:02 -0800115 public static final int OP_COARSE_LOCATION = 0;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700116 /** @hide Access to fine location information. */
Dianne Hackborn35654b62013-01-14 17:38:02 -0800117 public static final int OP_FINE_LOCATION = 1;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700118 /** @hide Causing GPS to run. */
Dianne Hackborn35654b62013-01-14 17:38:02 -0800119 public static final int OP_GPS = 2;
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800120 /** @hide */
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700121 public static final int OP_VIBRATE = 3;
122 /** @hide */
123 public static final int OP_READ_CONTACTS = 4;
124 /** @hide */
125 public static final int OP_WRITE_CONTACTS = 5;
126 /** @hide */
127 public static final int OP_READ_CALL_LOG = 6;
128 /** @hide */
129 public static final int OP_WRITE_CALL_LOG = 7;
130 /** @hide */
131 public static final int OP_READ_CALENDAR = 8;
132 /** @hide */
133 public static final int OP_WRITE_CALENDAR = 9;
134 /** @hide */
135 public static final int OP_WIFI_SCAN = 10;
136 /** @hide */
137 public static final int OP_POST_NOTIFICATION = 11;
138 /** @hide */
139 public static final int OP_NEIGHBORING_CELLS = 12;
140 /** @hide */
141 public static final int OP_CALL_PHONE = 13;
142 /** @hide */
143 public static final int OP_READ_SMS = 14;
144 /** @hide */
145 public static final int OP_WRITE_SMS = 15;
146 /** @hide */
147 public static final int OP_RECEIVE_SMS = 16;
148 /** @hide */
149 public static final int OP_RECEIVE_EMERGECY_SMS = 17;
150 /** @hide */
151 public static final int OP_RECEIVE_MMS = 18;
152 /** @hide */
153 public static final int OP_RECEIVE_WAP_PUSH = 19;
154 /** @hide */
155 public static final int OP_SEND_SMS = 20;
156 /** @hide */
157 public static final int OP_READ_ICC_SMS = 21;
158 /** @hide */
159 public static final int OP_WRITE_ICC_SMS = 22;
160 /** @hide */
161 public static final int OP_WRITE_SETTINGS = 23;
162 /** @hide */
163 public static final int OP_SYSTEM_ALERT_WINDOW = 24;
164 /** @hide */
165 public static final int OP_ACCESS_NOTIFICATIONS = 25;
166 /** @hide */
167 public static final int OP_CAMERA = 26;
168 /** @hide */
169 public static final int OP_RECORD_AUDIO = 27;
170 /** @hide */
171 public static final int OP_PLAY_AUDIO = 28;
172 /** @hide */
173 public static final int OP_READ_CLIPBOARD = 29;
174 /** @hide */
175 public static final int OP_WRITE_CLIPBOARD = 30;
176 /** @hide */
177 public static final int OP_TAKE_MEDIA_BUTTONS = 31;
178 /** @hide */
179 public static final int OP_TAKE_AUDIO_FOCUS = 32;
180 /** @hide */
181 public static final int OP_AUDIO_MASTER_VOLUME = 33;
182 /** @hide */
183 public static final int OP_AUDIO_VOICE_VOLUME = 34;
184 /** @hide */
185 public static final int OP_AUDIO_RING_VOLUME = 35;
186 /** @hide */
187 public static final int OP_AUDIO_MEDIA_VOLUME = 36;
188 /** @hide */
189 public static final int OP_AUDIO_ALARM_VOLUME = 37;
190 /** @hide */
191 public static final int OP_AUDIO_NOTIFICATION_VOLUME = 38;
192 /** @hide */
193 public static final int OP_AUDIO_BLUETOOTH_VOLUME = 39;
194 /** @hide */
195 public static final int OP_WAKE_LOCK = 40;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700196 /** @hide Continually monitoring location data. */
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700197 public static final int OP_MONITOR_LOCATION = 41;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700198 /** @hide Continually monitoring location data with a relatively high power request. */
David Christie0b837452013-07-29 16:02:13 -0700199 public static final int OP_MONITOR_HIGH_POWER_LOCATION = 42;
Dianne Hackborne22b3b12014-05-07 18:06:44 -0700200 /** @hide Retrieve current usage stats via {@link UsageStatsManager}. */
201 public static final int OP_GET_USAGE_STATS = 43;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700202 /** @hide */
Emily Bernier22c921a2014-05-28 11:01:32 -0400203 public static final int OP_MUTE_MICROPHONE = 44;
204 /** @hide */
Jason Monk1c7c3192014-06-26 12:52:18 -0400205 public static final int OP_TOAST_WINDOW = 45;
Michael Wrightc39d47a2014-07-08 18:07:36 -0700206 /** @hide Capture the device's display contents and/or audio */
207 public static final int OP_PROJECT_MEDIA = 46;
Jeff Davidson05542602014-08-11 14:07:27 -0700208 /** @hide Activate a VPN connection without user intervention. */
209 public static final int OP_ACTIVATE_VPN = 47;
Benjamin Franzf3ece362015-02-11 10:51:10 +0000210 /** @hide Access the WallpaperManagerAPI to write wallpapers. */
211 public static final int OP_WRITE_WALLPAPER = 48;
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700212 /** @hide Received the assist structure from an app. */
213 public static final int OP_ASSIST_STRUCTURE = 49;
214 /** @hide Received a screenshot from assist. */
215 public static final int OP_ASSIST_SCREENSHOT = 50;
Svet Ganov16a16892015-04-16 10:32:04 -0700216 /** @hide Read the phone state. */
217 public static final int OP_READ_PHONE_STATE = 51;
Svet Ganovc3300092015-04-17 09:07:22 -0700218 /** @hide Add voicemail messages to the voicemail content provider. */
219 public static final int OP_ADD_VOICEMAIL = 52;
Jason Monk1c7c3192014-06-26 12:52:18 -0400220 /** @hide */
Svet Ganovc3300092015-04-17 09:07:22 -0700221 public static final int _NUM_OP = 53;
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800222
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700223 /** Access to coarse location information. */
224 public static final String OPSTR_COARSE_LOCATION =
225 "android:coarse_location";
226 /** Access to fine location information. */
227 public static final String OPSTR_FINE_LOCATION =
228 "android:fine_location";
229 /** Continually monitoring location data. */
230 public static final String OPSTR_MONITOR_LOCATION
231 = "android:monitor_location";
232 /** Continually monitoring location data with a relatively high power request. */
233 public static final String OPSTR_MONITOR_HIGH_POWER_LOCATION
234 = "android:monitor_location_high_power";
Dianne Hackborn5064e7c2014-09-02 10:57:16 -0700235 /** Access to {@link android.app.usage.UsageStatsManager}. */
236 public static final String OPSTR_GET_USAGE_STATS
237 = "android:get_usage_stats";
Jeff Davidson05542602014-08-11 14:07:27 -0700238 /** Activate a VPN connection without user intervention. @hide */
239 @SystemApi
240 public static final String OPSTR_ACTIVATE_VPN = "android:activate_vpn";
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700241
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800242 /**
243 * This maps each operation to the operation that serves as the
244 * switch to determine whether it is allowed. Generally this is
245 * a 1:1 mapping, but for some things (like location) that have
246 * multiple low-level operations being tracked that should be
David Christie0b837452013-07-29 16:02:13 -0700247 * presented to the user as one switch then this can be used to
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800248 * make them all controlled by the same single operation.
249 */
250 private static int[] sOpToSwitch = new int[] {
251 OP_COARSE_LOCATION,
252 OP_COARSE_LOCATION,
253 OP_COARSE_LOCATION,
254 OP_VIBRATE,
255 OP_READ_CONTACTS,
256 OP_WRITE_CONTACTS,
257 OP_READ_CALL_LOG,
258 OP_WRITE_CALL_LOG,
259 OP_READ_CALENDAR,
260 OP_WRITE_CALENDAR,
261 OP_COARSE_LOCATION,
262 OP_POST_NOTIFICATION,
263 OP_COARSE_LOCATION,
264 OP_CALL_PHONE,
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800265 OP_READ_SMS,
266 OP_WRITE_SMS,
David Braun18966a82013-09-10 13:14:46 -0700267 OP_RECEIVE_SMS,
268 OP_RECEIVE_SMS,
269 OP_RECEIVE_SMS,
270 OP_RECEIVE_SMS,
271 OP_SEND_SMS,
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800272 OP_READ_SMS,
273 OP_WRITE_SMS,
Dianne Hackborn961321f2013-02-05 17:22:41 -0800274 OP_WRITE_SETTINGS,
Dianne Hackbornc2293022013-02-06 23:14:49 -0800275 OP_SYSTEM_ALERT_WINDOW,
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500276 OP_ACCESS_NOTIFICATIONS,
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800277 OP_CAMERA,
278 OP_RECORD_AUDIO,
279 OP_PLAY_AUDIO,
Dianne Hackbornefcc1a22013-02-25 18:02:35 -0800280 OP_READ_CLIPBOARD,
281 OP_WRITE_CLIPBOARD,
Dianne Hackbornba50b97c2013-04-30 15:04:46 -0700282 OP_TAKE_MEDIA_BUTTONS,
283 OP_TAKE_AUDIO_FOCUS,
284 OP_AUDIO_MASTER_VOLUME,
285 OP_AUDIO_VOICE_VOLUME,
286 OP_AUDIO_RING_VOLUME,
287 OP_AUDIO_MEDIA_VOLUME,
288 OP_AUDIO_ALARM_VOLUME,
289 OP_AUDIO_NOTIFICATION_VOLUME,
290 OP_AUDIO_BLUETOOTH_VOLUME,
Dianne Hackborn713df152013-05-17 11:27:57 -0700291 OP_WAKE_LOCK,
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700292 OP_COARSE_LOCATION,
David Christie0b837452013-07-29 16:02:13 -0700293 OP_COARSE_LOCATION,
Dianne Hackborne22b3b12014-05-07 18:06:44 -0700294 OP_GET_USAGE_STATS,
Jason Monk1c7c3192014-06-26 12:52:18 -0400295 OP_MUTE_MICROPHONE,
296 OP_TOAST_WINDOW,
Michael Wrightc39d47a2014-07-08 18:07:36 -0700297 OP_PROJECT_MEDIA,
Jeff Davidson05542602014-08-11 14:07:27 -0700298 OP_ACTIVATE_VPN,
Benjamin Franzf3ece362015-02-11 10:51:10 +0000299 OP_WRITE_WALLPAPER,
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700300 OP_ASSIST_STRUCTURE,
301 OP_ASSIST_SCREENSHOT,
Svet Ganovc3300092015-04-17 09:07:22 -0700302 OP_READ_PHONE_STATE,
303 OP_ADD_VOICEMAIL
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800304 };
305
306 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700307 * This maps each operation to the public string constant for it.
308 * If it doesn't have a public string constant, it maps to null.
309 */
310 private static String[] sOpToString = new String[] {
311 OPSTR_COARSE_LOCATION,
312 OPSTR_FINE_LOCATION,
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 null,
350 null,
351 null,
352 OPSTR_MONITOR_LOCATION,
353 OPSTR_MONITOR_HIGH_POWER_LOCATION,
Dianne Hackborn5064e7c2014-09-02 10:57:16 -0700354 OPSTR_GET_USAGE_STATS,
Emily Bernier22c921a2014-05-28 11:01:32 -0400355 null,
Jason Monk1c7c3192014-06-26 12:52:18 -0400356 null,
Michael Wrightc39d47a2014-07-08 18:07:36 -0700357 null,
Jeff Davidson05542602014-08-11 14:07:27 -0700358 OPSTR_ACTIVATE_VPN,
Benjamin Franzf3ece362015-02-11 10:51:10 +0000359 null,
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700360 null,
361 null,
Svet Ganovc3300092015-04-17 09:07:22 -0700362 null,
Svet Ganov16a16892015-04-16 10:32:04 -0700363 null
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700364 };
365
366 /**
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800367 * This provides a simple name for each operation to be used
368 * in debug output.
369 */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800370 private static String[] sOpNames = new String[] {
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800371 "COARSE_LOCATION",
372 "FINE_LOCATION",
373 "GPS",
374 "VIBRATE",
375 "READ_CONTACTS",
376 "WRITE_CONTACTS",
377 "READ_CALL_LOG",
378 "WRITE_CALL_LOG",
379 "READ_CALENDAR",
380 "WRITE_CALENDAR",
381 "WIFI_SCAN",
382 "POST_NOTIFICATION",
383 "NEIGHBORING_CELLS",
384 "CALL_PHONE",
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800385 "READ_SMS",
386 "WRITE_SMS",
387 "RECEIVE_SMS",
388 "RECEIVE_EMERGECY_SMS",
389 "RECEIVE_MMS",
390 "RECEIVE_WAP_PUSH",
391 "SEND_SMS",
392 "READ_ICC_SMS",
393 "WRITE_ICC_SMS",
Dianne Hackborn961321f2013-02-05 17:22:41 -0800394 "WRITE_SETTINGS",
Dianne Hackbornc2293022013-02-06 23:14:49 -0800395 "SYSTEM_ALERT_WINDOW",
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500396 "ACCESS_NOTIFICATIONS",
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800397 "CAMERA",
398 "RECORD_AUDIO",
399 "PLAY_AUDIO",
Dianne Hackbornefcc1a22013-02-25 18:02:35 -0800400 "READ_CLIPBOARD",
401 "WRITE_CLIPBOARD",
Dianne Hackbornba50b97c2013-04-30 15:04:46 -0700402 "TAKE_MEDIA_BUTTONS",
403 "TAKE_AUDIO_FOCUS",
404 "AUDIO_MASTER_VOLUME",
405 "AUDIO_VOICE_VOLUME",
406 "AUDIO_RING_VOLUME",
407 "AUDIO_MEDIA_VOLUME",
408 "AUDIO_ALARM_VOLUME",
409 "AUDIO_NOTIFICATION_VOLUME",
410 "AUDIO_BLUETOOTH_VOLUME",
Dianne Hackborn713df152013-05-17 11:27:57 -0700411 "WAKE_LOCK",
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700412 "MONITOR_LOCATION",
David Christie0b837452013-07-29 16:02:13 -0700413 "MONITOR_HIGH_POWER_LOCATION",
Emily Bernier22c921a2014-05-28 11:01:32 -0400414 "GET_USAGE_STATS",
Michael Wrightc39d47a2014-07-08 18:07:36 -0700415 "MUTE_MICROPHONE",
Jason Monk1c7c3192014-06-26 12:52:18 -0400416 "TOAST_WINDOW",
Michael Wrightc39d47a2014-07-08 18:07:36 -0700417 "PROJECT_MEDIA",
Jeff Davidson05542602014-08-11 14:07:27 -0700418 "ACTIVATE_VPN",
Benjamin Franzf3ece362015-02-11 10:51:10 +0000419 "WRITE_WALLPAPER",
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700420 "ASSIST_STRUCTURE",
Svet Ganov16a16892015-04-16 10:32:04 -0700421 "ASSIST_SCREENSHOT",
Svet Ganovc3300092015-04-17 09:07:22 -0700422 "OP_READ_PHONE_STATE",
423 "ADD_VOICEMAIL"
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800424 };
425
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800426 /**
427 * This optionally maps a permission to an operation. If there
428 * is no permission associated with an operation, it is null.
429 */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800430 private static String[] sOpPerms = new String[] {
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800431 android.Manifest.permission.ACCESS_COARSE_LOCATION,
432 android.Manifest.permission.ACCESS_FINE_LOCATION,
433 null,
434 android.Manifest.permission.VIBRATE,
435 android.Manifest.permission.READ_CONTACTS,
436 android.Manifest.permission.WRITE_CONTACTS,
437 android.Manifest.permission.READ_CALL_LOG,
438 android.Manifest.permission.WRITE_CALL_LOG,
439 android.Manifest.permission.READ_CALENDAR,
440 android.Manifest.permission.WRITE_CALENDAR,
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800441 android.Manifest.permission.ACCESS_WIFI_STATE,
Robert Craigf97616c2013-10-07 12:32:02 -0400442 null, // no permission required for notifications
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800443 null, // neighboring cells shares the coarse location perm
444 android.Manifest.permission.CALL_PHONE,
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800445 android.Manifest.permission.READ_SMS,
Svetoslav6c589572015-04-16 16:19:24 -0700446 null, // no permission required for writing sms
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800447 android.Manifest.permission.RECEIVE_SMS,
448 android.Manifest.permission.RECEIVE_EMERGENCY_BROADCAST,
449 android.Manifest.permission.RECEIVE_MMS,
450 android.Manifest.permission.RECEIVE_WAP_PUSH,
451 android.Manifest.permission.SEND_SMS,
452 android.Manifest.permission.READ_SMS,
Svetoslav6c589572015-04-16 16:19:24 -0700453 null, // no permission required for writing icc sms
Dianne Hackborn961321f2013-02-05 17:22:41 -0800454 android.Manifest.permission.WRITE_SETTINGS,
Dianne Hackbornc2293022013-02-06 23:14:49 -0800455 android.Manifest.permission.SYSTEM_ALERT_WINDOW,
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500456 android.Manifest.permission.ACCESS_NOTIFICATIONS,
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800457 android.Manifest.permission.CAMERA,
458 android.Manifest.permission.RECORD_AUDIO,
459 null, // no permission for playing audio
Dianne Hackbornefcc1a22013-02-25 18:02:35 -0800460 null, // no permission for reading clipboard
461 null, // no permission for writing clipboard
Dianne Hackbornba50b97c2013-04-30 15:04:46 -0700462 null, // no permission for taking media buttons
463 null, // no permission for taking audio focus
464 null, // no permission for changing master volume
465 null, // no permission for changing voice volume
466 null, // no permission for changing ring volume
467 null, // no permission for changing media volume
468 null, // no permission for changing alarm volume
469 null, // no permission for changing notification volume
470 null, // no permission for changing bluetooth volume
Dianne Hackborn713df152013-05-17 11:27:57 -0700471 android.Manifest.permission.WAKE_LOCK,
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700472 null, // no permission for generic location monitoring
David Christie0b837452013-07-29 16:02:13 -0700473 null, // no permission for high power location monitoring
Dianne Hackborne22b3b12014-05-07 18:06:44 -0700474 android.Manifest.permission.PACKAGE_USAGE_STATS,
Emily Bernier22c921a2014-05-28 11:01:32 -0400475 null, // no permission for muting/unmuting microphone
Jason Monk1c7c3192014-06-26 12:52:18 -0400476 null, // no permission for displaying toasts
Michael Wrightc39d47a2014-07-08 18:07:36 -0700477 null, // no permission for projecting media
Jeff Davidson05542602014-08-11 14:07:27 -0700478 null, // no permission for activating vpn
Benjamin Franzf3ece362015-02-11 10:51:10 +0000479 null, // no permission for supporting wallpaper
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700480 null, // no permission for receiving assist structure
481 null, // no permission for receiving assist screenshot
Svet Ganovc3300092015-04-17 09:07:22 -0700482 Manifest.permission.READ_PHONE_STATE,
483 Manifest.permission.ADD_VOICEMAIL
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800484 };
485
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800486 /**
Jason Monk62062992014-05-06 09:55:28 -0400487 * Specifies whether an Op should be restricted by a user restriction.
488 * Each Op should be filled with a restriction string from UserManager or
489 * null to specify it is not affected by any user restriction.
490 */
491 private static String[] sOpRestrictions = new String[] {
Julia Reynolds9854d572014-07-02 14:46:02 -0400492 UserManager.DISALLOW_SHARE_LOCATION, //COARSE_LOCATION
493 UserManager.DISALLOW_SHARE_LOCATION, //FINE_LOCATION
494 UserManager.DISALLOW_SHARE_LOCATION, //GPS
Jason Monk62062992014-05-06 09:55:28 -0400495 null, //VIBRATE
496 null, //READ_CONTACTS
497 null, //WRITE_CONTACTS
Yorke Lee15f83c62014-08-13 14:14:29 -0700498 UserManager.DISALLOW_OUTGOING_CALLS, //READ_CALL_LOG
499 UserManager.DISALLOW_OUTGOING_CALLS, //WRITE_CALL_LOG
Jason Monk62062992014-05-06 09:55:28 -0400500 null, //READ_CALENDAR
501 null, //WRITE_CALENDAR
Julia Reynolds9854d572014-07-02 14:46:02 -0400502 UserManager.DISALLOW_SHARE_LOCATION, //WIFI_SCAN
Jason Monk62062992014-05-06 09:55:28 -0400503 null, //POST_NOTIFICATION
504 null, //NEIGHBORING_CELLS
505 null, //CALL_PHONE
Amith Yamasani41c1ded2014-08-05 11:15:05 -0700506 UserManager.DISALLOW_SMS, //READ_SMS
507 UserManager.DISALLOW_SMS, //WRITE_SMS
508 UserManager.DISALLOW_SMS, //RECEIVE_SMS
509 null, //RECEIVE_EMERGENCY_SMS
510 UserManager.DISALLOW_SMS, //RECEIVE_MMS
Jason Monk62062992014-05-06 09:55:28 -0400511 null, //RECEIVE_WAP_PUSH
Amith Yamasani41c1ded2014-08-05 11:15:05 -0700512 UserManager.DISALLOW_SMS, //SEND_SMS
513 UserManager.DISALLOW_SMS, //READ_ICC_SMS
514 UserManager.DISALLOW_SMS, //WRITE_ICC_SMS
Jason Monk62062992014-05-06 09:55:28 -0400515 null, //WRITE_SETTINGS
Jason Monk1c7c3192014-06-26 12:52:18 -0400516 UserManager.DISALLOW_CREATE_WINDOWS, //SYSTEM_ALERT_WINDOW
Jason Monk62062992014-05-06 09:55:28 -0400517 null, //ACCESS_NOTIFICATIONS
518 null, //CAMERA
519 null, //RECORD_AUDIO
520 null, //PLAY_AUDIO
521 null, //READ_CLIPBOARD
522 null, //WRITE_CLIPBOARD
523 null, //TAKE_MEDIA_BUTTONS
524 null, //TAKE_AUDIO_FOCUS
Emily Bernier45775c42014-05-16 15:12:04 -0400525 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MASTER_VOLUME
526 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_VOICE_VOLUME
527 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_RING_VOLUME
528 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MEDIA_VOLUME
529 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ALARM_VOLUME
530 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_NOTIFICATION_VOLUME
531 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_BLUETOOTH_VOLUME
Jason Monk62062992014-05-06 09:55:28 -0400532 null, //WAKE_LOCK
Julia Reynolds9854d572014-07-02 14:46:02 -0400533 UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_LOCATION
534 UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_HIGH_POWER_LOCATION
Jason Monk62062992014-05-06 09:55:28 -0400535 null, //GET_USAGE_STATS
Emily Bernier22c921a2014-05-28 11:01:32 -0400536 UserManager.DISALLOW_UNMUTE_MICROPHONE, // MUTE_MICROPHONE
Jason Monk1c7c3192014-06-26 12:52:18 -0400537 UserManager.DISALLOW_CREATE_WINDOWS, // TOAST_WINDOW
Michael Wrightc39d47a2014-07-08 18:07:36 -0700538 null, //PROJECT_MEDIA
Jeff Davidson05542602014-08-11 14:07:27 -0700539 UserManager.DISALLOW_CONFIG_VPN, // ACTIVATE_VPN
Benjamin Franzf3ece362015-02-11 10:51:10 +0000540 UserManager.DISALLOW_WALLPAPER, // WRITE_WALLPAPER
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700541 null, // ASSIST_STRUCTURE
542 null, // ASSIST_SCREENSHOT
Svet Ganovc3300092015-04-17 09:07:22 -0700543 null, // READ_PHONE_STATE
544 null // ADD_VOICEMAIL
Jason Monk1c7c3192014-06-26 12:52:18 -0400545 };
546
547 /**
548 * This specifies whether each option should allow the system
549 * (and system ui) to bypass the user restriction when active.
550 */
551 private static boolean[] sOpAllowSystemRestrictionBypass = new boolean[] {
552 false, //COARSE_LOCATION
553 false, //FINE_LOCATION
554 false, //GPS
555 false, //VIBRATE
556 false, //READ_CONTACTS
557 false, //WRITE_CONTACTS
558 false, //READ_CALL_LOG
559 false, //WRITE_CALL_LOG
560 false, //READ_CALENDAR
561 false, //WRITE_CALENDAR
Julia Reynolds9854d572014-07-02 14:46:02 -0400562 true, //WIFI_SCAN
Jason Monk1c7c3192014-06-26 12:52:18 -0400563 false, //POST_NOTIFICATION
564 false, //NEIGHBORING_CELLS
565 false, //CALL_PHONE
566 false, //READ_SMS
567 false, //WRITE_SMS
568 false, //RECEIVE_SMS
569 false, //RECEIVE_EMERGECY_SMS
570 false, //RECEIVE_MMS
571 false, //RECEIVE_WAP_PUSH
572 false, //SEND_SMS
573 false, //READ_ICC_SMS
574 false, //WRITE_ICC_SMS
575 false, //WRITE_SETTINGS
576 true, //SYSTEM_ALERT_WINDOW
577 false, //ACCESS_NOTIFICATIONS
578 false, //CAMERA
579 false, //RECORD_AUDIO
580 false, //PLAY_AUDIO
581 false, //READ_CLIPBOARD
582 false, //WRITE_CLIPBOARD
583 false, //TAKE_MEDIA_BUTTONS
584 false, //TAKE_AUDIO_FOCUS
585 false, //AUDIO_MASTER_VOLUME
586 false, //AUDIO_VOICE_VOLUME
587 false, //AUDIO_RING_VOLUME
588 false, //AUDIO_MEDIA_VOLUME
589 false, //AUDIO_ALARM_VOLUME
590 false, //AUDIO_NOTIFICATION_VOLUME
591 false, //AUDIO_BLUETOOTH_VOLUME
592 false, //WAKE_LOCK
593 false, //MONITOR_LOCATION
594 false, //MONITOR_HIGH_POWER_LOCATION
595 false, //GET_USAGE_STATS
Michael Wrightc39d47a2014-07-08 18:07:36 -0700596 false, //MUTE_MICROPHONE
597 true, //TOAST_WINDOW
598 false, //PROJECT_MEDIA
Jeff Davidson05542602014-08-11 14:07:27 -0700599 false, //ACTIVATE_VPN
Benjamin Franzf3ece362015-02-11 10:51:10 +0000600 false, //WALLPAPER
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700601 false, //ASSIST_STRUCTURE
602 false, //ASSIST_SCREENSHOT
Svet Ganov16a16892015-04-16 10:32:04 -0700603 false, //READ_PHONE_STATE
Svet Ganovc3300092015-04-17 09:07:22 -0700604 false //ADD_VOICEMAIL
Jason Monk62062992014-05-06 09:55:28 -0400605 };
606
607 /**
David Braunf5d83192013-09-16 13:43:51 -0700608 * This specifies the default mode for each operation.
609 */
610 private static int[] sOpDefaultMode = new int[] {
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_IGNORED, // OP_WRITE_SMS
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,
646 AppOpsManager.MODE_ALLOWED,
647 AppOpsManager.MODE_ALLOWED,
648 AppOpsManager.MODE_ALLOWED,
649 AppOpsManager.MODE_ALLOWED,
650 AppOpsManager.MODE_ALLOWED,
651 AppOpsManager.MODE_ALLOWED,
652 AppOpsManager.MODE_ALLOWED,
653 AppOpsManager.MODE_ALLOWED,
Dianne Hackborn33f5ddd2014-07-21 15:35:45 -0700654 AppOpsManager.MODE_DEFAULT, // OP_GET_USAGE_STATS
Emily Bernier22c921a2014-05-28 11:01:32 -0400655 AppOpsManager.MODE_ALLOWED,
Jason Monk1c7c3192014-06-26 12:52:18 -0400656 AppOpsManager.MODE_ALLOWED,
Michael Wrightc39d47a2014-07-08 18:07:36 -0700657 AppOpsManager.MODE_IGNORED, // OP_PROJECT_MEDIA
Jeff Davidson05542602014-08-11 14:07:27 -0700658 AppOpsManager.MODE_IGNORED, // OP_ACTIVATE_VPN
Benjamin Franzf3ece362015-02-11 10:51:10 +0000659 AppOpsManager.MODE_ALLOWED,
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700660 AppOpsManager.MODE_ALLOWED,
661 AppOpsManager.MODE_ALLOWED,
Svet Ganovc3300092015-04-17 09:07:22 -0700662 AppOpsManager.MODE_ALLOWED,
Svet Ganov16a16892015-04-16 10:32:04 -0700663 AppOpsManager.MODE_ALLOWED
David Braunf5d83192013-09-16 13:43:51 -0700664 };
665
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700666 /**
667 * This specifies whether each option is allowed to be reset
668 * when resetting all app preferences. Disable reset for
669 * app ops that are under strong control of some part of the
670 * system (such as OP_WRITE_SMS, which should be allowed only
671 * for whichever app is selected as the current SMS app).
672 */
673 private static boolean[] sOpDisableReset = new boolean[] {
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 true, // OP_WRITE_SMS
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,
708 false,
709 false,
710 false,
711 false,
712 false,
713 false,
714 false,
715 false,
716 false,
Dianne Hackborne22b3b12014-05-07 18:06:44 -0700717 false,
Emily Bernier22c921a2014-05-28 11:01:32 -0400718 false,
Jason Monk1c7c3192014-06-26 12:52:18 -0400719 false,
Michael Wrightc39d47a2014-07-08 18:07:36 -0700720 false,
Jeff Davidson05542602014-08-11 14:07:27 -0700721 false,
Benjamin Franzf3ece362015-02-11 10:51:10 +0000722 false,
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700723 false,
724 false,
Svet Ganovc3300092015-04-17 09:07:22 -0700725 false,
Svet Ganov16a16892015-04-16 10:32:04 -0700726 false
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700727 };
728
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700729 private static HashMap<String, Integer> sOpStrToOp = new HashMap<String, Integer>();
730
731 static {
732 if (sOpToSwitch.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700733 throw new IllegalStateException("sOpToSwitch length " + sOpToSwitch.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700734 + " should be " + _NUM_OP);
735 }
736 if (sOpToString.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700737 throw new IllegalStateException("sOpToString length " + sOpToString.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700738 + " should be " + _NUM_OP);
739 }
740 if (sOpNames.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700741 throw new IllegalStateException("sOpNames length " + sOpNames.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700742 + " should be " + _NUM_OP);
743 }
744 if (sOpPerms.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700745 throw new IllegalStateException("sOpPerms length " + sOpPerms.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700746 + " should be " + _NUM_OP);
747 }
748 if (sOpDefaultMode.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700749 throw new IllegalStateException("sOpDefaultMode length " + sOpDefaultMode.length
750 + " should be " + _NUM_OP);
751 }
752 if (sOpDisableReset.length != _NUM_OP) {
753 throw new IllegalStateException("sOpDisableReset length " + sOpDisableReset.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700754 + " should be " + _NUM_OP);
755 }
Jason Monk62062992014-05-06 09:55:28 -0400756 if (sOpRestrictions.length != _NUM_OP) {
757 throw new IllegalStateException("sOpRestrictions length " + sOpRestrictions.length
758 + " should be " + _NUM_OP);
759 }
Jason Monk1c7c3192014-06-26 12:52:18 -0400760 if (sOpAllowSystemRestrictionBypass.length != _NUM_OP) {
761 throw new IllegalStateException("sOpAllowSYstemRestrictionsBypass length "
762 + sOpRestrictions.length + " should be " + _NUM_OP);
763 }
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700764 for (int i=0; i<_NUM_OP; i++) {
765 if (sOpToString[i] != null) {
766 sOpStrToOp.put(sOpToString[i], i);
767 }
768 }
769 }
770
David Braunf5d83192013-09-16 13:43:51 -0700771 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800772 * Retrieve the op switch that controls the given operation.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700773 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800774 */
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800775 public static int opToSwitch(int op) {
776 return sOpToSwitch[op];
777 }
778
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800779 /**
780 * Retrieve a non-localized name for the operation, for debugging output.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700781 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800782 */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800783 public static String opToName(int op) {
Dianne Hackbornc2293022013-02-06 23:14:49 -0800784 if (op == OP_NONE) return "NONE";
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800785 return op < sOpNames.length ? sOpNames[op] : ("Unknown(" + op + ")");
786 }
787
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800788 /**
Dianne Hackborn7b7c58b2014-12-02 18:32:20 -0800789 * @hide
790 */
791 public static int strDebugOpToOp(String op) {
792 for (int i=0; i<sOpNames.length; i++) {
793 if (sOpNames[i].equals(op)) {
794 return i;
795 }
796 }
797 throw new IllegalArgumentException("Unknown operation string: " + op);
798 }
799
800 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800801 * Retrieve the permission associated with an operation, or null if there is not one.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700802 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800803 */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800804 public static String opToPermission(int op) {
805 return sOpPerms[op];
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800806 }
807
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800808 /**
Jason Monk62062992014-05-06 09:55:28 -0400809 * Retrieve the user restriction associated with an operation, or null if there is not one.
810 * @hide
811 */
812 public static String opToRestriction(int op) {
813 return sOpRestrictions[op];
814 }
815
816 /**
Jason Monk1c7c3192014-06-26 12:52:18 -0400817 * Retrieve whether the op allows the system (and system ui) to
818 * bypass the user restriction.
819 * @hide
820 */
821 public static boolean opAllowSystemBypassRestriction(int op) {
822 return sOpAllowSystemRestrictionBypass[op];
823 }
824
825 /**
David Braunf5d83192013-09-16 13:43:51 -0700826 * Retrieve the default mode for the operation.
827 * @hide
828 */
829 public static int opToDefaultMode(int op) {
830 return sOpDefaultMode[op];
831 }
832
833 /**
Dianne Hackborn8828d3a2013-09-25 16:47:10 -0700834 * Retrieve whether the op allows itself to be reset.
835 * @hide
836 */
837 public static boolean opAllowsReset(int op) {
838 return !sOpDisableReset[op];
839 }
840
841 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800842 * Class holding all of the operation information associated with an app.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700843 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800844 */
Dianne Hackborn35654b62013-01-14 17:38:02 -0800845 public static class PackageOps implements Parcelable {
846 private final String mPackageName;
847 private final int mUid;
848 private final List<OpEntry> mEntries;
849
850 public PackageOps(String packageName, int uid, List<OpEntry> entries) {
851 mPackageName = packageName;
852 mUid = uid;
853 mEntries = entries;
854 }
855
856 public String getPackageName() {
857 return mPackageName;
858 }
859
860 public int getUid() {
861 return mUid;
862 }
863
864 public List<OpEntry> getOps() {
865 return mEntries;
866 }
867
868 @Override
869 public int describeContents() {
870 return 0;
871 }
872
873 @Override
874 public void writeToParcel(Parcel dest, int flags) {
875 dest.writeString(mPackageName);
876 dest.writeInt(mUid);
877 dest.writeInt(mEntries.size());
878 for (int i=0; i<mEntries.size(); i++) {
879 mEntries.get(i).writeToParcel(dest, flags);
880 }
881 }
882
883 PackageOps(Parcel source) {
884 mPackageName = source.readString();
885 mUid = source.readInt();
886 mEntries = new ArrayList<OpEntry>();
887 final int N = source.readInt();
888 for (int i=0; i<N; i++) {
889 mEntries.add(OpEntry.CREATOR.createFromParcel(source));
890 }
891 }
892
893 public static final Creator<PackageOps> CREATOR = new Creator<PackageOps>() {
894 @Override public PackageOps createFromParcel(Parcel source) {
895 return new PackageOps(source);
896 }
897
898 @Override public PackageOps[] newArray(int size) {
899 return new PackageOps[size];
900 }
901 };
902 }
903
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800904 /**
905 * Class holding the information about one unique operation of an application.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700906 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800907 */
Dianne Hackborn35654b62013-01-14 17:38:02 -0800908 public static class OpEntry implements Parcelable {
909 private final int mOp;
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800910 private final int mMode;
Dianne Hackborn35654b62013-01-14 17:38:02 -0800911 private final long mTime;
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800912 private final long mRejectTime;
Dianne Hackborn35654b62013-01-14 17:38:02 -0800913 private final int mDuration;
914
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800915 public OpEntry(int op, int mode, long time, long rejectTime, int duration) {
Dianne Hackborn35654b62013-01-14 17:38:02 -0800916 mOp = op;
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800917 mMode = mode;
Dianne Hackborn35654b62013-01-14 17:38:02 -0800918 mTime = time;
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800919 mRejectTime = rejectTime;
Dianne Hackborn35654b62013-01-14 17:38:02 -0800920 mDuration = duration;
921 }
922
923 public int getOp() {
924 return mOp;
925 }
926
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800927 public int getMode() {
928 return mMode;
929 }
930
Dianne Hackborn35654b62013-01-14 17:38:02 -0800931 public long getTime() {
932 return mTime;
933 }
934
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800935 public long getRejectTime() {
936 return mRejectTime;
937 }
938
Dianne Hackborn35654b62013-01-14 17:38:02 -0800939 public boolean isRunning() {
940 return mDuration == -1;
941 }
942
943 public int getDuration() {
944 return mDuration == -1 ? (int)(System.currentTimeMillis()-mTime) : mDuration;
945 }
946
947 @Override
948 public int describeContents() {
949 return 0;
950 }
951
952 @Override
953 public void writeToParcel(Parcel dest, int flags) {
954 dest.writeInt(mOp);
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800955 dest.writeInt(mMode);
Dianne Hackborn35654b62013-01-14 17:38:02 -0800956 dest.writeLong(mTime);
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800957 dest.writeLong(mRejectTime);
Dianne Hackborn35654b62013-01-14 17:38:02 -0800958 dest.writeInt(mDuration);
959 }
960
961 OpEntry(Parcel source) {
962 mOp = source.readInt();
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800963 mMode = source.readInt();
Dianne Hackborn35654b62013-01-14 17:38:02 -0800964 mTime = source.readLong();
Dianne Hackborn5e45ee62013-01-24 19:13:44 -0800965 mRejectTime = source.readLong();
Dianne Hackborn35654b62013-01-14 17:38:02 -0800966 mDuration = source.readInt();
967 }
968
969 public static final Creator<OpEntry> CREATOR = new Creator<OpEntry>() {
970 @Override public OpEntry createFromParcel(Parcel source) {
971 return new OpEntry(source);
972 }
973
974 @Override public OpEntry[] newArray(int size) {
975 return new OpEntry[size];
976 }
977 };
978 }
979
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800980 /**
981 * Callback for notification of changes to operation state.
982 */
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700983 public interface OnOpChangedListener {
984 public void onOpChanged(String op, String packageName);
985 }
986
987 /**
988 * Callback for notification of changes to operation state.
989 * This allows you to see the raw op codes instead of strings.
990 * @hide
991 */
992 public static class OnOpChangedInternalListener implements OnOpChangedListener {
993 public void onOpChanged(String op, String packageName) { }
994 public void onOpChanged(int op, String packageName) { }
Dianne Hackbornc2293022013-02-06 23:14:49 -0800995 }
996
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700997 AppOpsManager(Context context, IAppOpsService service) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800998 mContext = context;
999 mService = service;
1000 }
1001
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001002 /**
1003 * Retrieve current operation state for all applications.
1004 *
1005 * @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 -07001006 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001007 */
Dianne Hackborn35654b62013-01-14 17:38:02 -08001008 public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) {
1009 try {
1010 return mService.getPackagesForOps(ops);
1011 } catch (RemoteException e) {
1012 }
1013 return null;
1014 }
1015
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001016 /**
1017 * Retrieve current operation state for one application.
1018 *
1019 * @param uid The uid of the application of interest.
1020 * @param packageName The name of the application of interest.
1021 * @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 -07001022 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001023 */
Dianne Hackborn72e39832013-01-18 18:36:09 -08001024 public List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, int[] ops) {
1025 try {
1026 return mService.getOpsForPackage(uid, packageName, ops);
1027 } catch (RemoteException e) {
1028 }
1029 return null;
1030 }
1031
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001032 /** @hide */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001033 public void setMode(int code, int uid, String packageName, int mode) {
1034 try {
1035 mService.setMode(code, uid, packageName, mode);
1036 } catch (RemoteException e) {
1037 }
1038 }
1039
John Spurlock1af30c72014-03-10 08:33:35 -04001040 /**
1041 * Set a non-persisted restriction on an audio operation at a stream-level.
1042 * Restrictions are temporary additional constraints imposed on top of the persisted rules
1043 * defined by {@link #setMode}.
1044 *
1045 * @param code The operation to restrict.
John Spurlock7b414672014-07-18 13:02:39 -04001046 * @param usage The {@link android.media.AudioAttributes} usage value.
John Spurlock1af30c72014-03-10 08:33:35 -04001047 * @param mode The restriction mode (MODE_IGNORED,MODE_ERRORED) or MODE_ALLOWED to unrestrict.
1048 * @param exceptionPackages Optional list of packages to exclude from the restriction.
1049 * @hide
1050 */
John Spurlock7b414672014-07-18 13:02:39 -04001051 public void setRestriction(int code, @AttributeUsage int usage, int mode,
1052 String[] exceptionPackages) {
John Spurlock1af30c72014-03-10 08:33:35 -04001053 try {
1054 final int uid = Binder.getCallingUid();
John Spurlock7b414672014-07-18 13:02:39 -04001055 mService.setAudioRestriction(code, usage, uid, mode, exceptionPackages);
John Spurlock1af30c72014-03-10 08:33:35 -04001056 } catch (RemoteException e) {
1057 }
1058 }
1059
Dianne Hackborn607b4142013-08-02 18:10:10 -07001060 /** @hide */
1061 public void resetAllModes() {
1062 try {
Dianne Hackborn7b7c58b2014-12-02 18:32:20 -08001063 mService.resetAllModes(UserHandle.myUserId(), null);
Dianne Hackborn607b4142013-08-02 18:10:10 -07001064 } catch (RemoteException e) {
1065 }
1066 }
1067
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001068 /**
1069 * Monitor for changes to the operating mode for the given op in the given app package.
Dianne Hackborne4cb66f2013-10-02 10:34:02 -07001070 * @param op The operation to monitor, one of OPSTR_*.
1071 * @param packageName The name of the application to monitor.
1072 * @param callback Where to report changes.
1073 */
1074 public void startWatchingMode(String op, String packageName,
1075 final OnOpChangedListener callback) {
1076 startWatchingMode(strOpToOp(op), packageName, callback);
1077 }
1078
1079 /**
1080 * Monitor for changes to the operating mode for the given op in the given app package.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001081 * @param op The operation to monitor, one of OP_*.
1082 * @param packageName The name of the application to monitor.
1083 * @param callback Where to report changes.
Dianne Hackborne4cb66f2013-10-02 10:34:02 -07001084 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001085 */
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001086 public void startWatchingMode(int op, String packageName, final OnOpChangedListener callback) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08001087 synchronized (mModeWatchers) {
1088 IAppOpsCallback cb = mModeWatchers.get(callback);
1089 if (cb == null) {
1090 cb = new IAppOpsCallback.Stub() {
1091 public void opChanged(int op, String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001092 if (callback instanceof OnOpChangedInternalListener) {
1093 ((OnOpChangedInternalListener)callback).onOpChanged(op, packageName);
1094 }
1095 if (sOpToString[op] != null) {
1096 callback.onOpChanged(sOpToString[op], packageName);
1097 }
Dianne Hackbornc2293022013-02-06 23:14:49 -08001098 }
1099 };
1100 mModeWatchers.put(callback, cb);
1101 }
1102 try {
1103 mService.startWatchingMode(op, packageName, cb);
1104 } catch (RemoteException e) {
1105 }
1106 }
1107 }
1108
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001109 /**
1110 * Stop monitoring that was previously started with {@link #startWatchingMode}. All
1111 * monitoring associated with this callback will be removed.
1112 */
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001113 public void stopWatchingMode(OnOpChangedListener callback) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08001114 synchronized (mModeWatchers) {
1115 IAppOpsCallback cb = mModeWatchers.get(callback);
1116 if (cb != null) {
1117 try {
1118 mService.stopWatchingMode(cb);
1119 } catch (RemoteException e) {
1120 }
1121 }
1122 }
1123 }
1124
Dianne Hackborn95d78532013-09-11 09:51:14 -07001125 private String buildSecurityExceptionMsg(int op, int uid, String packageName) {
1126 return packageName + " from uid " + uid + " not allowed to perform " + sOpNames[op];
1127 }
1128
Adam Lesinskib5cf61b2014-08-18 16:10:28 -07001129 /**
1130 * {@hide}
1131 */
1132 public static int strOpToOp(String op) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001133 Integer val = sOpStrToOp.get(op);
1134 if (val == null) {
1135 throw new IllegalArgumentException("Unknown operation string: " + op);
1136 }
1137 return val;
1138 }
1139
1140 /**
1141 * Do a quick check for whether an application might be able to perform an operation.
1142 * This is <em>not</em> a security check; you must use {@link #noteOp(String, int, String)}
1143 * or {@link #startOp(String, int, String)} for your actual security checks, which also
1144 * ensure that the given uid and package name are consistent. This function can just be
1145 * used for a quick check to see if an operation has been disabled for the application,
1146 * as an early reject of some work. This does not modify the time stamp or other data
1147 * about the operation.
1148 * @param op The operation to check. One of the OPSTR_* constants.
1149 * @param uid The user id of the application attempting to perform the operation.
1150 * @param packageName The name of the application attempting to perform the operation.
1151 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1152 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1153 * causing the app to crash).
1154 * @throws SecurityException If the app has been configured to crash on this op.
1155 */
1156 public int checkOp(String op, int uid, String packageName) {
1157 return checkOp(strOpToOp(op), uid, packageName);
1158 }
1159
1160 /**
John Spurlock925b85e2014-03-10 16:52:11 -04001161 * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001162 * returns {@link #MODE_ERRORED}.
1163 */
1164 public int checkOpNoThrow(String op, int uid, String packageName) {
1165 return checkOpNoThrow(strOpToOp(op), uid, packageName);
1166 }
1167
1168 /**
1169 * Make note of an application performing an operation. Note that you must pass
1170 * in both the uid and name of the application to be checked; this function will verify
1171 * that these two match, and if not, return {@link #MODE_IGNORED}. If this call
1172 * succeeds, the last execution time of the operation for this app will be updated to
1173 * the current time.
1174 * @param op The operation to note. One of the OPSTR_* constants.
1175 * @param uid The user id of the application attempting to perform the operation.
1176 * @param packageName The name of the application attempting to perform the operation.
1177 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1178 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1179 * causing the app to crash).
1180 * @throws SecurityException If the app has been configured to crash on this op.
1181 */
1182 public int noteOp(String op, int uid, String packageName) {
1183 return noteOp(strOpToOp(op), uid, packageName);
1184 }
1185
1186 /**
1187 * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
1188 * returns {@link #MODE_ERRORED}.
1189 */
1190 public int noteOpNoThrow(String op, int uid, String packageName) {
1191 return noteOpNoThrow(strOpToOp(op), uid, packageName);
1192 }
1193
1194 /**
1195 * Report that an application has started executing a long-running operation. Note that you
1196 * must pass in both the uid and name of the application to be checked; this function will
1197 * verify that these two match, and if not, return {@link #MODE_IGNORED}. If this call
1198 * succeeds, the last execution time of the operation for this app will be updated to
1199 * the current time and the operation will be marked as "running". In this case you must
1200 * later call {@link #finishOp(String, int, String)} to report when the application is no
1201 * longer performing the operation.
1202 * @param op The operation to start. One of the OPSTR_* constants.
1203 * @param uid The user id of the application attempting to perform the operation.
1204 * @param packageName The name of the application attempting to perform the operation.
1205 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1206 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1207 * causing the app to crash).
1208 * @throws SecurityException If the app has been configured to crash on this op.
1209 */
1210 public int startOp(String op, int uid, String packageName) {
1211 return startOp(strOpToOp(op), uid, packageName);
1212 }
1213
1214 /**
1215 * Like {@link #startOp} but instead of throwing a {@link SecurityException} it
1216 * returns {@link #MODE_ERRORED}.
1217 */
1218 public int startOpNoThrow(String op, int uid, String packageName) {
1219 return startOpNoThrow(strOpToOp(op), uid, packageName);
1220 }
1221
1222 /**
1223 * Report that an application is no longer performing an operation that had previously
1224 * been started with {@link #startOp(String, int, String)}. There is no validation of input
1225 * or result; the parameters supplied here must be the exact same ones previously passed
1226 * in when starting the operation.
1227 */
1228 public void finishOp(String op, int uid, String packageName) {
1229 finishOp(strOpToOp(op), uid, packageName);
1230 }
1231
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001232 /**
1233 * Do a quick check for whether an application might be able to perform an operation.
1234 * This is <em>not</em> a security check; you must use {@link #noteOp(int, int, String)}
1235 * or {@link #startOp(int, int, String)} for your actual security checks, which also
1236 * ensure that the given uid and package name are consistent. This function can just be
1237 * used for a quick check to see if an operation has been disabled for the application,
1238 * as an early reject of some work. This does not modify the time stamp or other data
1239 * about the operation.
1240 * @param op The operation to check. One of the OP_* constants.
1241 * @param uid The user id of the application attempting to perform the operation.
1242 * @param packageName The name of the application attempting to perform the operation.
1243 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1244 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1245 * causing the app to crash).
1246 * @throws SecurityException If the app has been configured to crash on this op.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001247 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001248 */
Dianne Hackborn35654b62013-01-14 17:38:02 -08001249 public int checkOp(int op, int uid, String packageName) {
1250 try {
1251 int mode = mService.checkOperation(op, uid, packageName);
1252 if (mode == MODE_ERRORED) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07001253 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborn35654b62013-01-14 17:38:02 -08001254 }
1255 return mode;
1256 } catch (RemoteException e) {
1257 }
1258 return MODE_IGNORED;
1259 }
1260
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001261 /**
1262 * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
1263 * returns {@link #MODE_ERRORED}.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001264 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001265 */
Dianne Hackborn35654b62013-01-14 17:38:02 -08001266 public int checkOpNoThrow(int op, int uid, String packageName) {
1267 try {
1268 return mService.checkOperation(op, uid, packageName);
1269 } catch (RemoteException e) {
1270 }
1271 return MODE_IGNORED;
1272 }
1273
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001274 /**
Jeff Sharkey911d7f42013-09-05 18:11:45 -07001275 * Do a quick check to validate if a package name belongs to a UID.
1276 *
1277 * @throws SecurityException if the package name doesn't belong to the given
1278 * UID, or if ownership cannot be verified.
1279 */
1280 public void checkPackage(int uid, String packageName) {
1281 try {
1282 if (mService.checkPackage(uid, packageName) != MODE_ALLOWED) {
1283 throw new SecurityException(
1284 "Package " + packageName + " does not belong to " + uid);
1285 }
1286 } catch (RemoteException e) {
1287 throw new SecurityException("Unable to verify package ownership", e);
1288 }
1289 }
1290
1291 /**
John Spurlock1af30c72014-03-10 08:33:35 -04001292 * Like {@link #checkOp} but at a stream-level for audio operations.
1293 * @hide
1294 */
1295 public int checkAudioOp(int op, int stream, int uid, String packageName) {
1296 try {
1297 final int mode = mService.checkAudioOperation(op, stream, uid, packageName);
1298 if (mode == MODE_ERRORED) {
1299 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
1300 }
1301 return mode;
1302 } catch (RemoteException e) {
1303 }
1304 return MODE_IGNORED;
1305 }
1306
1307 /**
1308 * Like {@link #checkAudioOp} but instead of throwing a {@link SecurityException} it
1309 * returns {@link #MODE_ERRORED}.
1310 * @hide
1311 */
1312 public int checkAudioOpNoThrow(int op, int stream, int uid, String packageName) {
1313 try {
1314 return mService.checkAudioOperation(op, stream, uid, packageName);
1315 } catch (RemoteException e) {
1316 }
1317 return MODE_IGNORED;
1318 }
1319
1320 /**
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001321 * Make note of an application performing an operation. Note that you must pass
1322 * in both the uid and name of the application to be checked; this function will verify
1323 * that these two match, and if not, return {@link #MODE_IGNORED}. If this call
1324 * succeeds, the last execution time of the operation for this app will be updated to
1325 * the current time.
1326 * @param op The operation to note. One of the OP_* constants.
1327 * @param uid The user id of the application attempting to perform the operation.
1328 * @param packageName The name of the application attempting to perform the operation.
1329 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1330 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1331 * causing the app to crash).
1332 * @throws SecurityException If the app has been configured to crash on this op.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001333 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001334 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001335 public int noteOp(int op, int uid, String packageName) {
1336 try {
1337 int mode = mService.noteOperation(op, uid, packageName);
1338 if (mode == MODE_ERRORED) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07001339 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001340 }
1341 return mode;
1342 } catch (RemoteException e) {
1343 }
1344 return MODE_IGNORED;
1345 }
1346
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001347 /**
1348 * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
1349 * returns {@link #MODE_ERRORED}.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001350 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001351 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001352 public int noteOpNoThrow(int op, int uid, String packageName) {
1353 try {
1354 return mService.noteOperation(op, uid, packageName);
1355 } catch (RemoteException e) {
1356 }
1357 return MODE_IGNORED;
1358 }
1359
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001360 /** @hide */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001361 public int noteOp(int op) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07001362 return noteOp(op, Process.myUid(), mContext.getOpPackageName());
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001363 }
1364
Dianne Hackborne98f5db2013-07-17 17:23:25 -07001365 /** @hide */
1366 public static IBinder getToken(IAppOpsService service) {
1367 synchronized (AppOpsManager.class) {
1368 if (sToken != null) {
1369 return sToken;
1370 }
1371 try {
1372 sToken = service.getToken(new Binder());
1373 } catch (RemoteException e) {
1374 // System is dead, whatevs.
1375 }
1376 return sToken;
1377 }
1378 }
1379
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001380 /**
1381 * Report that an application has started executing a long-running operation. Note that you
1382 * must pass in both the uid and name of the application to be checked; this function will
1383 * verify that these two match, and if not, return {@link #MODE_IGNORED}. If this call
1384 * succeeds, the last execution time of the operation for this app will be updated to
1385 * the current time and the operation will be marked as "running". In this case you must
1386 * later call {@link #finishOp(int, int, String)} to report when the application is no
1387 * longer performing the operation.
1388 * @param op The operation to start. One of the OP_* constants.
1389 * @param uid The user id of the application attempting to perform the operation.
1390 * @param packageName The name of the application attempting to perform the operation.
1391 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
1392 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
1393 * causing the app to crash).
1394 * @throws SecurityException If the app has been configured to crash on this op.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001395 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001396 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001397 public int startOp(int op, int uid, String packageName) {
1398 try {
Dianne Hackborne98f5db2013-07-17 17:23:25 -07001399 int mode = mService.startOperation(getToken(mService), op, uid, packageName);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001400 if (mode == MODE_ERRORED) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07001401 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001402 }
1403 return mode;
1404 } catch (RemoteException e) {
1405 }
1406 return MODE_IGNORED;
1407 }
1408
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001409 /**
1410 * Like {@link #startOp} but instead of throwing a {@link SecurityException} it
1411 * returns {@link #MODE_ERRORED}.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001412 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001413 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001414 public int startOpNoThrow(int op, int uid, String packageName) {
1415 try {
Dianne Hackborne98f5db2013-07-17 17:23:25 -07001416 return mService.startOperation(getToken(mService), op, uid, packageName);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001417 } catch (RemoteException e) {
1418 }
1419 return MODE_IGNORED;
1420 }
1421
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001422 /** @hide */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001423 public int startOp(int op) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07001424 return startOp(op, Process.myUid(), mContext.getOpPackageName());
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001425 }
1426
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001427 /**
1428 * Report that an application is no longer performing an operation that had previously
1429 * been started with {@link #startOp(int, int, String)}. There is no validation of input
1430 * or result; the parameters supplied here must be the exact same ones previously passed
1431 * in when starting the operation.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001432 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001433 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001434 public void finishOp(int op, int uid, String packageName) {
1435 try {
Dianne Hackborne98f5db2013-07-17 17:23:25 -07001436 mService.finishOperation(getToken(mService), op, uid, packageName);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001437 } catch (RemoteException e) {
1438 }
1439 }
1440
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001441 /** @hide */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001442 public void finishOp(int op) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07001443 finishOp(op, Process.myUid(), mContext.getOpPackageName());
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001444 }
1445}