Android10 requestPermissions权限申请流程

xref: /frameworks/base/core/java/android/app/Activity.java5076 ​​​​​​​

public final void requestPermissions(@NonNull String[] permissions, int requestCode) {

5077          if (requestCode < 0) {

5078              throw new IllegalArgumentException("requestCode should be >= 0");

5079          }

5080          if (mHasCurrentPermissionsRequest) {

5081              Log.w(TAG, "Can request only one set of permissions at a time");

5082              // Dispatch the callback with empty arrays which means a cancellation.

5083              onRequestPermissionsResult(requestCode, new String[0], new int[0]);

5084              return;

5085          }

5086          Intent intent = getPackageManager().buildRequestPermissionsIntent(permissions);

5087          startActivityForResult(REQUEST_PERMISSIONS_WHO_PREFIX, intent, requestCode, null);

5088          mHasCurrentPermissionsRequest = true;

5089      }

xref: /frameworks/base/core/java/android/content/pm/PackageManager.java

2968      @SystemApi

2969      public static final String ACTION_REQUEST_PERMISSIONS =

2970              "android.content.pm.action.REQUEST_PERMISSIONS";





4263      @NonNull

4264      @UnsupportedAppUsage

4265      public Intent buildRequestPermissionsIntent(@NonNull String[] permissions) {

4266          if (ArrayUtils.isEmpty(permissions)) {

4267             throw new IllegalArgumentException("permission cannot be null or empty");

4268          }

4269          Intent intent = new Intent(ACTION_REQUEST_PERMISSIONS);

4270          intent.putExtra(EXTRA_REQUEST_PERMISSIONS_NAMES, permissions);

4271          intent.setPackage(getPermissionControllerPackageName());

4272          return intent;

4273      }

xref: /packages/apps/PermissionController/AndroidManifest.xml

82         <activity android:name="com.android.packageinstaller.permission.ui.GrantPermissionsActivity"

83                 android:configChanges="keyboardHidden|screenSize"

84                 android:excludeFromRecents="true"

85                 android:theme="@style/GrantPermissions"

86                 android:visibleToInstantApps="true"

87                 android:inheritShowWhenLocked="true">

88             <intent-filter android:priority="1">

89                 <action android:name="android.content.pm.action.REQUEST_PERMISSIONS" />

90                 <category android:name="android.intent.category.DEFAULT" />

91             </intent-filter>

92         </activity>

通过隐式意图跳转到GrantPermissionsActivity。

xref: /packages/apps/PermissionController/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java

 

256      @Override

257      public void onCreate(Bundle icicle) {

258          super.onCreate(icicle);

259  

260          if (icicle == null) {

261              mRequestId = new Random().nextLong();

262          } else {

263              mRequestId = icicle.getLong(KEY_REQUEST_ID);

264          }

265  

266          getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);

267  

268          // Cache this as this can only read on onCreate, not later.

269          mCallingPackage = getCallingPackage();

270  

271          SafetyNetLogger.logIfHasUndefinedPermissionGroup(getPackageManager(), mCallingPackage);

272  

273          setFinishOnTouchOutside(false);

274  

275          setTitle(R.string.permission_request_title);

276  

277          mRequestedPermissions = getIntent().getStringArrayExtra(

278                  PackageManager.EXTRA_REQUEST_PERMISSIONS_NAMES);

279          if (mRequestedPermissions == null) {

280              mRequestedPermissions = new String[0];

281          }

282  

283          final int requestedPermCount = mRequestedPermissions.length;

284  

285          if (requestedPermCount == 0) {

286              setResultAndFinish();

287              return;

288          }

289  

290          PackageInfo callingPackageInfo = getCallingPackageInfo();

291  

292          if (callingPackageInfo == null || callingPackageInfo.requestedPermissions == null

293                  || callingPackageInfo.requestedPermissions.length <= 0) {

294              setResultAndFinish();

295              return;

296          }

297  

298          // Don't allow legacy apps to request runtime permissions.

299          if (callingPackageInfo.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {

300              // Returning empty arrays means a cancellation.

301              mRequestedPermissions = new String[0];

302              setResultAndFinish();

303              return;

304          }

305  

306          mCallingUid = callingPackageInfo.applicationInfo.uid;

307  

308          UserHandle userHandle = UserHandle.getUserHandleForUid(mCallingUid);

309  

310          if (DeviceUtils.isTelevision(this)) {

311              mViewHandler = new com.android.packageinstaller.permission.ui.television

312                      .GrantPermissionsViewHandlerImpl(this,

313                      mCallingPackage).setResultListener(this);

314          } else if (DeviceUtils.isWear(this)) {

315              mViewHandler = new GrantPermissionsWatchViewHandler(this).setResultListener(this);

316          } else if (DeviceUtils.isAuto(this)) {

317              mViewHandler = new GrantPermissionsAutoViewHandler(this, mCallingPackage, userHandle)

318                      .setResultListener(this);

319          } else {

320              mViewHandler = new com.android.packageinstaller.permission.ui.handheld

321                      .GrantPermissionsViewHandlerImpl(this, mCallingPackage, userHandle)

322                      .setResultListener(this);

323          }

324  

325          mAppPermissions = new AppPermissions(this, callingPackageInfo, false,

326                  new Runnable() {

327                      @Override

328                      public void run() {

329                          setResultAndFinish();

330                      }

331                  });

332  

333          for (String requestedPermission : mRequestedPermissions) {

334              if (requestedPermission == null) {

335                  continue;

336              }

337  

338              ArrayList<String> affectedPermissions =

339                      computeAffectedPermissions(requestedPermission);

340  

341              int numAffectedPermissions = affectedPermissions.size();

342              for (int i = 0; i < numAffectedPermissions; i++) {

343                  AppPermissionGroup group =

344                          mAppPermissions.getGroupForPermission(affectedPermissions.get(i));

345                  if (group == null) {

346                      reportRequestResult(affectedPermissions.get(i),

347                              PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED);

348  

349                      continue;

350                  }

351  

352                  addRequestedPermissions(group, affectedPermissions.get(i), icicle == null);

353              }

354          }

355  

356          int numGroupStates = mRequestGrantPermissionGroups.size();

357          for (int groupStateNum = 0; groupStateNum < numGroupStates; groupStateNum++) {

358              GroupState groupState = mRequestGrantPermissionGroups.valueAt(groupStateNum);

359              AppPermissionGroup group = groupState.mGroup;

360  

361              // Restore permission group state after lifecycle events

362              if (icicle != null) {

363                  groupState.mState = icicle.getInt(

364                          getInstanceStateKey(mRequestGrantPermissionGroups.keyAt(groupStateNum)),

365                          groupState.mState);

366              }

367  

368              // Do not attempt to grant background access if foreground access is not either already

369              // granted or requested

370              if (group.isBackgroundGroup()) {

371                  // Check if a foreground permission is already granted

372                  boolean foregroundGroupAlreadyGranted = mAppPermissions.getPermissionGroup(

373                          group.getName()).areRuntimePermissionsGranted();

374                  boolean hasForegroundRequest = (getForegroundGroupState(group.getName()) != null);

375  

376                  if (!foregroundGroupAlreadyGranted && !hasForegroundRequest) {

377                      // The background permission cannot be granted at this time

378                      int numPermissions = groupState.affectedPermissions.length;

379                      for (int permissionNum = 0; permissionNum < numPermissions; permissionNum++) {

380                          Log.w(LOG_TAG,

381                                  "Cannot grant " + groupState.affectedPermissions[permissionNum]

382                                          + " as the matching foreground permission is not already "

383                                          + "granted.");

384                      }

385  

386                      groupState.mState = GroupState.STATE_SKIPPED;

387  

388                      reportRequestResult(groupState.affectedPermissions,

389                              PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED);

390                  }

391              }

392          }

393  

394          setContentView(mViewHandler.createView());

395  

396          Window window = getWindow();

397          WindowManager.LayoutParams layoutParams = window.getAttributes();

398          mViewHandler.updateWindowAttributes(layoutParams);

399          window.setAttributes(layoutParams);

400  

401          // Restore UI state after lifecycle events. This has to be before

402          // showNextPermissionGroupGrantRequest is called. showNextPermissionGroupGrantRequest might

403          // update the UI and the UI behaves differently for updates and initial creations.

404          if (icicle != null) {

405              mViewHandler.loadInstanceState(icicle);

406          }

407  

408          if (!showNextPermissionGroupGrantRequest()) {

409              setResultAndFinish();

410          }

411      }

396          Window window = getWindow();

397          WindowManager.LayoutParams layoutParams = window.getAttributes();

398          mViewHandler.updateWindowAttributes(layoutParams);

399          window.setAttributes(layoutParams);

弹出授权的dialog界面。

xref: /packages/apps/PermissionController/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java

803      /**

804       * Grants or revoked the affected permissions for a single {@link groupState}.

805       *

806       * @param groupState The group state with the permissions to grant/revoke

807       * @param granted {@code true} if the permissions should be granted, {@code false} if they

808       *        should be revoked

809       * @param doNotAskAgain if the permissions should be revoked should be app be allowed to ask

810       *        again for the same permissions?

811       */

812      private void onPermissionGrantResultSingleState(GroupState groupState, boolean granted,

813              boolean doNotAskAgain) {

814          if (groupState != null && groupState.mGroup != null

815                  && groupState.mState == GroupState.STATE_UNKNOWN) {

816              if (granted) {

817                  groupState.mGroup.grantRuntimePermissions(doNotAskAgain,

818                          groupState.affectedPermissions);

819                  groupState.mState = GroupState.STATE_ALLOWED;

820  

821                  reportRequestResult(groupState.affectedPermissions,

822                          PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_GRANTED);

823              } else {

824                  groupState.mGroup.revokeRuntimePermissions(doNotAskAgain,

825                          groupState.affectedPermissions);

826                  groupState.mState = GroupState.STATE_DENIED;

827  

828                  reportRequestResult(groupState.affectedPermissions, doNotAskAgain

829                          ?

830                          PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED_WITH_PREJUDICE

831                          : PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED);

832              }

833          }

834      }

用户选择授权与否会在onPermissionGrantResultSingleState方法中处理。groupState.mGroup.grantRuntimePermissions方法最终会调用到AppPermissionGroup.java类中的grantRuntimePermissions方法。

xref: /packages/apps/PermissionController/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java

 754      /**

755       * Grant permissions of the group.

756       *

757       * <p>This also automatically grants all app ops for permissions that have app ops.

758       * <p>This does <u>only</u> grant permissions in {@link #mPermissions}, i.e. usually not

759       * the background permissions.

760       *

761       * @param fixedByTheUser If the user requested that she/he does not want to be asked again

762       * @param filterPermissions If {@code null} all permissions of the group will be granted.

763       *                          Otherwise only permissions in {@code filterPermissions} will be

764       *                          granted.

765       *

766       * @return {@code true} iff all permissions of this group could be granted.

767       */

768      public boolean grantRuntimePermissions(boolean fixedByTheUser, String[] filterPermissions) {

769          boolean killApp = false;

770          boolean wasAllGranted = true;

771  

772          // We toggle permissions only to apps that support runtime

773          // permissions, otherwise we toggle the app op corresponding

774          // to the permission if the permission is granted to the app.

775          for (Permission permission : mPermissions.values()) {

776              if (filterPermissions != null

777                      && !ArrayUtils.contains(filterPermissions, permission.getName())) {

778                  continue;

779              }

780  

781              if (!permission.isGrantingAllowed(mIsEphemeralApp, mAppSupportsRuntimePermissions)) {

782                  // Skip unallowed permissions.

783                  continue;

784              }

785  

786              boolean wasGranted = permission.isGrantedIncludingAppOp();

787  

788              if (mAppSupportsRuntimePermissions) {

789                  // Do not touch permissions fixed by the system.

790                  if (permission.isSystemFixed()) {

791                      wasAllGranted = false;

792                      break;

793                  }

794  

795                  // Ensure the permission app op enabled before the permission grant.

796                  if (permission.affectsAppOp() && !permission.isAppOpAllowed()) {

797                      permission.setAppOpAllowed(true);

798                  }

799  

800                  // Grant the permission if needed.

801                  if (!permission.isGranted()) {

802                      permission.setGranted(true);

803                  }

804  

805                  // Update the permission flags.

806                  if (!fixedByTheUser) {

807                      // Now the apps can ask for the permission as the user

808                      // no longer has it fixed in a denied state.

809                      if (permission.isUserFixed() || permission.isUserSet()) {

810                          permission.setUserFixed(false);

811                          permission.setUserSet(false);

812                      }

813                  }

814              } else {

815                  // Legacy apps cannot have a not granted permission but just in case.

816                  if (!permission.isGranted()) {

817                      continue;

818                  }

819  

820                  // If the permissions has no corresponding app op, then it is a

821                  // third-party one and we do not offer toggling of such permissions.

822                  if (permission.affectsAppOp()) {

823                      if (!permission.isAppOpAllowed()) {

824                          permission.setAppOpAllowed(true);

825  

826                          // Legacy apps do not know that they have to retry access to a

827                          // resource due to changes in runtime permissions (app ops in this

828                          // case). Therefore, we restart them on app op change, so they

829                          // can pick up the change.

830                          killApp = true;

831                      }

832  

833                      // Mark that the permission should not be be granted on upgrade

834                      // when the app begins supporting runtime permissions.

835                      if (permission.shouldRevokeOnUpgrade()) {

836                          permission.setRevokeOnUpgrade(false);

837                      }

838                  }

839  

840                  // Granting a permission explicitly means the user already

841                  // reviewed it so clear the review flag on every grant.

842                  if (permission.isReviewRequired()) {

843                      permission.unsetReviewRequired();

844                  }

845              }

846  

847              // If we newly grant background access to the fine location, double-guess the user some

848              // time later if this was really the right choice.

849              if (!wasGranted && permission.isGrantedIncludingAppOp()) {

850                  if (permission.getName().equals(ACCESS_FINE_LOCATION)) {

851                      Permission bgPerm = permission.getBackgroundPermission();

852                      if (bgPerm != null) {

853                          if (bgPerm.isGrantedIncludingAppOp()) {

854                              mTriggerLocationAccessCheckOnPersist = true;

855                          }

856                      }

857                  } else if (permission.getName().equals(ACCESS_BACKGROUND_LOCATION)) {

858                      ArrayList<Permission> fgPerms = permission.getForegroundPermissions();

859                      if (fgPerms != null) {

860                          int numFgPerms = fgPerms.size();

861                          for (int fgPermNum = 0; fgPermNum < numFgPerms; fgPermNum++) {

862                              Permission fgPerm = fgPerms.get(fgPermNum);

863  

864                              if (fgPerm.getName().equals(ACCESS_FINE_LOCATION)) {

865                                  if (fgPerm.isGrantedIncludingAppOp()) {

866                                      mTriggerLocationAccessCheckOnPersist = true;

867                                  }

868  

869                                  break;

870                              }

871                          }

872                      }

873                  }

874              }

875          }

876  

877          if (!mDelayChanges) {

878              persistChanges(false);

879  

880              if (killApp) {

881                  killApp(KILL_REASON_APP_OP_CHANGE);

882              }

883          }

884  

885          return wasAllGranted;

886      }

如果不延迟改变就调用persistChanges方法。

xref: /packages/apps/PermissionController/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java

1214      /**

1215       * If the changes to this group were delayed, persist them to the platform.

1216       *

1217       * @param mayKillBecauseOfAppOpsChange If the app these permissions belong to may be killed if

1218       *                                     app ops change. If this is set to {@code false} the

1219       *                                     caller has to make sure to kill the app if needed.

1220       */

1221      void persistChanges(boolean mayKillBecauseOfAppOpsChange) {

1222          int uid = mPackageInfo.applicationInfo.uid;

1223  

1224          int numPermissions = mPermissions.size();

1225          boolean shouldKillApp = false;

1226  

1227          for (int i = 0; i < numPermissions; i++) {

1228              Permission permission = mPermissions.valueAt(i);

1229  

1230              if (!permission.isSystemFixed()) {

1231                  if (permission.isGranted()) {

1232                      mPackageManager.grantRuntimePermission(mPackageInfo.packageName,

1233                              permission.getName(), mUserHandle);

1234                  } else {

1235                      boolean isCurrentlyGranted = mContext.checkPermission(permission.getName(), -1,

1236                              uid) == PERMISSION_GRANTED;

1237  

1238                      if (isCurrentlyGranted) {

1239                          mPackageManager.revokeRuntimePermission(mPackageInfo.packageName,

1240                                  permission.getName(), mUserHandle);

1241                      }

1242                  }

1243              }

1244  

1245              int flags = (permission.isUserSet() ? PackageManager.FLAG_PERMISSION_USER_SET : 0)

1246                      | (permission.isUserFixed() ? PackageManager.FLAG_PERMISSION_USER_FIXED : 0)

1247                      | (permission.shouldRevokeOnUpgrade()

1248                      ? PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE : 0)

1249                      | (permission.isPolicyFixed() ? PackageManager.FLAG_PERMISSION_POLICY_FIXED : 0)

1250                      | (permission.isReviewRequired()

1251                      ? PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED : 0);

1252  

1253              mPackageManager.updatePermissionFlags(permission.getName(),

1254                      mPackageInfo.packageName,

1255                      PackageManager.FLAG_PERMISSION_USER_SET

1256                              | PackageManager.FLAG_PERMISSION_USER_FIXED

1257                              | PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE

1258                              | PackageManager.FLAG_PERMISSION_POLICY_FIXED

1259                              | PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED,

1260                      flags, mUserHandle);

1261  

1262              if (permission.affectsAppOp()) {

1263                  if (!permission.isSystemFixed()) {

1264                      // Enabling/Disabling an app op may put the app in a situation in which it has

1265                      // a handle to state it shouldn't have, so we have to kill the app. This matches

1266                      // the revoke runtime permission behavior.

1267                      if (permission.isAppOpAllowed()) {

1268                          shouldKillApp |= allowAppOp(permission, uid);

1269                      } else {

1270                          shouldKillApp |= disallowAppOp(permission, uid);

1271                      }

1272                  }

1273              }

1274          }

1275  

1276          if (mayKillBecauseOfAppOpsChange && shouldKillApp) {

1277              killApp(KILL_REASON_APP_OP_CHANGE);

1278          }

1279  

1280          if (mTriggerLocationAccessCheckOnPersist) {

1281              new LocationAccessCheck(mContext, null).checkLocationAccessSoon();

1282              mTriggerLocationAccessCheckOnPersist = false;

1283          }

1284      }

mPackageManager.grantRuntimePermission;调用PackageManager的grantRuntimePermission。PackageManager是抽象类需要调用它的实现类ApplicationPackageManager里面的grantRuntimePermission方法,然后通过AIDL跨进程通信调用到PackageManagerService.java类中的grantRuntimePermission。

xref: /frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

5721      @Override

5722      public void grantRuntimePermission(String packageName, String permName, final int userId) {

5723          boolean overridePolicy = (checkUidPermission(

5724                  Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY, Binder.getCallingUid())

5725                  == PackageManager.PERMISSION_GRANTED);

5726  

5727          mPermissionManager.grantRuntimePermission(permName, packageName, overridePolicy,

5728                  getCallingUid(), userId, mPermissionCallback);

5729      }

调用PermissionManager类的grantRuntimePermission方法,最终会调用到PermissionManagerService类中的grantRuntimePermission方法。

xref: /frameworks/base/services/core/java/com/android/server/pm/permission/PermissionManagerService.java

2083      private void grantRuntimePermission(String permName, String packageName, boolean overridePolicy,

2084              int callingUid, final int userId, PermissionCallback callback) {

2085          if (!mUserManagerInt.exists(userId)) {

2086              Log.e(TAG, "No such user:" + userId);

2087              return;

2088          }

2089  

2090          mContext.enforceCallingOrSelfPermission(

2091                  android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,

2092                  "grantRuntimePermission");

2093  

2094          enforceCrossUserPermission(callingUid, userId,

2095                  true,  // requireFullPermission

2096                  true,  // checkShell

2097                  false, // requirePermissionWhenSameUser

2098                  "grantRuntimePermission");

2099  

2100          final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);

2101          if (pkg == null || pkg.mExtras == null) {

2102              throw new IllegalArgumentException("Unknown package: " + packageName);

2103          }

2104          final BasePermission bp;

2105          synchronized(mLock) {

2106              bp = mSettings.getPermissionLocked(permName);

2107          }

2108          if (bp == null) {

2109              throw new IllegalArgumentException("Unknown permission: " + permName);

2110          }

2111          if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {

2112              throw new IllegalArgumentException("Unknown package: " + packageName);

2113          }

2114  

2115          bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);

2116  

2117          // If a permission review is required for legacy apps we represent

2118          // their permissions as always granted runtime ones since we need

2119          // to keep the review required permission flag per user while an

2120          // install permission's state is shared across all users.

2121          if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M

2122                  && bp.isRuntime()) {

2123              return;

2124          }

2125  

2126          final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);

2127  

2128          final PackageSetting ps = (PackageSetting) pkg.mExtras;

2129          final PermissionsState permissionsState = ps.getPermissionsState();

2130  

2131          final int flags = permissionsState.getPermissionFlags(permName, userId);

2132          if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {

2133              Log.e(TAG, "Cannot grant system fixed permission "

2134                      + permName + " for package " + packageName);

2135              return;

2136          }

2137          if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {

2138              Log.e(TAG, "Cannot grant policy fixed permission "

2139                      + permName + " for package " + packageName);

2140              return;

2141          }

2142  

2143          if (bp.isHardRestricted()

2144                  && (flags & PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) == 0) {

2145              Log.e(TAG, "Cannot grant hard restricted non-exempt permission "

2146                      + permName + " for package " + packageName);

2147              return;

2148          }

2149  

2150          if (bp.isSoftRestricted() && !SoftRestrictedPermissionPolicy.forPermission(mContext,

2151                  pkg.applicationInfo, UserHandle.of(userId), permName).canBeGranted()) {

2152              Log.e(TAG, "Cannot grant soft restricted permission " + permName + " for package "

2153                      + packageName);

2154              return;

2155          }

2156  

2157          if (bp.isDevelopment()) {

2158              // Development permissions must be handled specially, since they are not

2159              // normal runtime permissions.  For now they apply to all users.

2160              if (permissionsState.grantInstallPermission(bp) !=

2161                      PERMISSION_OPERATION_FAILURE) {

2162                  if (callback != null) {

2163                      callback.onInstallPermissionGranted();

2164                  }

2165              }

2166              return;

2167          }

2168  

2169          if (ps.getInstantApp(userId) && !bp.isInstant()) {

2170              throw new SecurityException("Cannot grant non-ephemeral permission"

2171                      + permName + " for package " + packageName);

2172          }

2173  

2174          if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {

2175              Slog.w(TAG, "Cannot grant runtime permission to a legacy app");

2176              return;

2177          }

2178  

2179          final int result = permissionsState.grantRuntimePermission(bp, userId);

2180          switch (result) {

2181              case PERMISSION_OPERATION_FAILURE: {

2182                  return;

2183              }

2184  

2185              case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {

2186                  if (callback != null) {

2187                      callback.onGidsChanged(UserHandle.getAppId(pkg.applicationInfo.uid), userId);

2188                  }

2189              }

2190              break;

2191          }

2192  

2193          if (bp.isRuntime()) {

2194              logPermission(MetricsEvent.ACTION_PERMISSION_GRANTED, permName, packageName);

2195          }

2196  

2197          if (callback != null) {

2198              callback.onPermissionGranted(uid, userId);

2199          }

2200  

2201          if (bp.isRuntime()) {

2202              notifyRuntimePermissionStateChanged(packageName, userId);

2203          }

2204  

2205          // Only need to do this if user is initialized. Otherwise it's a new user

2206          // and there are no processes running as the user yet and there's no need

2207          // to make an expensive call to remount processes for the changed permissions.

2208          if (READ_EXTERNAL_STORAGE.equals(permName)

2209                  || WRITE_EXTERNAL_STORAGE.equals(permName)) {

2210              final long token = Binder.clearCallingIdentity();

2211              try {

2212                  if (mUserManagerInt.isUserInitialized(userId)) {

2213                      StorageManagerInternal storageManagerInternal = LocalServices.getService(

2214                              StorageManagerInternal.class);

2215                      storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);

2216                  }

2217              } finally {

2218                  Binder.restoreCallingIdentity(token);

2219              }

2220          }

2221  

2222      }



2197          if (callback != null) {

2198              callback.onPermissionGranted(uid, userId);

2199          }

通过callback将处理结果回调给PackageManagerService。

xref: /frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

1758      private PermissionCallback mPermissionCallback = new PermissionCallback() {

1759          @Override

1760          public void onGidsChanged(int appId, int userId) {

1761              mHandler.post(() -> killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED));

1762          }

1763          @Override

1764          public void onPermissionGranted(int uid, int userId) {

1765              mOnPermissionChangeListeners.onPermissionsChanged(uid);

1766  

1767              // Not critical; if this is lost, the application has to request again.

1768              synchronized (mPackages) {

1769                  mSettings.writeRuntimePermissionsForUserLPr(userId, false);

1770              }

1771          }

1772          @Override

1773          public void onInstallPermissionGranted() {

1774              synchronized (mPackages) {

1775                  scheduleWriteSettingsLocked();

1776              }

1777          }

1778          @Override

1779          public void onPermissionRevoked(int uid, int userId) {

1780              mOnPermissionChangeListeners.onPermissionsChanged(uid);

1781  

1782              synchronized (mPackages) {

1783                  // Critical; after this call the application should never have the permission

1784                  mSettings.writeRuntimePermissionsForUserLPr(userId, true);

1785              }

1786  

1787              final int appId = UserHandle.getAppId(uid);

1788              killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);

1789          }

1790          @Override

1791          public void onInstallPermissionRevoked() {

1792              synchronized (mPackages) {

1793                  scheduleWriteSettingsLocked();

1794              }

1795          }

1796          @Override

1797          public void onPermissionUpdated(int[] updatedUserIds, boolean sync) {

1798              synchronized (mPackages) {

1799                  for (int userId : updatedUserIds) {

1800                      mSettings.writeRuntimePermissionsForUserLPr(userId, sync);

1801                  }

1802              }

1803          }

1804          @Override

1805          public void onInstallPermissionUpdated() {

1806              synchronized (mPackages) {

1807                  scheduleWriteSettingsLocked();

1808              }

1809          }

1810          @Override

1811          public void onPermissionRemoved() {

1812              synchronized (mPackages) {

1813                  mSettings.writeLPr();

1814              }

1815          }

1816      };

mOnPermissionChangeListeners.onPermissionsChanged(uid);将处理结果回调给用户。mSettings.writeRuntimePermissionsForUserLPr(userId, false);把修改权限的结果写到runtime-permissions.xml文件里面

 

xref: /frameworks/base/services/core/java/com/android/server/pm/Settings.java

5200          private void writePermissionsSync(int userId) {

5201              AtomicFile destination = new AtomicFile(getUserRuntimePermissionsFile(userId),

5202                      "package-perms-" + userId);

5203  

5204              ArrayMap<String, List<PermissionState>> permissionsForPackage = new ArrayMap<>();

5205              ArrayMap<String, List<PermissionState>> permissionsForSharedUser = new ArrayMap<>();

5206  

5207              synchronized (mPersistenceLock) {

5208                  mWriteScheduled.delete(userId);

5209  

5210                  final int packageCount = mPackages.size();

5211                  for (int i = 0; i < packageCount; i++) {

5212                      String packageName = mPackages.keyAt(i);

5213                      PackageSetting packageSetting = mPackages.valueAt(i);

5214                      if (packageSetting.sharedUser == null) {

5215                          PermissionsState permissionsState = packageSetting.getPermissionsState();

5216                          List<PermissionState> permissionsStates = permissionsState

5217                                  .getRuntimePermissionStates(userId);

5218                          if (!permissionsStates.isEmpty()) {

5219                              permissionsForPackage.put(packageName, permissionsStates);

5220                          }

5221                      }

5222                  }

5223  

5224                  final int sharedUserCount = mSharedUsers.size();

5225                  for (int i = 0; i < sharedUserCount; i++) {

5226                      String sharedUserName = mSharedUsers.keyAt(i);

5227                      SharedUserSetting sharedUser = mSharedUsers.valueAt(i);

5228                      PermissionsState permissionsState = sharedUser.getPermissionsState();

5229                      List<PermissionState> permissionsStates = permissionsState

5230                              .getRuntimePermissionStates(userId);

5231                      if (!permissionsStates.isEmpty()) {

5232                          permissionsForSharedUser.put(sharedUserName, permissionsStates);

5233                      }

5234                  }

5235              }

5236  

5237              FileOutputStream out = null;

5238              try {

5239                  out = destination.startWrite();

5240  

5241                  XmlSerializer serializer = Xml.newSerializer();

5242                  serializer.setOutput(out, StandardCharsets.UTF_8.name());

5243                  serializer.setFeature(

5244                          "http://xmlpull.org/v1/doc/features.html#indent-output", true);

5245                  serializer.startDocument(null, true);

5246  

5247                  serializer.startTag(null, TAG_RUNTIME_PERMISSIONS);

5248  

5249                  final int version = mVersions.get(userId, INITIAL_VERSION);

5250                  serializer.attribute(null, ATTR_VERSION, Integer.toString(version));

5251  

5252                  String fingerprint = mFingerprints.get(userId);

5253                  if (fingerprint != null) {

5254                      serializer.attribute(null, ATTR_FINGERPRINT, fingerprint);

5255                  }

5256  

5257                  final int packageCount = permissionsForPackage.size();

5258                  for (int i = 0; i < packageCount; i++) {

5259                      String packageName = permissionsForPackage.keyAt(i);

5260                      List<PermissionState> permissionStates = permissionsForPackage.valueAt(i);

5261                      serializer.startTag(null, TAG_PACKAGE);

5262                      serializer.attribute(null, ATTR_NAME, packageName);

5263                      writePermissions(serializer, permissionStates);

5264                      serializer.endTag(null, TAG_PACKAGE);

5265                  }

5266  

5267                  final int sharedUserCount = permissionsForSharedUser.size();

5268                  for (int i = 0; i < sharedUserCount; i++) {

5269                      String packageName = permissionsForSharedUser.keyAt(i);

5270                      List<PermissionState> permissionStates = permissionsForSharedUser.valueAt(i);

5271                      serializer.startTag(null, TAG_SHARED_USER);

5272                      serializer.attribute(null, ATTR_NAME, packageName);

5273                      writePermissions(serializer, permissionStates);

5274                      serializer.endTag(null, TAG_SHARED_USER);

5275                  }

5276  

5277                  serializer.endTag(null, TAG_RUNTIME_PERMISSIONS);

5278  

5279                  serializer.endDocument();

5280                  destination.finishWrite(out);

5281  

5282                  if (Build.FINGERPRINT.equals(fingerprint)) {

5283                      mDefaultPermissionsGranted.put(userId, true);

5284                  }

5285              // Any error while writing is fatal.

5286              } catch (Throwable t) {

5287                  Slog.wtf(PackageManagerService.TAG,

5288                          "Failed to write settings, restoring backup", t);

5289                  destination.failWrite(out);

5290              } finally {

5291                  IoUtils.closeQuietly(out);

5292              }

5293          }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值