AppOpsManager.java revision 15f83c6f64e26a74acf9b75ce41d39870d5a5b7a
1/* 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 19import android.Manifest; 20import android.media.AudioAttributes.AttributeUsage; 21import android.os.Binder; 22import android.os.IBinder; 23import android.os.UserManager; 24import android.util.ArrayMap; 25 26import com.android.internal.app.IAppOpsService; 27import com.android.internal.app.IAppOpsCallback; 28 29import java.util.ArrayList; 30import java.util.HashMap; 31import java.util.List; 32 33import android.content.Context; 34import android.os.Parcel; 35import android.os.Parcelable; 36import android.os.Process; 37import android.os.RemoteException; 38 39/** 40 * API for interacting with "application operation" tracking. 41 * 42 * <p>This API is not generally intended for third party application developers; most 43 * features are only available to system applications. Obtain an instance of it through 44 * {@link Context#getSystemService(String) Context.getSystemService} with 45 * {@link Context#APP_OPS_SERVICE Context.APP_OPS_SERVICE}.</p> 46 */ 47public class AppOpsManager { 48 /** 49 * <p>App ops allows callers to:</p> 50 * 51 * <ul> 52 * <li> Note when operations are happening, and find out if they are allowed for the current 53 * caller.</li> 54 * <li> Disallow specific apps from doing specific operations.</li> 55 * <li> Collect all of the current information about operations that have been executed or 56 * are not being allowed.</li> 57 * <li> Monitor for changes in whether an operation is allowed.</li> 58 * </ul> 59 * 60 * <p>Each operation is identified by a single integer; these integers are a fixed set of 61 * operations, enumerated by the OP_* constants. 62 * 63 * <p></p>When checking operations, the result is a "mode" integer indicating the current 64 * setting for the operation under that caller: MODE_ALLOWED, MODE_IGNORED (don't execute 65 * the operation but fake its behavior enough so that the caller doesn't crash), 66 * MODE_ERRORED (throw a SecurityException back to the caller; the normal operation calls 67 * will do this for you). 68 */ 69 70 final Context mContext; 71 final IAppOpsService mService; 72 final ArrayMap<OnOpChangedListener, IAppOpsCallback> mModeWatchers 73 = new ArrayMap<OnOpChangedListener, IAppOpsCallback>(); 74 75 static IBinder sToken; 76 77 /** 78 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is 79 * allowed to perform the given operation. 80 */ 81 public static final int MODE_ALLOWED = 0; 82 83 /** 84 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is 85 * not allowed to perform the given operation, and this attempt should 86 * <em>silently fail</em> (it should not cause the app to crash). 87 */ 88 public static final int MODE_IGNORED = 1; 89 90 /** 91 * Result from {@link #checkOpNoThrow}, {@link #noteOpNoThrow}, {@link #startOpNoThrow}: the 92 * given caller is not allowed to perform the given operation, and this attempt should 93 * cause it to have a fatal error, typically a {@link SecurityException}. 94 */ 95 public static final int MODE_ERRORED = 2; 96 97 /** 98 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller should 99 * use its default security check. This mode is not normally used; it should only be used 100 * with appop permissions, and callers must explicitly check for it and deal with it. 101 */ 102 public static final int MODE_DEFAULT = 3; 103 104 // when adding one of these: 105 // - increment _NUM_OP 106 // - add rows to sOpToSwitch, sOpToString, sOpNames, sOpPerms, sOpDefaultMode 107 // - add descriptive strings to Settings/res/values/arrays.xml 108 // - add the op to the appropriate template in AppOpsState.OpsTemplate (settings app) 109 110 /** @hide No operation specified. */ 111 public static final int OP_NONE = -1; 112 /** @hide Access to coarse location information. */ 113 public static final int OP_COARSE_LOCATION = 0; 114 /** @hide Access to fine location information. */ 115 public static final int OP_FINE_LOCATION = 1; 116 /** @hide Causing GPS to run. */ 117 public static final int OP_GPS = 2; 118 /** @hide */ 119 public static final int OP_VIBRATE = 3; 120 /** @hide */ 121 public static final int OP_READ_CONTACTS = 4; 122 /** @hide */ 123 public static final int OP_WRITE_CONTACTS = 5; 124 /** @hide */ 125 public static final int OP_READ_CALL_LOG = 6; 126 /** @hide */ 127 public static final int OP_WRITE_CALL_LOG = 7; 128 /** @hide */ 129 public static final int OP_READ_CALENDAR = 8; 130 /** @hide */ 131 public static final int OP_WRITE_CALENDAR = 9; 132 /** @hide */ 133 public static final int OP_WIFI_SCAN = 10; 134 /** @hide */ 135 public static final int OP_POST_NOTIFICATION = 11; 136 /** @hide */ 137 public static final int OP_NEIGHBORING_CELLS = 12; 138 /** @hide */ 139 public static final int OP_CALL_PHONE = 13; 140 /** @hide */ 141 public static final int OP_READ_SMS = 14; 142 /** @hide */ 143 public static final int OP_WRITE_SMS = 15; 144 /** @hide */ 145 public static final int OP_RECEIVE_SMS = 16; 146 /** @hide */ 147 public static final int OP_RECEIVE_EMERGECY_SMS = 17; 148 /** @hide */ 149 public static final int OP_RECEIVE_MMS = 18; 150 /** @hide */ 151 public static final int OP_RECEIVE_WAP_PUSH = 19; 152 /** @hide */ 153 public static final int OP_SEND_SMS = 20; 154 /** @hide */ 155 public static final int OP_READ_ICC_SMS = 21; 156 /** @hide */ 157 public static final int OP_WRITE_ICC_SMS = 22; 158 /** @hide */ 159 public static final int OP_WRITE_SETTINGS = 23; 160 /** @hide */ 161 public static final int OP_SYSTEM_ALERT_WINDOW = 24; 162 /** @hide */ 163 public static final int OP_ACCESS_NOTIFICATIONS = 25; 164 /** @hide */ 165 public static final int OP_CAMERA = 26; 166 /** @hide */ 167 public static final int OP_RECORD_AUDIO = 27; 168 /** @hide */ 169 public static final int OP_PLAY_AUDIO = 28; 170 /** @hide */ 171 public static final int OP_READ_CLIPBOARD = 29; 172 /** @hide */ 173 public static final int OP_WRITE_CLIPBOARD = 30; 174 /** @hide */ 175 public static final int OP_TAKE_MEDIA_BUTTONS = 31; 176 /** @hide */ 177 public static final int OP_TAKE_AUDIO_FOCUS = 32; 178 /** @hide */ 179 public static final int OP_AUDIO_MASTER_VOLUME = 33; 180 /** @hide */ 181 public static final int OP_AUDIO_VOICE_VOLUME = 34; 182 /** @hide */ 183 public static final int OP_AUDIO_RING_VOLUME = 35; 184 /** @hide */ 185 public static final int OP_AUDIO_MEDIA_VOLUME = 36; 186 /** @hide */ 187 public static final int OP_AUDIO_ALARM_VOLUME = 37; 188 /** @hide */ 189 public static final int OP_AUDIO_NOTIFICATION_VOLUME = 38; 190 /** @hide */ 191 public static final int OP_AUDIO_BLUETOOTH_VOLUME = 39; 192 /** @hide */ 193 public static final int OP_WAKE_LOCK = 40; 194 /** @hide Continually monitoring location data. */ 195 public static final int OP_MONITOR_LOCATION = 41; 196 /** @hide Continually monitoring location data with a relatively high power request. */ 197 public static final int OP_MONITOR_HIGH_POWER_LOCATION = 42; 198 /** @hide Retrieve current usage stats via {@link UsageStatsManager}. */ 199 public static final int OP_GET_USAGE_STATS = 43; 200 /** @hide */ 201 public static final int OP_MUTE_MICROPHONE = 44; 202 /** @hide */ 203 public static final int OP_TOAST_WINDOW = 45; 204 /** @hide Capture the device's display contents and/or audio */ 205 public static final int OP_PROJECT_MEDIA = 46; 206 /** @hide */ 207 public static final int _NUM_OP = 47; 208 209 /** Access to coarse location information. */ 210 public static final String OPSTR_COARSE_LOCATION = 211 "android:coarse_location"; 212 /** Access to fine location information. */ 213 public static final String OPSTR_FINE_LOCATION = 214 "android:fine_location"; 215 /** Continually monitoring location data. */ 216 public static final String OPSTR_MONITOR_LOCATION 217 = "android:monitor_location"; 218 /** Continually monitoring location data with a relatively high power request. */ 219 public static final String OPSTR_MONITOR_HIGH_POWER_LOCATION 220 = "android:monitor_location_high_power"; 221 222 /** 223 * This maps each operation to the operation that serves as the 224 * switch to determine whether it is allowed. Generally this is 225 * a 1:1 mapping, but for some things (like location) that have 226 * multiple low-level operations being tracked that should be 227 * presented to the user as one switch then this can be used to 228 * make them all controlled by the same single operation. 229 */ 230 private static int[] sOpToSwitch = new int[] { 231 OP_COARSE_LOCATION, 232 OP_COARSE_LOCATION, 233 OP_COARSE_LOCATION, 234 OP_VIBRATE, 235 OP_READ_CONTACTS, 236 OP_WRITE_CONTACTS, 237 OP_READ_CALL_LOG, 238 OP_WRITE_CALL_LOG, 239 OP_READ_CALENDAR, 240 OP_WRITE_CALENDAR, 241 OP_COARSE_LOCATION, 242 OP_POST_NOTIFICATION, 243 OP_COARSE_LOCATION, 244 OP_CALL_PHONE, 245 OP_READ_SMS, 246 OP_WRITE_SMS, 247 OP_RECEIVE_SMS, 248 OP_RECEIVE_SMS, 249 OP_RECEIVE_SMS, 250 OP_RECEIVE_SMS, 251 OP_SEND_SMS, 252 OP_READ_SMS, 253 OP_WRITE_SMS, 254 OP_WRITE_SETTINGS, 255 OP_SYSTEM_ALERT_WINDOW, 256 OP_ACCESS_NOTIFICATIONS, 257 OP_CAMERA, 258 OP_RECORD_AUDIO, 259 OP_PLAY_AUDIO, 260 OP_READ_CLIPBOARD, 261 OP_WRITE_CLIPBOARD, 262 OP_TAKE_MEDIA_BUTTONS, 263 OP_TAKE_AUDIO_FOCUS, 264 OP_AUDIO_MASTER_VOLUME, 265 OP_AUDIO_VOICE_VOLUME, 266 OP_AUDIO_RING_VOLUME, 267 OP_AUDIO_MEDIA_VOLUME, 268 OP_AUDIO_ALARM_VOLUME, 269 OP_AUDIO_NOTIFICATION_VOLUME, 270 OP_AUDIO_BLUETOOTH_VOLUME, 271 OP_WAKE_LOCK, 272 OP_COARSE_LOCATION, 273 OP_COARSE_LOCATION, 274 OP_GET_USAGE_STATS, 275 OP_MUTE_MICROPHONE, 276 OP_TOAST_WINDOW, 277 OP_PROJECT_MEDIA, 278 }; 279 280 /** 281 * This maps each operation to the public string constant for it. 282 * If it doesn't have a public string constant, it maps to null. 283 */ 284 private static String[] sOpToString = new String[] { 285 OPSTR_COARSE_LOCATION, 286 OPSTR_FINE_LOCATION, 287 null, 288 null, 289 null, 290 null, 291 null, 292 null, 293 null, 294 null, 295 null, 296 null, 297 null, 298 null, 299 null, 300 null, 301 null, 302 null, 303 null, 304 null, 305 null, 306 null, 307 null, 308 null, 309 null, 310 null, 311 null, 312 null, 313 null, 314 null, 315 null, 316 null, 317 null, 318 null, 319 null, 320 null, 321 null, 322 null, 323 null, 324 null, 325 null, 326 OPSTR_MONITOR_LOCATION, 327 OPSTR_MONITOR_HIGH_POWER_LOCATION, 328 null, 329 null, 330 null, 331 null, 332 }; 333 334 /** 335 * This provides a simple name for each operation to be used 336 * in debug output. 337 */ 338 private static String[] sOpNames = new String[] { 339 "COARSE_LOCATION", 340 "FINE_LOCATION", 341 "GPS", 342 "VIBRATE", 343 "READ_CONTACTS", 344 "WRITE_CONTACTS", 345 "READ_CALL_LOG", 346 "WRITE_CALL_LOG", 347 "READ_CALENDAR", 348 "WRITE_CALENDAR", 349 "WIFI_SCAN", 350 "POST_NOTIFICATION", 351 "NEIGHBORING_CELLS", 352 "CALL_PHONE", 353 "READ_SMS", 354 "WRITE_SMS", 355 "RECEIVE_SMS", 356 "RECEIVE_EMERGECY_SMS", 357 "RECEIVE_MMS", 358 "RECEIVE_WAP_PUSH", 359 "SEND_SMS", 360 "READ_ICC_SMS", 361 "WRITE_ICC_SMS", 362 "WRITE_SETTINGS", 363 "SYSTEM_ALERT_WINDOW", 364 "ACCESS_NOTIFICATIONS", 365 "CAMERA", 366 "RECORD_AUDIO", 367 "PLAY_AUDIO", 368 "READ_CLIPBOARD", 369 "WRITE_CLIPBOARD", 370 "TAKE_MEDIA_BUTTONS", 371 "TAKE_AUDIO_FOCUS", 372 "AUDIO_MASTER_VOLUME", 373 "AUDIO_VOICE_VOLUME", 374 "AUDIO_RING_VOLUME", 375 "AUDIO_MEDIA_VOLUME", 376 "AUDIO_ALARM_VOLUME", 377 "AUDIO_NOTIFICATION_VOLUME", 378 "AUDIO_BLUETOOTH_VOLUME", 379 "WAKE_LOCK", 380 "MONITOR_LOCATION", 381 "MONITOR_HIGH_POWER_LOCATION", 382 "GET_USAGE_STATS", 383 "MUTE_MICROPHONE", 384 "TOAST_WINDOW", 385 "PROJECT_MEDIA", 386 }; 387 388 /** 389 * This optionally maps a permission to an operation. If there 390 * is no permission associated with an operation, it is null. 391 */ 392 private static String[] sOpPerms = new String[] { 393 android.Manifest.permission.ACCESS_COARSE_LOCATION, 394 android.Manifest.permission.ACCESS_FINE_LOCATION, 395 null, 396 android.Manifest.permission.VIBRATE, 397 android.Manifest.permission.READ_CONTACTS, 398 android.Manifest.permission.WRITE_CONTACTS, 399 android.Manifest.permission.READ_CALL_LOG, 400 android.Manifest.permission.WRITE_CALL_LOG, 401 android.Manifest.permission.READ_CALENDAR, 402 android.Manifest.permission.WRITE_CALENDAR, 403 android.Manifest.permission.ACCESS_WIFI_STATE, 404 null, // no permission required for notifications 405 null, // neighboring cells shares the coarse location perm 406 android.Manifest.permission.CALL_PHONE, 407 android.Manifest.permission.READ_SMS, 408 android.Manifest.permission.WRITE_SMS, 409 android.Manifest.permission.RECEIVE_SMS, 410 android.Manifest.permission.RECEIVE_EMERGENCY_BROADCAST, 411 android.Manifest.permission.RECEIVE_MMS, 412 android.Manifest.permission.RECEIVE_WAP_PUSH, 413 android.Manifest.permission.SEND_SMS, 414 android.Manifest.permission.READ_SMS, 415 android.Manifest.permission.WRITE_SMS, 416 android.Manifest.permission.WRITE_SETTINGS, 417 android.Manifest.permission.SYSTEM_ALERT_WINDOW, 418 android.Manifest.permission.ACCESS_NOTIFICATIONS, 419 android.Manifest.permission.CAMERA, 420 android.Manifest.permission.RECORD_AUDIO, 421 null, // no permission for playing audio 422 null, // no permission for reading clipboard 423 null, // no permission for writing clipboard 424 null, // no permission for taking media buttons 425 null, // no permission for taking audio focus 426 null, // no permission for changing master volume 427 null, // no permission for changing voice volume 428 null, // no permission for changing ring volume 429 null, // no permission for changing media volume 430 null, // no permission for changing alarm volume 431 null, // no permission for changing notification volume 432 null, // no permission for changing bluetooth volume 433 android.Manifest.permission.WAKE_LOCK, 434 null, // no permission for generic location monitoring 435 null, // no permission for high power location monitoring 436 android.Manifest.permission.PACKAGE_USAGE_STATS, 437 null, // no permission for muting/unmuting microphone 438 null, // no permission for displaying toasts 439 null, // no permission for projecting media 440 }; 441 442 /** 443 * Specifies whether an Op should be restricted by a user restriction. 444 * Each Op should be filled with a restriction string from UserManager or 445 * null to specify it is not affected by any user restriction. 446 */ 447 private static String[] sOpRestrictions = new String[] { 448 UserManager.DISALLOW_SHARE_LOCATION, //COARSE_LOCATION 449 UserManager.DISALLOW_SHARE_LOCATION, //FINE_LOCATION 450 UserManager.DISALLOW_SHARE_LOCATION, //GPS 451 null, //VIBRATE 452 null, //READ_CONTACTS 453 null, //WRITE_CONTACTS 454 UserManager.DISALLOW_OUTGOING_CALLS, //READ_CALL_LOG 455 UserManager.DISALLOW_OUTGOING_CALLS, //WRITE_CALL_LOG 456 null, //READ_CALENDAR 457 null, //WRITE_CALENDAR 458 UserManager.DISALLOW_SHARE_LOCATION, //WIFI_SCAN 459 null, //POST_NOTIFICATION 460 null, //NEIGHBORING_CELLS 461 null, //CALL_PHONE 462 UserManager.DISALLOW_SMS, //READ_SMS 463 UserManager.DISALLOW_SMS, //WRITE_SMS 464 UserManager.DISALLOW_SMS, //RECEIVE_SMS 465 null, //RECEIVE_EMERGENCY_SMS 466 UserManager.DISALLOW_SMS, //RECEIVE_MMS 467 null, //RECEIVE_WAP_PUSH 468 UserManager.DISALLOW_SMS, //SEND_SMS 469 UserManager.DISALLOW_SMS, //READ_ICC_SMS 470 UserManager.DISALLOW_SMS, //WRITE_ICC_SMS 471 null, //WRITE_SETTINGS 472 UserManager.DISALLOW_CREATE_WINDOWS, //SYSTEM_ALERT_WINDOW 473 null, //ACCESS_NOTIFICATIONS 474 null, //CAMERA 475 null, //RECORD_AUDIO 476 null, //PLAY_AUDIO 477 null, //READ_CLIPBOARD 478 null, //WRITE_CLIPBOARD 479 null, //TAKE_MEDIA_BUTTONS 480 null, //TAKE_AUDIO_FOCUS 481 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MASTER_VOLUME 482 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_VOICE_VOLUME 483 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_RING_VOLUME 484 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MEDIA_VOLUME 485 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ALARM_VOLUME 486 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_NOTIFICATION_VOLUME 487 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_BLUETOOTH_VOLUME 488 null, //WAKE_LOCK 489 UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_LOCATION 490 UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_HIGH_POWER_LOCATION 491 null, //GET_USAGE_STATS 492 UserManager.DISALLOW_UNMUTE_MICROPHONE, // MUTE_MICROPHONE 493 UserManager.DISALLOW_CREATE_WINDOWS, // TOAST_WINDOW 494 null, //PROJECT_MEDIA 495 }; 496 497 /** 498 * This specifies whether each option should allow the system 499 * (and system ui) to bypass the user restriction when active. 500 */ 501 private static boolean[] sOpAllowSystemRestrictionBypass = new boolean[] { 502 false, //COARSE_LOCATION 503 false, //FINE_LOCATION 504 false, //GPS 505 false, //VIBRATE 506 false, //READ_CONTACTS 507 false, //WRITE_CONTACTS 508 false, //READ_CALL_LOG 509 false, //WRITE_CALL_LOG 510 false, //READ_CALENDAR 511 false, //WRITE_CALENDAR 512 true, //WIFI_SCAN 513 false, //POST_NOTIFICATION 514 false, //NEIGHBORING_CELLS 515 false, //CALL_PHONE 516 false, //READ_SMS 517 false, //WRITE_SMS 518 false, //RECEIVE_SMS 519 false, //RECEIVE_EMERGECY_SMS 520 false, //RECEIVE_MMS 521 false, //RECEIVE_WAP_PUSH 522 false, //SEND_SMS 523 false, //READ_ICC_SMS 524 false, //WRITE_ICC_SMS 525 false, //WRITE_SETTINGS 526 true, //SYSTEM_ALERT_WINDOW 527 false, //ACCESS_NOTIFICATIONS 528 false, //CAMERA 529 false, //RECORD_AUDIO 530 false, //PLAY_AUDIO 531 false, //READ_CLIPBOARD 532 false, //WRITE_CLIPBOARD 533 false, //TAKE_MEDIA_BUTTONS 534 false, //TAKE_AUDIO_FOCUS 535 false, //AUDIO_MASTER_VOLUME 536 false, //AUDIO_VOICE_VOLUME 537 false, //AUDIO_RING_VOLUME 538 false, //AUDIO_MEDIA_VOLUME 539 false, //AUDIO_ALARM_VOLUME 540 false, //AUDIO_NOTIFICATION_VOLUME 541 false, //AUDIO_BLUETOOTH_VOLUME 542 false, //WAKE_LOCK 543 false, //MONITOR_LOCATION 544 false, //MONITOR_HIGH_POWER_LOCATION 545 false, //GET_USAGE_STATS 546 false, //MUTE_MICROPHONE 547 true, //TOAST_WINDOW 548 false, //PROJECT_MEDIA 549 }; 550 551 /** 552 * This specifies the default mode for each operation. 553 */ 554 private static int[] sOpDefaultMode = new int[] { 555 AppOpsManager.MODE_ALLOWED, 556 AppOpsManager.MODE_ALLOWED, 557 AppOpsManager.MODE_ALLOWED, 558 AppOpsManager.MODE_ALLOWED, 559 AppOpsManager.MODE_ALLOWED, 560 AppOpsManager.MODE_ALLOWED, 561 AppOpsManager.MODE_ALLOWED, 562 AppOpsManager.MODE_ALLOWED, 563 AppOpsManager.MODE_ALLOWED, 564 AppOpsManager.MODE_ALLOWED, 565 AppOpsManager.MODE_ALLOWED, 566 AppOpsManager.MODE_ALLOWED, 567 AppOpsManager.MODE_ALLOWED, 568 AppOpsManager.MODE_ALLOWED, 569 AppOpsManager.MODE_ALLOWED, 570 AppOpsManager.MODE_IGNORED, // OP_WRITE_SMS 571 AppOpsManager.MODE_ALLOWED, 572 AppOpsManager.MODE_ALLOWED, 573 AppOpsManager.MODE_ALLOWED, 574 AppOpsManager.MODE_ALLOWED, 575 AppOpsManager.MODE_ALLOWED, 576 AppOpsManager.MODE_ALLOWED, 577 AppOpsManager.MODE_ALLOWED, 578 AppOpsManager.MODE_ALLOWED, 579 AppOpsManager.MODE_ALLOWED, 580 AppOpsManager.MODE_ALLOWED, 581 AppOpsManager.MODE_ALLOWED, 582 AppOpsManager.MODE_ALLOWED, 583 AppOpsManager.MODE_ALLOWED, 584 AppOpsManager.MODE_ALLOWED, 585 AppOpsManager.MODE_ALLOWED, 586 AppOpsManager.MODE_ALLOWED, 587 AppOpsManager.MODE_ALLOWED, 588 AppOpsManager.MODE_ALLOWED, 589 AppOpsManager.MODE_ALLOWED, 590 AppOpsManager.MODE_ALLOWED, 591 AppOpsManager.MODE_ALLOWED, 592 AppOpsManager.MODE_ALLOWED, 593 AppOpsManager.MODE_ALLOWED, 594 AppOpsManager.MODE_ALLOWED, 595 AppOpsManager.MODE_ALLOWED, 596 AppOpsManager.MODE_ALLOWED, 597 AppOpsManager.MODE_ALLOWED, 598 AppOpsManager.MODE_DEFAULT, // OP_GET_USAGE_STATS 599 AppOpsManager.MODE_ALLOWED, 600 AppOpsManager.MODE_ALLOWED, 601 AppOpsManager.MODE_IGNORED, // OP_PROJECT_MEDIA 602 }; 603 604 /** 605 * This specifies whether each option is allowed to be reset 606 * when resetting all app preferences. Disable reset for 607 * app ops that are under strong control of some part of the 608 * system (such as OP_WRITE_SMS, which should be allowed only 609 * for whichever app is selected as the current SMS app). 610 */ 611 private static boolean[] sOpDisableReset = new boolean[] { 612 false, 613 false, 614 false, 615 false, 616 false, 617 false, 618 false, 619 false, 620 false, 621 false, 622 false, 623 false, 624 false, 625 false, 626 false, 627 true, // OP_WRITE_SMS 628 false, 629 false, 630 false, 631 false, 632 false, 633 false, 634 false, 635 false, 636 false, 637 false, 638 false, 639 false, 640 false, 641 false, 642 false, 643 false, 644 false, 645 false, 646 false, 647 false, 648 false, 649 false, 650 false, 651 false, 652 false, 653 false, 654 false, 655 false, 656 false, 657 false, 658 false, 659 }; 660 661 private static HashMap<String, Integer> sOpStrToOp = new HashMap<String, Integer>(); 662 663 static { 664 if (sOpToSwitch.length != _NUM_OP) { 665 throw new IllegalStateException("sOpToSwitch length " + sOpToSwitch.length 666 + " should be " + _NUM_OP); 667 } 668 if (sOpToString.length != _NUM_OP) { 669 throw new IllegalStateException("sOpToString length " + sOpToString.length 670 + " should be " + _NUM_OP); 671 } 672 if (sOpNames.length != _NUM_OP) { 673 throw new IllegalStateException("sOpNames length " + sOpNames.length 674 + " should be " + _NUM_OP); 675 } 676 if (sOpPerms.length != _NUM_OP) { 677 throw new IllegalStateException("sOpPerms length " + sOpPerms.length 678 + " should be " + _NUM_OP); 679 } 680 if (sOpDefaultMode.length != _NUM_OP) { 681 throw new IllegalStateException("sOpDefaultMode length " + sOpDefaultMode.length 682 + " should be " + _NUM_OP); 683 } 684 if (sOpDisableReset.length != _NUM_OP) { 685 throw new IllegalStateException("sOpDisableReset length " + sOpDisableReset.length 686 + " should be " + _NUM_OP); 687 } 688 if (sOpRestrictions.length != _NUM_OP) { 689 throw new IllegalStateException("sOpRestrictions length " + sOpRestrictions.length 690 + " should be " + _NUM_OP); 691 } 692 if (sOpAllowSystemRestrictionBypass.length != _NUM_OP) { 693 throw new IllegalStateException("sOpAllowSYstemRestrictionsBypass length " 694 + sOpRestrictions.length + " should be " + _NUM_OP); 695 } 696 for (int i=0; i<_NUM_OP; i++) { 697 if (sOpToString[i] != null) { 698 sOpStrToOp.put(sOpToString[i], i); 699 } 700 } 701 } 702 703 /** 704 * Retrieve the op switch that controls the given operation. 705 * @hide 706 */ 707 public static int opToSwitch(int op) { 708 return sOpToSwitch[op]; 709 } 710 711 /** 712 * Retrieve a non-localized name for the operation, for debugging output. 713 * @hide 714 */ 715 public static String opToName(int op) { 716 if (op == OP_NONE) return "NONE"; 717 return op < sOpNames.length ? sOpNames[op] : ("Unknown(" + op + ")"); 718 } 719 720 /** 721 * Retrieve the permission associated with an operation, or null if there is not one. 722 * @hide 723 */ 724 public static String opToPermission(int op) { 725 return sOpPerms[op]; 726 } 727 728 /** 729 * Retrieve the user restriction associated with an operation, or null if there is not one. 730 * @hide 731 */ 732 public static String opToRestriction(int op) { 733 return sOpRestrictions[op]; 734 } 735 736 /** 737 * Retrieve whether the op allows the system (and system ui) to 738 * bypass the user restriction. 739 * @hide 740 */ 741 public static boolean opAllowSystemBypassRestriction(int op) { 742 return sOpAllowSystemRestrictionBypass[op]; 743 } 744 745 /** 746 * Retrieve the default mode for the operation. 747 * @hide 748 */ 749 public static int opToDefaultMode(int op) { 750 return sOpDefaultMode[op]; 751 } 752 753 /** 754 * Retrieve whether the op allows itself to be reset. 755 * @hide 756 */ 757 public static boolean opAllowsReset(int op) { 758 return !sOpDisableReset[op]; 759 } 760 761 /** 762 * Class holding all of the operation information associated with an app. 763 * @hide 764 */ 765 public static class PackageOps implements Parcelable { 766 private final String mPackageName; 767 private final int mUid; 768 private final List<OpEntry> mEntries; 769 770 public PackageOps(String packageName, int uid, List<OpEntry> entries) { 771 mPackageName = packageName; 772 mUid = uid; 773 mEntries = entries; 774 } 775 776 public String getPackageName() { 777 return mPackageName; 778 } 779 780 public int getUid() { 781 return mUid; 782 } 783 784 public List<OpEntry> getOps() { 785 return mEntries; 786 } 787 788 @Override 789 public int describeContents() { 790 return 0; 791 } 792 793 @Override 794 public void writeToParcel(Parcel dest, int flags) { 795 dest.writeString(mPackageName); 796 dest.writeInt(mUid); 797 dest.writeInt(mEntries.size()); 798 for (int i=0; i<mEntries.size(); i++) { 799 mEntries.get(i).writeToParcel(dest, flags); 800 } 801 } 802 803 PackageOps(Parcel source) { 804 mPackageName = source.readString(); 805 mUid = source.readInt(); 806 mEntries = new ArrayList<OpEntry>(); 807 final int N = source.readInt(); 808 for (int i=0; i<N; i++) { 809 mEntries.add(OpEntry.CREATOR.createFromParcel(source)); 810 } 811 } 812 813 public static final Creator<PackageOps> CREATOR = new Creator<PackageOps>() { 814 @Override public PackageOps createFromParcel(Parcel source) { 815 return new PackageOps(source); 816 } 817 818 @Override public PackageOps[] newArray(int size) { 819 return new PackageOps[size]; 820 } 821 }; 822 } 823 824 /** 825 * Class holding the information about one unique operation of an application. 826 * @hide 827 */ 828 public static class OpEntry implements Parcelable { 829 private final int mOp; 830 private final int mMode; 831 private final long mTime; 832 private final long mRejectTime; 833 private final int mDuration; 834 835 public OpEntry(int op, int mode, long time, long rejectTime, int duration) { 836 mOp = op; 837 mMode = mode; 838 mTime = time; 839 mRejectTime = rejectTime; 840 mDuration = duration; 841 } 842 843 public int getOp() { 844 return mOp; 845 } 846 847 public int getMode() { 848 return mMode; 849 } 850 851 public long getTime() { 852 return mTime; 853 } 854 855 public long getRejectTime() { 856 return mRejectTime; 857 } 858 859 public boolean isRunning() { 860 return mDuration == -1; 861 } 862 863 public int getDuration() { 864 return mDuration == -1 ? (int)(System.currentTimeMillis()-mTime) : mDuration; 865 } 866 867 @Override 868 public int describeContents() { 869 return 0; 870 } 871 872 @Override 873 public void writeToParcel(Parcel dest, int flags) { 874 dest.writeInt(mOp); 875 dest.writeInt(mMode); 876 dest.writeLong(mTime); 877 dest.writeLong(mRejectTime); 878 dest.writeInt(mDuration); 879 } 880 881 OpEntry(Parcel source) { 882 mOp = source.readInt(); 883 mMode = source.readInt(); 884 mTime = source.readLong(); 885 mRejectTime = source.readLong(); 886 mDuration = source.readInt(); 887 } 888 889 public static final Creator<OpEntry> CREATOR = new Creator<OpEntry>() { 890 @Override public OpEntry createFromParcel(Parcel source) { 891 return new OpEntry(source); 892 } 893 894 @Override public OpEntry[] newArray(int size) { 895 return new OpEntry[size]; 896 } 897 }; 898 } 899 900 /** 901 * Callback for notification of changes to operation state. 902 */ 903 public interface OnOpChangedListener { 904 public void onOpChanged(String op, String packageName); 905 } 906 907 /** 908 * Callback for notification of changes to operation state. 909 * This allows you to see the raw op codes instead of strings. 910 * @hide 911 */ 912 public static class OnOpChangedInternalListener implements OnOpChangedListener { 913 public void onOpChanged(String op, String packageName) { } 914 public void onOpChanged(int op, String packageName) { } 915 } 916 917 AppOpsManager(Context context, IAppOpsService service) { 918 mContext = context; 919 mService = service; 920 } 921 922 /** 923 * Retrieve current operation state for all applications. 924 * 925 * @param ops The set of operations you are interested in, or null if you want all of them. 926 * @hide 927 */ 928 public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) { 929 try { 930 return mService.getPackagesForOps(ops); 931 } catch (RemoteException e) { 932 } 933 return null; 934 } 935 936 /** 937 * Retrieve current operation state for one application. 938 * 939 * @param uid The uid of the application of interest. 940 * @param packageName The name of the application of interest. 941 * @param ops The set of operations you are interested in, or null if you want all of them. 942 * @hide 943 */ 944 public List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, int[] ops) { 945 try { 946 return mService.getOpsForPackage(uid, packageName, ops); 947 } catch (RemoteException e) { 948 } 949 return null; 950 } 951 952 /** @hide */ 953 public void setMode(int code, int uid, String packageName, int mode) { 954 try { 955 mService.setMode(code, uid, packageName, mode); 956 } catch (RemoteException e) { 957 } 958 } 959 960 /** 961 * Set a non-persisted restriction on an audio operation at a stream-level. 962 * Restrictions are temporary additional constraints imposed on top of the persisted rules 963 * defined by {@link #setMode}. 964 * 965 * @param code The operation to restrict. 966 * @param usage The {@link android.media.AudioAttributes} usage value. 967 * @param mode The restriction mode (MODE_IGNORED,MODE_ERRORED) or MODE_ALLOWED to unrestrict. 968 * @param exceptionPackages Optional list of packages to exclude from the restriction. 969 * @hide 970 */ 971 public void setRestriction(int code, @AttributeUsage int usage, int mode, 972 String[] exceptionPackages) { 973 try { 974 final int uid = Binder.getCallingUid(); 975 mService.setAudioRestriction(code, usage, uid, mode, exceptionPackages); 976 } catch (RemoteException e) { 977 } 978 } 979 980 /** @hide */ 981 public void resetAllModes() { 982 try { 983 mService.resetAllModes(); 984 } catch (RemoteException e) { 985 } 986 } 987 988 /** 989 * Monitor for changes to the operating mode for the given op in the given app package. 990 * @param op The operation to monitor, one of OPSTR_*. 991 * @param packageName The name of the application to monitor. 992 * @param callback Where to report changes. 993 */ 994 public void startWatchingMode(String op, String packageName, 995 final OnOpChangedListener callback) { 996 startWatchingMode(strOpToOp(op), packageName, callback); 997 } 998 999 /** 1000 * Monitor for changes to the operating mode for the given op in the given app package. 1001 * @param op The operation to monitor, one of OP_*. 1002 * @param packageName The name of the application to monitor. 1003 * @param callback Where to report changes. 1004 * @hide 1005 */ 1006 public void startWatchingMode(int op, String packageName, final OnOpChangedListener callback) { 1007 synchronized (mModeWatchers) { 1008 IAppOpsCallback cb = mModeWatchers.get(callback); 1009 if (cb == null) { 1010 cb = new IAppOpsCallback.Stub() { 1011 public void opChanged(int op, String packageName) { 1012 if (callback instanceof OnOpChangedInternalListener) { 1013 ((OnOpChangedInternalListener)callback).onOpChanged(op, packageName); 1014 } 1015 if (sOpToString[op] != null) { 1016 callback.onOpChanged(sOpToString[op], packageName); 1017 } 1018 } 1019 }; 1020 mModeWatchers.put(callback, cb); 1021 } 1022 try { 1023 mService.startWatchingMode(op, packageName, cb); 1024 } catch (RemoteException e) { 1025 } 1026 } 1027 } 1028 1029 /** 1030 * Stop monitoring that was previously started with {@link #startWatchingMode}. All 1031 * monitoring associated with this callback will be removed. 1032 */ 1033 public void stopWatchingMode(OnOpChangedListener callback) { 1034 synchronized (mModeWatchers) { 1035 IAppOpsCallback cb = mModeWatchers.get(callback); 1036 if (cb != null) { 1037 try { 1038 mService.stopWatchingMode(cb); 1039 } catch (RemoteException e) { 1040 } 1041 } 1042 } 1043 } 1044 1045 private String buildSecurityExceptionMsg(int op, int uid, String packageName) { 1046 return packageName + " from uid " + uid + " not allowed to perform " + sOpNames[op]; 1047 } 1048 1049 private int strOpToOp(String op) { 1050 Integer val = sOpStrToOp.get(op); 1051 if (val == null) { 1052 throw new IllegalArgumentException("Unknown operation string: " + op); 1053 } 1054 return val; 1055 } 1056 1057 /** 1058 * Do a quick check for whether an application might be able to perform an operation. 1059 * This is <em>not</em> a security check; you must use {@link #noteOp(String, int, String)} 1060 * or {@link #startOp(String, int, String)} for your actual security checks, which also 1061 * ensure that the given uid and package name are consistent. This function can just be 1062 * used for a quick check to see if an operation has been disabled for the application, 1063 * as an early reject of some work. This does not modify the time stamp or other data 1064 * about the operation. 1065 * @param op The operation to check. One of the OPSTR_* constants. 1066 * @param uid The user id of the application attempting to perform the operation. 1067 * @param packageName The name of the application attempting to perform the operation. 1068 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or 1069 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without 1070 * causing the app to crash). 1071 * @throws SecurityException If the app has been configured to crash on this op. 1072 */ 1073 public int checkOp(String op, int uid, String packageName) { 1074 return checkOp(strOpToOp(op), uid, packageName); 1075 } 1076 1077 /** 1078 * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it 1079 * returns {@link #MODE_ERRORED}. 1080 */ 1081 public int checkOpNoThrow(String op, int uid, String packageName) { 1082 return checkOpNoThrow(strOpToOp(op), uid, packageName); 1083 } 1084 1085 /** 1086 * Make note of an application performing an operation. Note that you must pass 1087 * in both the uid and name of the application to be checked; this function will verify 1088 * that these two match, and if not, return {@link #MODE_IGNORED}. If this call 1089 * succeeds, the last execution time of the operation for this app will be updated to 1090 * the current time. 1091 * @param op The operation to note. One of the OPSTR_* constants. 1092 * @param uid The user id of the application attempting to perform the operation. 1093 * @param packageName The name of the application attempting to perform the operation. 1094 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or 1095 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without 1096 * causing the app to crash). 1097 * @throws SecurityException If the app has been configured to crash on this op. 1098 */ 1099 public int noteOp(String op, int uid, String packageName) { 1100 return noteOp(strOpToOp(op), uid, packageName); 1101 } 1102 1103 /** 1104 * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it 1105 * returns {@link #MODE_ERRORED}. 1106 */ 1107 public int noteOpNoThrow(String op, int uid, String packageName) { 1108 return noteOpNoThrow(strOpToOp(op), uid, packageName); 1109 } 1110 1111 /** 1112 * Report that an application has started executing a long-running operation. Note that you 1113 * must pass in both the uid and name of the application to be checked; this function will 1114 * verify that these two match, and if not, return {@link #MODE_IGNORED}. If this call 1115 * succeeds, the last execution time of the operation for this app will be updated to 1116 * the current time and the operation will be marked as "running". In this case you must 1117 * later call {@link #finishOp(String, int, String)} to report when the application is no 1118 * longer performing the operation. 1119 * @param op The operation to start. One of the OPSTR_* constants. 1120 * @param uid The user id of the application attempting to perform the operation. 1121 * @param packageName The name of the application attempting to perform the operation. 1122 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or 1123 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without 1124 * causing the app to crash). 1125 * @throws SecurityException If the app has been configured to crash on this op. 1126 */ 1127 public int startOp(String op, int uid, String packageName) { 1128 return startOp(strOpToOp(op), uid, packageName); 1129 } 1130 1131 /** 1132 * Like {@link #startOp} but instead of throwing a {@link SecurityException} it 1133 * returns {@link #MODE_ERRORED}. 1134 */ 1135 public int startOpNoThrow(String op, int uid, String packageName) { 1136 return startOpNoThrow(strOpToOp(op), uid, packageName); 1137 } 1138 1139 /** 1140 * Report that an application is no longer performing an operation that had previously 1141 * been started with {@link #startOp(String, int, String)}. There is no validation of input 1142 * or result; the parameters supplied here must be the exact same ones previously passed 1143 * in when starting the operation. 1144 */ 1145 public void finishOp(String op, int uid, String packageName) { 1146 finishOp(strOpToOp(op), uid, packageName); 1147 } 1148 1149 /** 1150 * Do a quick check for whether an application might be able to perform an operation. 1151 * This is <em>not</em> a security check; you must use {@link #noteOp(int, int, String)} 1152 * or {@link #startOp(int, int, String)} for your actual security checks, which also 1153 * ensure that the given uid and package name are consistent. This function can just be 1154 * used for a quick check to see if an operation has been disabled for the application, 1155 * as an early reject of some work. This does not modify the time stamp or other data 1156 * about the operation. 1157 * @param op The operation to check. One of the OP_* constants. 1158 * @param uid The user id of the application attempting to perform the operation. 1159 * @param packageName The name of the application attempting to perform the operation. 1160 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or 1161 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without 1162 * causing the app to crash). 1163 * @throws SecurityException If the app has been configured to crash on this op. 1164 * @hide 1165 */ 1166 public int checkOp(int op, int uid, String packageName) { 1167 try { 1168 int mode = mService.checkOperation(op, uid, packageName); 1169 if (mode == MODE_ERRORED) { 1170 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName)); 1171 } 1172 return mode; 1173 } catch (RemoteException e) { 1174 } 1175 return MODE_IGNORED; 1176 } 1177 1178 /** 1179 * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it 1180 * returns {@link #MODE_ERRORED}. 1181 * @hide 1182 */ 1183 public int checkOpNoThrow(int op, int uid, String packageName) { 1184 try { 1185 return mService.checkOperation(op, uid, packageName); 1186 } catch (RemoteException e) { 1187 } 1188 return MODE_IGNORED; 1189 } 1190 1191 /** 1192 * Do a quick check to validate if a package name belongs to a UID. 1193 * 1194 * @throws SecurityException if the package name doesn't belong to the given 1195 * UID, or if ownership cannot be verified. 1196 */ 1197 public void checkPackage(int uid, String packageName) { 1198 try { 1199 if (mService.checkPackage(uid, packageName) != MODE_ALLOWED) { 1200 throw new SecurityException( 1201 "Package " + packageName + " does not belong to " + uid); 1202 } 1203 } catch (RemoteException e) { 1204 throw new SecurityException("Unable to verify package ownership", e); 1205 } 1206 } 1207 1208 /** 1209 * Like {@link #checkOp} but at a stream-level for audio operations. 1210 * @hide 1211 */ 1212 public int checkAudioOp(int op, int stream, int uid, String packageName) { 1213 try { 1214 final int mode = mService.checkAudioOperation(op, stream, uid, packageName); 1215 if (mode == MODE_ERRORED) { 1216 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName)); 1217 } 1218 return mode; 1219 } catch (RemoteException e) { 1220 } 1221 return MODE_IGNORED; 1222 } 1223 1224 /** 1225 * Like {@link #checkAudioOp} but instead of throwing a {@link SecurityException} it 1226 * returns {@link #MODE_ERRORED}. 1227 * @hide 1228 */ 1229 public int checkAudioOpNoThrow(int op, int stream, int uid, String packageName) { 1230 try { 1231 return mService.checkAudioOperation(op, stream, uid, packageName); 1232 } catch (RemoteException e) { 1233 } 1234 return MODE_IGNORED; 1235 } 1236 1237 /** 1238 * Make note of an application performing an operation. Note that you must pass 1239 * in both the uid and name of the application to be checked; this function will verify 1240 * that these two match, and if not, return {@link #MODE_IGNORED}. If this call 1241 * succeeds, the last execution time of the operation for this app will be updated to 1242 * the current time. 1243 * @param op The operation to note. One of the OP_* constants. 1244 * @param uid The user id of the application attempting to perform the operation. 1245 * @param packageName The name of the application attempting to perform the operation. 1246 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or 1247 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without 1248 * causing the app to crash). 1249 * @throws SecurityException If the app has been configured to crash on this op. 1250 * @hide 1251 */ 1252 public int noteOp(int op, int uid, String packageName) { 1253 try { 1254 int mode = mService.noteOperation(op, uid, packageName); 1255 if (mode == MODE_ERRORED) { 1256 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName)); 1257 } 1258 return mode; 1259 } catch (RemoteException e) { 1260 } 1261 return MODE_IGNORED; 1262 } 1263 1264 /** 1265 * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it 1266 * returns {@link #MODE_ERRORED}. 1267 * @hide 1268 */ 1269 public int noteOpNoThrow(int op, int uid, String packageName) { 1270 try { 1271 return mService.noteOperation(op, uid, packageName); 1272 } catch (RemoteException e) { 1273 } 1274 return MODE_IGNORED; 1275 } 1276 1277 /** @hide */ 1278 public int noteOp(int op) { 1279 return noteOp(op, Process.myUid(), mContext.getOpPackageName()); 1280 } 1281 1282 /** @hide */ 1283 public static IBinder getToken(IAppOpsService service) { 1284 synchronized (AppOpsManager.class) { 1285 if (sToken != null) { 1286 return sToken; 1287 } 1288 try { 1289 sToken = service.getToken(new Binder()); 1290 } catch (RemoteException e) { 1291 // System is dead, whatevs. 1292 } 1293 return sToken; 1294 } 1295 } 1296 1297 /** 1298 * Report that an application has started executing a long-running operation. Note that you 1299 * must pass in both the uid and name of the application to be checked; this function will 1300 * verify that these two match, and if not, return {@link #MODE_IGNORED}. If this call 1301 * succeeds, the last execution time of the operation for this app will be updated to 1302 * the current time and the operation will be marked as "running". In this case you must 1303 * later call {@link #finishOp(int, int, String)} to report when the application is no 1304 * longer performing the operation. 1305 * @param op The operation to start. One of the OP_* constants. 1306 * @param uid The user id of the application attempting to perform the operation. 1307 * @param packageName The name of the application attempting to perform the operation. 1308 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or 1309 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without 1310 * causing the app to crash). 1311 * @throws SecurityException If the app has been configured to crash on this op. 1312 * @hide 1313 */ 1314 public int startOp(int op, int uid, String packageName) { 1315 try { 1316 int mode = mService.startOperation(getToken(mService), op, uid, packageName); 1317 if (mode == MODE_ERRORED) { 1318 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName)); 1319 } 1320 return mode; 1321 } catch (RemoteException e) { 1322 } 1323 return MODE_IGNORED; 1324 } 1325 1326 /** 1327 * Like {@link #startOp} but instead of throwing a {@link SecurityException} it 1328 * returns {@link #MODE_ERRORED}. 1329 * @hide 1330 */ 1331 public int startOpNoThrow(int op, int uid, String packageName) { 1332 try { 1333 return mService.startOperation(getToken(mService), op, uid, packageName); 1334 } catch (RemoteException e) { 1335 } 1336 return MODE_IGNORED; 1337 } 1338 1339 /** @hide */ 1340 public int startOp(int op) { 1341 return startOp(op, Process.myUid(), mContext.getOpPackageName()); 1342 } 1343 1344 /** 1345 * Report that an application is no longer performing an operation that had previously 1346 * been started with {@link #startOp(int, int, String)}. There is no validation of input 1347 * or result; the parameters supplied here must be the exact same ones previously passed 1348 * in when starting the operation. 1349 * @hide 1350 */ 1351 public void finishOp(int op, int uid, String packageName) { 1352 try { 1353 mService.finishOperation(getToken(mService), op, uid, packageName); 1354 } catch (RemoteException e) { 1355 } 1356 } 1357 1358 /** @hide */ 1359 public void finishOp(int op) { 1360 finishOp(op, Process.myUid(), mContext.getOpPackageName()); 1361 } 1362} 1363