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