PermissionManagerService.java revision 460f28c2f017dcef9c34a93c7bd5b18e97c6e15f
1/* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.pm.permission; 18 19import static android.Manifest.permission.READ_EXTERNAL_STORAGE; 20import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE; 21 22import android.Manifest; 23import android.annotation.NonNull; 24import android.annotation.Nullable; 25import android.app.AppOpsManager; 26import android.content.Context; 27import android.content.pm.PackageManager; 28import android.content.pm.PackageManagerInternal; 29import android.content.pm.PackageParser; 30import android.content.pm.PermissionGroupInfo; 31import android.content.pm.PermissionInfo; 32import android.content.pm.PackageParser.Package; 33import android.os.Binder; 34import android.os.Build; 35import android.os.Handler; 36import android.os.HandlerThread; 37import android.os.Process; 38import android.os.UserHandle; 39import android.os.UserManager; 40import android.os.UserManagerInternal; 41import android.os.storage.StorageManagerInternal; 42import android.util.ArrayMap; 43import android.util.ArraySet; 44import android.util.Log; 45import android.util.Slog; 46 47import com.android.internal.R; 48import com.android.internal.logging.MetricsLogger; 49import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 50import com.android.internal.util.ArrayUtils; 51import com.android.server.FgThread; 52import com.android.server.LocalServices; 53import com.android.server.ServiceThread; 54import com.android.server.SystemConfig; 55import com.android.server.Watchdog; 56import com.android.server.pm.PackageManagerService; 57import com.android.server.pm.PackageManagerServiceUtils; 58import com.android.server.pm.PackageSetting; 59import com.android.server.pm.ProcessLoggingHandler; 60import com.android.server.pm.SharedUserSetting; 61import com.android.server.pm.permission.DefaultPermissionGrantPolicy.DefaultPermissionGrantedCallback; 62import com.android.server.pm.permission.PermissionManagerInternal.PermissionCallback; 63import com.android.server.pm.permission.PermissionsState.PermissionState; 64 65import libcore.util.EmptyArray; 66 67import java.util.ArrayList; 68import java.util.Arrays; 69import java.util.Collection; 70import java.util.Iterator; 71import java.util.List; 72import java.util.Set; 73 74/** 75 * Manages all permissions and handles permissions related tasks. 76 */ 77public class PermissionManagerService { 78 private static final String TAG = "PackageManager"; 79 80 /** All dangerous permission names in the same order as the events in MetricsEvent */ 81 private static final List<String> ALL_DANGEROUS_PERMISSIONS = Arrays.asList( 82 Manifest.permission.READ_CALENDAR, 83 Manifest.permission.WRITE_CALENDAR, 84 Manifest.permission.CAMERA, 85 Manifest.permission.READ_CONTACTS, 86 Manifest.permission.WRITE_CONTACTS, 87 Manifest.permission.GET_ACCOUNTS, 88 Manifest.permission.ACCESS_FINE_LOCATION, 89 Manifest.permission.ACCESS_COARSE_LOCATION, 90 Manifest.permission.RECORD_AUDIO, 91 Manifest.permission.READ_PHONE_STATE, 92 Manifest.permission.CALL_PHONE, 93 Manifest.permission.READ_CALL_LOG, 94 Manifest.permission.WRITE_CALL_LOG, 95 Manifest.permission.ADD_VOICEMAIL, 96 Manifest.permission.USE_SIP, 97 Manifest.permission.PROCESS_OUTGOING_CALLS, 98 Manifest.permission.READ_CELL_BROADCASTS, 99 Manifest.permission.BODY_SENSORS, 100 Manifest.permission.SEND_SMS, 101 Manifest.permission.RECEIVE_SMS, 102 Manifest.permission.READ_SMS, 103 Manifest.permission.RECEIVE_WAP_PUSH, 104 Manifest.permission.RECEIVE_MMS, 105 Manifest.permission.READ_EXTERNAL_STORAGE, 106 Manifest.permission.WRITE_EXTERNAL_STORAGE, 107 Manifest.permission.READ_PHONE_NUMBERS, 108 Manifest.permission.ANSWER_PHONE_CALLS); 109 110 /** Cap the size of permission trees that 3rd party apps can define */ 111 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768; // characters of text 112 113 /** Lock to protect internal data access */ 114 private final Object mLock; 115 116 /** Internal connection to the package manager */ 117 private final PackageManagerInternal mPackageManagerInt; 118 119 /** Internal connection to the user manager */ 120 private final UserManagerInternal mUserManagerInt; 121 122 /** Default permission policy to provide proper behaviour out-of-the-box */ 123 private final DefaultPermissionGrantPolicy mDefaultPermissionGrantPolicy; 124 125 /** Internal storage for permissions and related settings */ 126 private final PermissionSettings mSettings; 127 128 private final HandlerThread mHandlerThread; 129 private final Handler mHandler; 130 private final Context mContext; 131 132 PermissionManagerService(Context context, 133 @Nullable DefaultPermissionGrantedCallback defaultGrantCallback, 134 @NonNull Object externalLock) { 135 mContext = context; 136 mLock = externalLock; 137 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class); 138 mUserManagerInt = LocalServices.getService(UserManagerInternal.class); 139 mSettings = new PermissionSettings(context, mLock); 140 141 mHandlerThread = new ServiceThread(TAG, 142 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/); 143 mHandlerThread.start(); 144 mHandler = new Handler(mHandlerThread.getLooper()); 145 Watchdog.getInstance().addThread(mHandler); 146 147 mDefaultPermissionGrantPolicy = new DefaultPermissionGrantPolicy( 148 context, mHandlerThread.getLooper(), defaultGrantCallback, this); 149 150 // propagate permission configuration 151 final ArrayMap<String, SystemConfig.PermissionEntry> permConfig = 152 SystemConfig.getInstance().getPermissions(); 153 synchronized (mLock) { 154 for (int i=0; i<permConfig.size(); i++) { 155 final SystemConfig.PermissionEntry perm = permConfig.valueAt(i); 156 BasePermission bp = mSettings.getPermissionLocked(perm.name); 157 if (bp == null) { 158 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN); 159 mSettings.putPermissionLocked(perm.name, bp); 160 } 161 if (perm.gids != null) { 162 bp.setGids(perm.gids, perm.perUser); 163 } 164 } 165 } 166 167 LocalServices.addService( 168 PermissionManagerInternal.class, new PermissionManagerInternalImpl()); 169 } 170 171 /** 172 * Creates and returns an initialized, internal service for use by other components. 173 * <p> 174 * The object returned is identical to the one returned by the LocalServices class using: 175 * {@code LocalServices.getService(PermissionManagerInternal.class);} 176 * <p> 177 * NOTE: The external lock is temporary and should be removed. This needs to be a 178 * lock created by the permission manager itself. 179 */ 180 public static PermissionManagerInternal create(Context context, 181 @Nullable DefaultPermissionGrantedCallback defaultGrantCallback, 182 @NonNull Object externalLock) { 183 final PermissionManagerInternal permMgrInt = 184 LocalServices.getService(PermissionManagerInternal.class); 185 if (permMgrInt != null) { 186 return permMgrInt; 187 } 188 new PermissionManagerService(context, defaultGrantCallback, externalLock); 189 return LocalServices.getService(PermissionManagerInternal.class); 190 } 191 192 @Nullable BasePermission getPermission(String permName) { 193 synchronized (mLock) { 194 return mSettings.getPermissionLocked(permName); 195 } 196 } 197 198 private int checkPermission(String permName, String pkgName, int callingUid, int userId) { 199 if (!mUserManagerInt.exists(userId)) { 200 return PackageManager.PERMISSION_DENIED; 201 } 202 203 final PackageParser.Package pkg = mPackageManagerInt.getPackage(pkgName); 204 if (pkg != null && pkg.mExtras != null) { 205 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) { 206 return PackageManager.PERMISSION_DENIED; 207 } 208 final PackageSetting ps = (PackageSetting) pkg.mExtras; 209 final boolean instantApp = ps.getInstantApp(userId); 210 final PermissionsState permissionsState = ps.getPermissionsState(); 211 if (permissionsState.hasPermission(permName, userId)) { 212 if (instantApp) { 213 synchronized (mLock) { 214 BasePermission bp = mSettings.getPermissionLocked(permName); 215 if (bp != null && bp.isInstant()) { 216 return PackageManager.PERMISSION_GRANTED; 217 } 218 } 219 } else { 220 return PackageManager.PERMISSION_GRANTED; 221 } 222 } 223 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 224 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 225 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 226 return PackageManager.PERMISSION_GRANTED; 227 } 228 } 229 230 return PackageManager.PERMISSION_DENIED; 231 } 232 233 private PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags, 234 int callingUid) { 235 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) { 236 return null; 237 } 238 synchronized (mLock) { 239 return PackageParser.generatePermissionGroupInfo( 240 mSettings.mPermissionGroups.get(groupName), flags); 241 } 242 } 243 244 private List<PermissionGroupInfo> getAllPermissionGroups(int flags, int callingUid) { 245 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) { 246 return null; 247 } 248 synchronized (mLock) { 249 final int N = mSettings.mPermissionGroups.size(); 250 final ArrayList<PermissionGroupInfo> out 251 = new ArrayList<PermissionGroupInfo>(N); 252 for (PackageParser.PermissionGroup pg : mSettings.mPermissionGroups.values()) { 253 out.add(PackageParser.generatePermissionGroupInfo(pg, flags)); 254 } 255 return out; 256 } 257 } 258 259 private PermissionInfo getPermissionInfo(String permName, String packageName, int flags, 260 int callingUid) { 261 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) { 262 return null; 263 } 264 // reader 265 synchronized (mLock) { 266 final BasePermission bp = mSettings.getPermissionLocked(permName); 267 if (bp == null) { 268 return null; 269 } 270 final int adjustedProtectionLevel = adjustPermissionProtectionFlagsLocked( 271 bp.getProtectionLevel(), packageName, callingUid); 272 return bp.generatePermissionInfo(adjustedProtectionLevel, flags); 273 } 274 } 275 276 private List<PermissionInfo> getPermissionInfoByGroup( 277 String groupName, int flags, int callingUid) { 278 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) { 279 return null; 280 } 281 synchronized (mLock) { 282 if (groupName != null && !mSettings.mPermissionGroups.containsKey(groupName)) { 283 return null; 284 } 285 final ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10); 286 for (BasePermission bp : mSettings.mPermissions.values()) { 287 final PermissionInfo pi = bp.generatePermissionInfo(groupName, flags); 288 if (pi != null) { 289 out.add(pi); 290 } 291 } 292 return out; 293 } 294 } 295 296 private int adjustPermissionProtectionFlagsLocked( 297 int protectionLevel, String packageName, int uid) { 298 // Signature permission flags area always reported 299 final int protectionLevelMasked = protectionLevel 300 & (PermissionInfo.PROTECTION_NORMAL 301 | PermissionInfo.PROTECTION_DANGEROUS 302 | PermissionInfo.PROTECTION_SIGNATURE); 303 if (protectionLevelMasked == PermissionInfo.PROTECTION_SIGNATURE) { 304 return protectionLevel; 305 } 306 // System sees all flags. 307 final int appId = UserHandle.getAppId(uid); 308 if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID 309 || appId == Process.SHELL_UID) { 310 return protectionLevel; 311 } 312 // Normalize package name to handle renamed packages and static libs 313 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName); 314 if (pkg == null) { 315 return protectionLevel; 316 } 317 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) { 318 return protectionLevelMasked; 319 } 320 // Apps that target O see flags for all protection levels. 321 final PackageSetting ps = (PackageSetting) pkg.mExtras; 322 if (ps == null) { 323 return protectionLevel; 324 } 325 if (ps.getAppId() != appId) { 326 return protectionLevel; 327 } 328 return protectionLevel; 329 } 330 331 private void addAllPermissions(PackageParser.Package pkg, boolean chatty) { 332 final int N = pkg.permissions.size(); 333 for (int i=0; i<N; i++) { 334 PackageParser.Permission p = pkg.permissions.get(i); 335 336 // Assume by default that we did not install this permission into the system. 337 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED; 338 339 synchronized (PermissionManagerService.this.mLock) { 340 // Now that permission groups have a special meaning, we ignore permission 341 // groups for legacy apps to prevent unexpected behavior. In particular, 342 // permissions for one app being granted to someone just because they happen 343 // to be in a group defined by another app (before this had no implications). 344 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) { 345 p.group = mSettings.mPermissionGroups.get(p.info.group); 346 // Warn for a permission in an unknown group. 347 if (PackageManagerService.DEBUG_PERMISSIONS 348 && p.info.group != null && p.group == null) { 349 Slog.i(TAG, "Permission " + p.info.name + " from package " 350 + p.info.packageName + " in an unknown group " + p.info.group); 351 } 352 } 353 354 if (p.tree) { 355 final BasePermission bp = BasePermission.createOrUpdate( 356 mSettings.getPermissionTreeLocked(p.info.name), p, pkg, 357 mSettings.getAllPermissionTreesLocked(), chatty); 358 mSettings.putPermissionTreeLocked(p.info.name, bp); 359 } else { 360 final BasePermission bp = BasePermission.createOrUpdate( 361 mSettings.getPermissionLocked(p.info.name), 362 p, pkg, mSettings.getAllPermissionTreesLocked(), chatty); 363 mSettings.putPermissionLocked(p.info.name, bp); 364 } 365 } 366 } 367 } 368 369 private void addAllPermissionGroups(PackageParser.Package pkg, boolean chatty) { 370 final int N = pkg.permissionGroups.size(); 371 StringBuilder r = null; 372 for (int i=0; i<N; i++) { 373 final PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i); 374 final PackageParser.PermissionGroup cur = mSettings.mPermissionGroups.get(pg.info.name); 375 final String curPackageName = (cur == null) ? null : cur.info.packageName; 376 final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName); 377 if (cur == null || isPackageUpdate) { 378 mSettings.mPermissionGroups.put(pg.info.name, pg); 379 if (chatty && PackageManagerService.DEBUG_PACKAGE_SCANNING) { 380 if (r == null) { 381 r = new StringBuilder(256); 382 } else { 383 r.append(' '); 384 } 385 if (isPackageUpdate) { 386 r.append("UPD:"); 387 } 388 r.append(pg.info.name); 389 } 390 } else { 391 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 392 + pg.info.packageName + " ignored: original from " 393 + cur.info.packageName); 394 if (chatty && PackageManagerService.DEBUG_PACKAGE_SCANNING) { 395 if (r == null) { 396 r = new StringBuilder(256); 397 } else { 398 r.append(' '); 399 } 400 r.append("DUP:"); 401 r.append(pg.info.name); 402 } 403 } 404 } 405 if (r != null && PackageManagerService.DEBUG_PACKAGE_SCANNING) { 406 Log.d(TAG, " Permission Groups: " + r); 407 } 408 409 } 410 411 private void removeAllPermissions(PackageParser.Package pkg, boolean chatty) { 412 synchronized (mLock) { 413 int N = pkg.permissions.size(); 414 StringBuilder r = null; 415 for (int i=0; i<N; i++) { 416 PackageParser.Permission p = pkg.permissions.get(i); 417 BasePermission bp = (BasePermission) mSettings.mPermissions.get(p.info.name); 418 if (bp == null) { 419 bp = mSettings.mPermissionTrees.get(p.info.name); 420 } 421 if (bp != null && bp.isPermission(p)) { 422 bp.setPermission(null); 423 if (PackageManagerService.DEBUG_REMOVE && chatty) { 424 if (r == null) { 425 r = new StringBuilder(256); 426 } else { 427 r.append(' '); 428 } 429 r.append(p.info.name); 430 } 431 } 432 if (p.isAppOp()) { 433 ArraySet<String> appOpPkgs = 434 mSettings.mAppOpPermissionPackages.get(p.info.name); 435 if (appOpPkgs != null) { 436 appOpPkgs.remove(pkg.packageName); 437 } 438 } 439 } 440 if (r != null) { 441 if (PackageManagerService.DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 442 } 443 444 N = pkg.requestedPermissions.size(); 445 r = null; 446 for (int i=0; i<N; i++) { 447 String perm = pkg.requestedPermissions.get(i); 448 if (mSettings.isPermissionAppOp(perm)) { 449 ArraySet<String> appOpPkgs = mSettings.mAppOpPermissionPackages.get(perm); 450 if (appOpPkgs != null) { 451 appOpPkgs.remove(pkg.packageName); 452 if (appOpPkgs.isEmpty()) { 453 mSettings.mAppOpPermissionPackages.remove(perm); 454 } 455 } 456 } 457 } 458 if (r != null) { 459 if (PackageManagerService.DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 460 } 461 } 462 } 463 464 private boolean addDynamicPermission( 465 PermissionInfo info, int callingUid, PermissionCallback callback) { 466 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) { 467 throw new SecurityException("Instant apps can't add permissions"); 468 } 469 if (info.labelRes == 0 && info.nonLocalizedLabel == null) { 470 throw new SecurityException("Label must be specified in permission"); 471 } 472 final BasePermission tree = mSettings.enforcePermissionTree(info.name, callingUid); 473 final boolean added; 474 final boolean changed; 475 synchronized (mLock) { 476 BasePermission bp = mSettings.getPermissionLocked(info.name); 477 added = bp == null; 478 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel); 479 if (added) { 480 enforcePermissionCapLocked(info, tree); 481 bp = new BasePermission(info.name, tree.getSourcePackageName(), 482 BasePermission.TYPE_DYNAMIC); 483 } else if (bp.isDynamic()) { 484 // TODO: switch this back to SecurityException 485 Slog.wtf(TAG, "Not allowed to modify non-dynamic permission " 486 + info.name); 487 } 488 changed = bp.addToTree(fixedLevel, info, tree); 489 if (added) { 490 mSettings.putPermissionLocked(info.name, bp); 491 } 492 } 493 if (changed && callback != null) { 494 callback.onPermissionChanged(); 495 } 496 return added; 497 } 498 499 private void removeDynamicPermission( 500 String permName, int callingUid, PermissionCallback callback) { 501 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) { 502 throw new SecurityException("Instant applications don't have access to this method"); 503 } 504 final BasePermission tree = mSettings.enforcePermissionTree(permName, callingUid); 505 synchronized (mLock) { 506 final BasePermission bp = mSettings.getPermissionLocked(permName); 507 if (bp == null) { 508 return; 509 } 510 if (bp.isDynamic()) { 511 // TODO: switch this back to SecurityException 512 Slog.wtf(TAG, "Not allowed to modify non-dynamic permission " 513 + permName); 514 } 515 mSettings.removePermissionLocked(permName); 516 if (callback != null) { 517 callback.onPermissionRemoved(); 518 } 519 } 520 } 521 522 private void grantRuntimePermissionsGrantedToDisabledPackageLocked( 523 PackageParser.Package pkg, int callingUid, PermissionCallback callback) { 524 if (pkg.parentPackage == null) { 525 return; 526 } 527 if (pkg.requestedPermissions == null) { 528 return; 529 } 530 final PackageParser.Package disabledPkg = 531 mPackageManagerInt.getDisabledPackage(pkg.parentPackage.packageName); 532 if (disabledPkg == null || disabledPkg.mExtras == null) { 533 return; 534 } 535 final PackageSetting disabledPs = (PackageSetting) disabledPkg.mExtras; 536 if (!disabledPs.isPrivileged() || disabledPs.hasChildPackages()) { 537 return; 538 } 539 final int permCount = pkg.requestedPermissions.size(); 540 for (int i = 0; i < permCount; i++) { 541 String permission = pkg.requestedPermissions.get(i); 542 BasePermission bp = mSettings.getPermissionLocked(permission); 543 if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) { 544 continue; 545 } 546 for (int userId : mUserManagerInt.getUserIds()) { 547 if (disabledPs.getPermissionsState().hasRuntimePermission(permission, userId)) { 548 grantRuntimePermission( 549 permission, pkg.packageName, false, callingUid, userId, callback); 550 } 551 } 552 } 553 } 554 555 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds, 556 String[] grantedPermissions, int callingUid, PermissionCallback callback) { 557 for (int userId : userIds) { 558 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions, callingUid, 559 callback); 560 } 561 } 562 563 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId, 564 String[] grantedPermissions, int callingUid, PermissionCallback callback) { 565 PackageSetting ps = (PackageSetting) pkg.mExtras; 566 if (ps == null) { 567 return; 568 } 569 570 PermissionsState permissionsState = ps.getPermissionsState(); 571 572 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 573 | PackageManager.FLAG_PERMISSION_POLICY_FIXED; 574 575 final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion 576 >= Build.VERSION_CODES.M; 577 578 final boolean instantApp = mPackageManagerInt.isInstantApp(pkg.packageName, userId); 579 580 for (String permission : pkg.requestedPermissions) { 581 final BasePermission bp; 582 synchronized (mLock) { 583 bp = mSettings.getPermissionLocked(permission); 584 } 585 if (bp != null && (bp.isRuntime() || bp.isDevelopment()) 586 && (!instantApp || bp.isInstant()) 587 && (supportsRuntimePermissions || !bp.isRuntimeOnly()) 588 && (grantedPermissions == null 589 || ArrayUtils.contains(grantedPermissions, permission))) { 590 final int flags = permissionsState.getPermissionFlags(permission, userId); 591 if (supportsRuntimePermissions) { 592 // Installer cannot change immutable permissions. 593 if ((flags & immutableFlags) == 0) { 594 grantRuntimePermission(permission, pkg.packageName, false, callingUid, 595 userId, callback); 596 } 597 } else if (mSettings.mPermissionReviewRequired) { 598 // In permission review mode we clear the review flag when we 599 // are asked to install the app with all permissions granted. 600 if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) { 601 updatePermissionFlags(permission, pkg.packageName, 602 PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, callingUid, 603 userId, callback); 604 } 605 } 606 } 607 } 608 } 609 610 private void grantRuntimePermission(String permName, String packageName, boolean overridePolicy, 611 int callingUid, final int userId, PermissionCallback callback) { 612 if (!mUserManagerInt.exists(userId)) { 613 Log.e(TAG, "No such user:" + userId); 614 return; 615 } 616 617 mContext.enforceCallingOrSelfPermission( 618 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 619 "grantRuntimePermission"); 620 621 enforceCrossUserPermission(callingUid, userId, 622 true /* requireFullPermission */, true /* checkShell */, 623 "grantRuntimePermission"); 624 625 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName); 626 if (pkg == null || pkg.mExtras == null) { 627 throw new IllegalArgumentException("Unknown package: " + packageName); 628 } 629 final BasePermission bp; 630 synchronized(mLock) { 631 bp = mSettings.getPermissionLocked(permName); 632 } 633 if (bp == null) { 634 throw new IllegalArgumentException("Unknown permission: " + permName); 635 } 636 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) { 637 throw new IllegalArgumentException("Unknown package: " + packageName); 638 } 639 640 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg); 641 642 // If a permission review is required for legacy apps we represent 643 // their permissions as always granted runtime ones since we need 644 // to keep the review required permission flag per user while an 645 // install permission's state is shared across all users. 646 if (mSettings.mPermissionReviewRequired 647 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M 648 && bp.isRuntime()) { 649 return; 650 } 651 652 final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid); 653 654 final PackageSetting ps = (PackageSetting) pkg.mExtras; 655 final PermissionsState permissionsState = ps.getPermissionsState(); 656 657 final int flags = permissionsState.getPermissionFlags(permName, userId); 658 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 659 throw new SecurityException("Cannot grant system fixed permission " 660 + permName + " for package " + packageName); 661 } 662 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) { 663 throw new SecurityException("Cannot grant policy fixed permission " 664 + permName + " for package " + packageName); 665 } 666 667 if (bp.isDevelopment()) { 668 // Development permissions must be handled specially, since they are not 669 // normal runtime permissions. For now they apply to all users. 670 if (permissionsState.grantInstallPermission(bp) != 671 PermissionsState.PERMISSION_OPERATION_FAILURE) { 672 if (callback != null) { 673 callback.onInstallPermissionGranted(); 674 } 675 } 676 return; 677 } 678 679 if (ps.getInstantApp(userId) && !bp.isInstant()) { 680 throw new SecurityException("Cannot grant non-ephemeral permission" 681 + permName + " for package " + packageName); 682 } 683 684 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 685 Slog.w(TAG, "Cannot grant runtime permission to a legacy app"); 686 return; 687 } 688 689 final int result = permissionsState.grantRuntimePermission(bp, userId); 690 switch (result) { 691 case PermissionsState.PERMISSION_OPERATION_FAILURE: { 692 return; 693 } 694 695 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 696 if (callback != null) { 697 callback.onGidsChanged(UserHandle.getAppId(pkg.applicationInfo.uid), userId); 698 } 699 } 700 break; 701 } 702 703 if (bp.isRuntime()) { 704 logPermissionGranted(mContext, permName, packageName); 705 } 706 707 if (callback != null) { 708 callback.onPermissionGranted(uid, userId); 709 } 710 711 // Only need to do this if user is initialized. Otherwise it's a new user 712 // and there are no processes running as the user yet and there's no need 713 // to make an expensive call to remount processes for the changed permissions. 714 if (READ_EXTERNAL_STORAGE.equals(permName) 715 || WRITE_EXTERNAL_STORAGE.equals(permName)) { 716 final long token = Binder.clearCallingIdentity(); 717 try { 718 if (mUserManagerInt.isUserInitialized(userId)) { 719 StorageManagerInternal storageManagerInternal = LocalServices.getService( 720 StorageManagerInternal.class); 721 storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName); 722 } 723 } finally { 724 Binder.restoreCallingIdentity(token); 725 } 726 } 727 728 } 729 730 private void revokeRuntimePermission(String permName, String packageName, 731 boolean overridePolicy, int callingUid, int userId, PermissionCallback callback) { 732 if (!mUserManagerInt.exists(userId)) { 733 Log.e(TAG, "No such user:" + userId); 734 return; 735 } 736 737 mContext.enforceCallingOrSelfPermission( 738 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 739 "revokeRuntimePermission"); 740 741 enforceCrossUserPermission(Binder.getCallingUid(), userId, 742 true /* requireFullPermission */, true /* checkShell */, 743 "revokeRuntimePermission"); 744 745 final int appId; 746 747 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName); 748 if (pkg == null || pkg.mExtras == null) { 749 throw new IllegalArgumentException("Unknown package: " + packageName); 750 } 751 if (mPackageManagerInt.filterAppAccess(pkg, Binder.getCallingUid(), userId)) { 752 throw new IllegalArgumentException("Unknown package: " + packageName); 753 } 754 final BasePermission bp = mSettings.getPermissionLocked(permName); 755 if (bp == null) { 756 throw new IllegalArgumentException("Unknown permission: " + permName); 757 } 758 759 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg); 760 761 // If a permission review is required for legacy apps we represent 762 // their permissions as always granted runtime ones since we need 763 // to keep the review required permission flag per user while an 764 // install permission's state is shared across all users. 765 if (mSettings.mPermissionReviewRequired 766 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M 767 && bp.isRuntime()) { 768 return; 769 } 770 771 final PackageSetting ps = (PackageSetting) pkg.mExtras; 772 final PermissionsState permissionsState = ps.getPermissionsState(); 773 774 final int flags = permissionsState.getPermissionFlags(permName, userId); 775 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 776 throw new SecurityException("Cannot revoke system fixed permission " 777 + permName + " for package " + packageName); 778 } 779 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) { 780 throw new SecurityException("Cannot revoke policy fixed permission " 781 + permName + " for package " + packageName); 782 } 783 784 if (bp.isDevelopment()) { 785 // Development permissions must be handled specially, since they are not 786 // normal runtime permissions. For now they apply to all users. 787 if (permissionsState.revokeInstallPermission(bp) != 788 PermissionsState.PERMISSION_OPERATION_FAILURE) { 789 if (callback != null) { 790 callback.onInstallPermissionRevoked(); 791 } 792 } 793 return; 794 } 795 796 if (permissionsState.revokeRuntimePermission(bp, userId) == 797 PermissionsState.PERMISSION_OPERATION_FAILURE) { 798 return; 799 } 800 801 if (bp.isRuntime()) { 802 logPermissionRevoked(mContext, permName, packageName); 803 } 804 805 if (callback != null) { 806 final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid); 807 callback.onPermissionRevoked(pkg.applicationInfo.uid, userId); 808 } 809 } 810 811 private int[] revokeUnusedSharedUserPermissions(SharedUserSetting suSetting, int[] allUserIds) { 812 // Collect all used permissions in the UID 813 final ArraySet<String> usedPermissions = new ArraySet<>(); 814 final List<PackageParser.Package> pkgList = suSetting.getPackages(); 815 if (pkgList == null || pkgList.size() == 0) { 816 return EmptyArray.INT; 817 } 818 for (PackageParser.Package pkg : pkgList) { 819 final int requestedPermCount = pkg.requestedPermissions.size(); 820 for (int j = 0; j < requestedPermCount; j++) { 821 String permission = pkg.requestedPermissions.get(j); 822 BasePermission bp = mSettings.getPermissionLocked(permission); 823 if (bp != null) { 824 usedPermissions.add(permission); 825 } 826 } 827 } 828 829 PermissionsState permissionsState = suSetting.getPermissionsState(); 830 // Prune install permissions 831 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates(); 832 final int installPermCount = installPermStates.size(); 833 for (int i = installPermCount - 1; i >= 0; i--) { 834 PermissionState permissionState = installPermStates.get(i); 835 if (!usedPermissions.contains(permissionState.getName())) { 836 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName()); 837 if (bp != null) { 838 permissionsState.revokeInstallPermission(bp); 839 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 840 PackageManager.MASK_PERMISSION_FLAGS, 0); 841 } 842 } 843 } 844 845 int[] runtimePermissionChangedUserIds = EmptyArray.INT; 846 847 // Prune runtime permissions 848 for (int userId : allUserIds) { 849 List<PermissionState> runtimePermStates = permissionsState 850 .getRuntimePermissionStates(userId); 851 final int runtimePermCount = runtimePermStates.size(); 852 for (int i = runtimePermCount - 1; i >= 0; i--) { 853 PermissionState permissionState = runtimePermStates.get(i); 854 if (!usedPermissions.contains(permissionState.getName())) { 855 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName()); 856 if (bp != null) { 857 permissionsState.revokeRuntimePermission(bp, userId); 858 permissionsState.updatePermissionFlags(bp, userId, 859 PackageManager.MASK_PERMISSION_FLAGS, 0); 860 runtimePermissionChangedUserIds = ArrayUtils.appendInt( 861 runtimePermissionChangedUserIds, userId); 862 } 863 } 864 } 865 } 866 867 return runtimePermissionChangedUserIds; 868 } 869 870 private String[] getAppOpPermissionPackages(String permName) { 871 if (mPackageManagerInt.getInstantAppPackageName(Binder.getCallingUid()) != null) { 872 return null; 873 } 874 synchronized (mLock) { 875 final ArraySet<String> pkgs = mSettings.mAppOpPermissionPackages.get(permName); 876 if (pkgs == null) { 877 return null; 878 } 879 return pkgs.toArray(new String[pkgs.size()]); 880 } 881 } 882 883 private int getPermissionFlags( 884 String permName, String packageName, int callingUid, int userId) { 885 if (!mUserManagerInt.exists(userId)) { 886 return 0; 887 } 888 889 enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags"); 890 891 enforceCrossUserPermission(callingUid, userId, 892 true /* requireFullPermission */, false /* checkShell */, 893 "getPermissionFlags"); 894 895 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName); 896 if (pkg == null || pkg.mExtras == null) { 897 return 0; 898 } 899 synchronized (mLock) { 900 if (mSettings.getPermissionLocked(permName) == null) { 901 return 0; 902 } 903 } 904 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) { 905 return 0; 906 } 907 final PackageSetting ps = (PackageSetting) pkg.mExtras; 908 PermissionsState permissionsState = ps.getPermissionsState(); 909 return permissionsState.getPermissionFlags(permName, userId); 910 } 911 912 private int updatePermissions(String packageName, PackageParser.Package pkgInfo, int flags) { 913 Set<BasePermission> needsUpdate = null; 914 synchronized (mLock) { 915 final Iterator<BasePermission> it = mSettings.mPermissions.values().iterator(); 916 while (it.hasNext()) { 917 final BasePermission bp = it.next(); 918 if (bp.isDynamic()) { 919 bp.updateDynamicPermission(mSettings.mPermissionTrees.values()); 920 } 921 if (bp.getSourcePackageSetting() != null) { 922 if (packageName != null && packageName.equals(bp.getSourcePackageName()) 923 && (pkgInfo == null || !hasPermission(pkgInfo, bp.getName()))) { 924 Slog.i(TAG, "Removing old permission tree: " + bp.getName() 925 + " from package " + bp.getSourcePackageName()); 926 flags |= PackageManagerService.UPDATE_PERMISSIONS_ALL; 927 it.remove(); 928 } 929 continue; 930 } 931 if (needsUpdate == null) { 932 needsUpdate = new ArraySet<>(mSettings.mPermissions.size()); 933 } 934 needsUpdate.add(bp); 935 } 936 } 937 if (needsUpdate != null) { 938 for (final BasePermission bp : needsUpdate) { 939 final PackageParser.Package pkg = 940 mPackageManagerInt.getPackage(bp.getSourcePackageName()); 941 synchronized (mLock) { 942 if (pkg != null && pkg.mExtras != null) { 943 final PackageSetting ps = (PackageSetting) pkg.mExtras; 944 if (bp.getSourcePackageSetting() == null) { 945 bp.setSourcePackageSetting(ps); 946 } 947 continue; 948 } 949 Slog.w(TAG, "Removing dangling permission: " + bp.getName() 950 + " from package " + bp.getSourcePackageName()); 951 mSettings.removePermissionLocked(bp.getName()); 952 } 953 } 954 } 955 return flags; 956 } 957 958 private int updatePermissionTrees(String packageName, PackageParser.Package pkgInfo, 959 int flags) { 960 Set<BasePermission> needsUpdate = null; 961 synchronized (mLock) { 962 final Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator(); 963 while (it.hasNext()) { 964 final BasePermission bp = it.next(); 965 if (bp.getSourcePackageSetting() != null) { 966 if (packageName != null && packageName.equals(bp.getSourcePackageName()) 967 && (pkgInfo == null || !hasPermission(pkgInfo, bp.getName()))) { 968 Slog.i(TAG, "Removing old permission tree: " + bp.getName() 969 + " from package " + bp.getSourcePackageName()); 970 flags |= PackageManagerService.UPDATE_PERMISSIONS_ALL; 971 it.remove(); 972 } 973 continue; 974 } 975 if (needsUpdate == null) { 976 needsUpdate = new ArraySet<>(mSettings.mPermissionTrees.size()); 977 } 978 needsUpdate.add(bp); 979 } 980 } 981 if (needsUpdate != null) { 982 for (final BasePermission bp : needsUpdate) { 983 final PackageParser.Package pkg = 984 mPackageManagerInt.getPackage(bp.getSourcePackageName()); 985 synchronized (mLock) { 986 if (pkg != null && pkg.mExtras != null) { 987 final PackageSetting ps = (PackageSetting) pkg.mExtras; 988 if (bp.getSourcePackageSetting() == null) { 989 bp.setSourcePackageSetting(ps); 990 } 991 continue; 992 } 993 Slog.w(TAG, "Removing dangling permission tree: " + bp.getName() 994 + " from package " + bp.getSourcePackageName()); 995 mSettings.removePermissionLocked(bp.getName()); 996 } 997 } 998 } 999 return flags; 1000 } 1001 1002 private void updatePermissionFlags(String permName, String packageName, int flagMask, 1003 int flagValues, int callingUid, int userId, PermissionCallback callback) { 1004 if (!mUserManagerInt.exists(userId)) { 1005 return; 1006 } 1007 1008 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags"); 1009 1010 enforceCrossUserPermission(callingUid, userId, 1011 true /* requireFullPermission */, true /* checkShell */, 1012 "updatePermissionFlags"); 1013 1014 // Only the system can change these flags and nothing else. 1015 if (callingUid != Process.SYSTEM_UID) { 1016 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 1017 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 1018 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 1019 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 1020 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 1021 } 1022 1023 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName); 1024 if (pkg == null || pkg.mExtras == null) { 1025 throw new IllegalArgumentException("Unknown package: " + packageName); 1026 } 1027 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) { 1028 throw new IllegalArgumentException("Unknown package: " + packageName); 1029 } 1030 1031 final BasePermission bp; 1032 synchronized (mLock) { 1033 bp = mSettings.getPermissionLocked(permName); 1034 } 1035 if (bp == null) { 1036 throw new IllegalArgumentException("Unknown permission: " + permName); 1037 } 1038 1039 final PackageSetting ps = (PackageSetting) pkg.mExtras; 1040 final PermissionsState permissionsState = ps.getPermissionsState(); 1041 final boolean hadState = 1042 permissionsState.getRuntimePermissionState(permName, userId) != null; 1043 final boolean permissionUpdated = 1044 permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues); 1045 if (permissionUpdated && callback != null) { 1046 // Install and runtime permissions are stored in different places, 1047 // so figure out what permission changed and persist the change. 1048 if (permissionsState.getInstallPermissionState(permName) != null) { 1049 callback.onInstallPermissionUpdated(); 1050 } else if (permissionsState.getRuntimePermissionState(permName, userId) != null 1051 || hadState) { 1052 callback.onPermissionUpdated(userId); 1053 } 1054 } 1055 } 1056 1057 private boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid, 1058 int userId, Collection<Package> packages, PermissionCallback callback) { 1059 if (!mUserManagerInt.exists(userId)) { 1060 return false; 1061 } 1062 1063 enforceGrantRevokeRuntimePermissionPermissions( 1064 "updatePermissionFlagsForAllApps"); 1065 enforceCrossUserPermission(callingUid, userId, 1066 true /* requireFullPermission */, true /* checkShell */, 1067 "updatePermissionFlagsForAllApps"); 1068 1069 // Only the system can change system fixed flags. 1070 if (callingUid != Process.SYSTEM_UID) { 1071 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 1072 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 1073 } 1074 1075 boolean changed = false; 1076 for (PackageParser.Package pkg : packages) { 1077 final PackageSetting ps = (PackageSetting) pkg.mExtras; 1078 if (ps == null) { 1079 continue; 1080 } 1081 PermissionsState permissionsState = ps.getPermissionsState(); 1082 changed |= permissionsState.updatePermissionFlagsForAllPermissions( 1083 userId, flagMask, flagValues); 1084 } 1085 return changed; 1086 } 1087 1088 private void enforceGrantRevokeRuntimePermissionPermissions(String message) { 1089 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS) 1090 != PackageManager.PERMISSION_GRANTED 1091 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) 1092 != PackageManager.PERMISSION_GRANTED) { 1093 throw new SecurityException(message + " requires " 1094 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or " 1095 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS); 1096 } 1097 } 1098 1099 /** 1100 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS 1101 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller. 1102 * @param checkShell whether to prevent shell from access if there's a debugging restriction 1103 * @param message the message to log on security exception 1104 */ 1105 private void enforceCrossUserPermission(int callingUid, int userId, 1106 boolean requireFullPermission, boolean checkShell, String message) { 1107 if (userId < 0) { 1108 throw new IllegalArgumentException("Invalid userId " + userId); 1109 } 1110 if (checkShell) { 1111 PackageManagerServiceUtils.enforceShellRestriction( 1112 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); 1113 } 1114 if (userId == UserHandle.getUserId(callingUid)) return; 1115 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 1116 if (requireFullPermission) { 1117 mContext.enforceCallingOrSelfPermission( 1118 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 1119 } else { 1120 try { 1121 mContext.enforceCallingOrSelfPermission( 1122 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 1123 } catch (SecurityException se) { 1124 mContext.enforceCallingOrSelfPermission( 1125 android.Manifest.permission.INTERACT_ACROSS_USERS, message); 1126 } 1127 } 1128 } 1129 } 1130 1131 private int calculateCurrentPermissionFootprintLocked(BasePermission tree) { 1132 int size = 0; 1133 for (BasePermission perm : mSettings.mPermissions.values()) { 1134 size += tree.calculateFootprint(perm); 1135 } 1136 return size; 1137 } 1138 1139 private void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) { 1140 // We calculate the max size of permissions defined by this uid and throw 1141 // if that plus the size of 'info' would exceed our stated maximum. 1142 if (tree.getUid() != Process.SYSTEM_UID) { 1143 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree); 1144 if (curTreeSize + info.calculateFootprint() > MAX_PERMISSION_TREE_FOOTPRINT) { 1145 throw new SecurityException("Permission tree size cap exceeded"); 1146 } 1147 } 1148 } 1149 1150 private static boolean hasPermission(PackageParser.Package pkgInfo, String permName) { 1151 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) { 1152 if (pkgInfo.permissions.get(i).info.name.equals(permName)) { 1153 return true; 1154 } 1155 } 1156 return false; 1157 } 1158 1159 /** 1160 * Get the first event id for the permission. 1161 * 1162 * <p>There are four events for each permission: <ul> 1163 * <li>Request permission: first id + 0</li> 1164 * <li>Grant permission: first id + 1</li> 1165 * <li>Request for permission denied: first id + 2</li> 1166 * <li>Revoke permission: first id + 3</li> 1167 * </ul></p> 1168 * 1169 * @param name name of the permission 1170 * 1171 * @return The first event id for the permission 1172 */ 1173 private static int getBaseEventId(@NonNull String name) { 1174 int eventIdIndex = ALL_DANGEROUS_PERMISSIONS.indexOf(name); 1175 1176 if (eventIdIndex == -1) { 1177 if (AppOpsManager.permissionToOpCode(name) == AppOpsManager.OP_NONE 1178 || Build.IS_USER) { 1179 Log.i(TAG, "Unknown permission " + name); 1180 1181 return MetricsEvent.ACTION_PERMISSION_REQUEST_UNKNOWN; 1182 } else { 1183 // Most likely #ALL_DANGEROUS_PERMISSIONS needs to be updated. 1184 // 1185 // Also update 1186 // - EventLogger#ALL_DANGEROUS_PERMISSIONS 1187 // - metrics_constants.proto 1188 throw new IllegalStateException("Unknown permission " + name); 1189 } 1190 } 1191 1192 return MetricsEvent.ACTION_PERMISSION_REQUEST_READ_CALENDAR + eventIdIndex * 4; 1193 } 1194 1195 /** 1196 * Log that a permission was revoked. 1197 * 1198 * @param context Context of the caller 1199 * @param name name of the permission 1200 * @param packageName package permission if for 1201 */ 1202 private static void logPermissionRevoked(@NonNull Context context, @NonNull String name, 1203 @NonNull String packageName) { 1204 MetricsLogger.action(context, getBaseEventId(name) + 3, packageName); 1205 } 1206 1207 /** 1208 * Log that a permission request was granted. 1209 * 1210 * @param context Context of the caller 1211 * @param name name of the permission 1212 * @param packageName package permission if for 1213 */ 1214 private static void logPermissionGranted(@NonNull Context context, @NonNull String name, 1215 @NonNull String packageName) { 1216 MetricsLogger.action(context, getBaseEventId(name) + 1, packageName); 1217 } 1218 1219 private class PermissionManagerInternalImpl extends PermissionManagerInternal { 1220 @Override 1221 public void addAllPermissions(Package pkg, boolean chatty) { 1222 PermissionManagerService.this.addAllPermissions(pkg, chatty); 1223 } 1224 @Override 1225 public void addAllPermissionGroups(Package pkg, boolean chatty) { 1226 PermissionManagerService.this.addAllPermissionGroups(pkg, chatty); 1227 } 1228 @Override 1229 public void removeAllPermissions(Package pkg, boolean chatty) { 1230 PermissionManagerService.this.removeAllPermissions(pkg, chatty); 1231 } 1232 @Override 1233 public boolean addDynamicPermission(PermissionInfo info, boolean async, int callingUid, 1234 PermissionCallback callback) { 1235 return PermissionManagerService.this.addDynamicPermission(info, callingUid, callback); 1236 } 1237 @Override 1238 public void removeDynamicPermission(String permName, int callingUid, 1239 PermissionCallback callback) { 1240 PermissionManagerService.this.removeDynamicPermission(permName, callingUid, callback); 1241 } 1242 @Override 1243 public void grantRuntimePermission(String permName, String packageName, 1244 boolean overridePolicy, int callingUid, int userId, 1245 PermissionCallback callback) { 1246 PermissionManagerService.this.grantRuntimePermission( 1247 permName, packageName, overridePolicy, callingUid, userId, callback); 1248 } 1249 @Override 1250 public void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds, 1251 String[] grantedPermissions, int callingUid, PermissionCallback callback) { 1252 PermissionManagerService.this.grantRequestedRuntimePermissions( 1253 pkg, userIds, grantedPermissions, callingUid, callback); 1254 } 1255 @Override 1256 public void grantRuntimePermissionsGrantedToDisabledPackage(PackageParser.Package pkg, 1257 int callingUid, PermissionCallback callback) { 1258 PermissionManagerService.this.grantRuntimePermissionsGrantedToDisabledPackageLocked( 1259 pkg, callingUid, callback); 1260 } 1261 @Override 1262 public void revokeRuntimePermission(String permName, String packageName, 1263 boolean overridePolicy, int callingUid, int userId, 1264 PermissionCallback callback) { 1265 PermissionManagerService.this.revokeRuntimePermission(permName, packageName, 1266 overridePolicy, callingUid, userId, callback); 1267 } 1268 @Override 1269 public int[] revokeUnusedSharedUserPermissions(SharedUserSetting suSetting, 1270 int[] allUserIds) { 1271 return PermissionManagerService.this.revokeUnusedSharedUserPermissions( 1272 (SharedUserSetting) suSetting, allUserIds); 1273 } 1274 @Override 1275 public String[] getAppOpPermissionPackages(String permName) { 1276 return PermissionManagerService.this.getAppOpPermissionPackages(permName); 1277 } 1278 @Override 1279 public int getPermissionFlags(String permName, String packageName, int callingUid, 1280 int userId) { 1281 return PermissionManagerService.this.getPermissionFlags(permName, packageName, 1282 callingUid, userId); 1283 } 1284 @Override 1285 public int updatePermissions(String packageName, 1286 PackageParser.Package pkgInfo, int flags) { 1287 return PermissionManagerService.this.updatePermissions(packageName, pkgInfo, flags); 1288 } 1289 @Override 1290 public int updatePermissionTrees(String packageName, 1291 PackageParser.Package pkgInfo, int flags) { 1292 return PermissionManagerService.this.updatePermissionTrees(packageName, pkgInfo, flags); 1293 } 1294 @Override 1295 public void updatePermissionFlags(String permName, String packageName, int flagMask, 1296 int flagValues, int callingUid, int userId, PermissionCallback callback) { 1297 PermissionManagerService.this.updatePermissionFlags( 1298 permName, packageName, flagMask, flagValues, callingUid, userId, callback); 1299 } 1300 @Override 1301 public boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid, 1302 int userId, Collection<Package> packages, PermissionCallback callback) { 1303 return PermissionManagerService.this.updatePermissionFlagsForAllApps( 1304 flagMask, flagValues, callingUid, userId, packages, callback); 1305 } 1306 @Override 1307 public void enforceCrossUserPermission(int callingUid, int userId, 1308 boolean requireFullPermission, boolean checkShell, String message) { 1309 PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId, 1310 requireFullPermission, checkShell, message); 1311 } 1312 @Override 1313 public void enforceGrantRevokeRuntimePermissionPermissions(String message) { 1314 PermissionManagerService.this.enforceGrantRevokeRuntimePermissionPermissions(message); 1315 } 1316 @Override 1317 public int checkPermission(String permName, String packageName, int callingUid, 1318 int userId) { 1319 return PermissionManagerService.this.checkPermission( 1320 permName, packageName, callingUid, userId); 1321 } 1322 @Override 1323 public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags, 1324 int callingUid) { 1325 return PermissionManagerService.this.getPermissionGroupInfo( 1326 groupName, flags, callingUid); 1327 } 1328 @Override 1329 public List<PermissionGroupInfo> getAllPermissionGroups(int flags, int callingUid) { 1330 return PermissionManagerService.this.getAllPermissionGroups(flags, callingUid); 1331 } 1332 @Override 1333 public PermissionInfo getPermissionInfo(String permName, String packageName, int flags, 1334 int callingUid) { 1335 return PermissionManagerService.this.getPermissionInfo( 1336 permName, packageName, flags, callingUid); 1337 } 1338 @Override 1339 public List<PermissionInfo> getPermissionInfoByGroup(String group, int flags, 1340 int callingUid) { 1341 return PermissionManagerService.this.getPermissionInfoByGroup(group, flags, callingUid); 1342 } 1343 @Override 1344 public PermissionSettings getPermissionSettings() { 1345 return mSettings; 1346 } 1347 @Override 1348 public DefaultPermissionGrantPolicy getDefaultPermissionGrantPolicy() { 1349 return mDefaultPermissionGrantPolicy; 1350 } 1351 @Override 1352 public BasePermission getPermissionTEMP(String permName) { 1353 synchronized (PermissionManagerService.this.mLock) { 1354 return mSettings.getPermissionLocked(permName); 1355 } 1356 } 1357 @Override 1358 public void putPermissionTEMP(String permName, BasePermission permission) { 1359 synchronized (PermissionManagerService.this.mLock) { 1360 mSettings.putPermissionLocked(permName, (BasePermission) permission); 1361 } 1362 } 1363 @Override 1364 public Iterator<BasePermission> getPermissionIteratorTEMP() { 1365 synchronized (PermissionManagerService.this.mLock) { 1366 return mSettings.getAllPermissionsLocked().iterator(); 1367 } 1368 } 1369 } 1370} 1371