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