话不多说直接上流程图:
1.checkSelfPermission
2.requestPermissions
因为都不是很复杂的流程,所以也咩有太多需要说明的,除了以下两点需要稍微知道下,算是自己记录下:
1.在checkSelfPermission流程中
调用到ActivityManager(frameworks\base\core\java\android\app\ActivityManager.java)中的方法checkComponentPermission比较重要
在这个方法中,可以知道root及systemuid的进程的权限直接PERMISSION_GRANTED。
public static int checkComponentPermission(String permission, int uid,
int owningUid, boolean exported) {
// Root, system server get to do everything.
final int appId = UserHandle.getAppId(uid);
if (appId == Process.ROOT_UID || appId == Process.SYSTEM_UID) {
return PackageManager.PERMISSION_GRANTED;
}
// Isolated processes don't get any permissions.
if (UserHandle.isIsolated(uid)) {
return PackageManager.PERMISSION_DENIED;
}
// If there is a uid that owns whatever is being accessed, it has
// blanket access to it regardless of the permissions it requires.
if (owningUid >= 0 && UserHandle.isSameApp(uid, owningUid)) {
return PackageManager.PERMISSION_GRANTED;
}
// If the target is not exported, then nobody else can get to it.
if (!exported) {
/*
RuntimeException here = new RuntimeException("here");
here.fillInStackTrace();
Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid,
here);
*/
return PackageManager.PERMISSION_DENIED;
}
if (permission == null) {
return PackageManager.PERMISSION_GRANTED;
}
try {
return AppGlobals.getPackageManager()
.checkUidPermission(permission, uid);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
2.在requestPermissions流程中
会调用到AppPermissionGroup(packages\apps\PermissionController\src\com\android\packageinstaller\permission\model\AppPermissionGroup.java)中的方法persistChanges
在这个方法中,可以知道在权限进行revoke时会先进行判断当前权限是否为PERMISSION_GRANTED,只有是才会进行revoke。
void persistChanges(boolean mayKillBecauseOfAppOpsChange) {
int uid = mPackageInfo.applicationInfo.uid;
int numPermissions = mPermissions.size();
boolean shouldKillApp = false;
for (int i = 0; i < numPermissions; i++) {
Permission permission = mPermissions.valueAt(i);
if (!permission.isSystemFixed()) {
if (permission.isGranted()) {
mPackageManager.grantRuntimePermission(mPackageInfo.packageName,
permission.getName(), mUserHandle);
} else {
boolean isCurrentlyGranted = mContext.checkPermission(permission.getName(), -1,
uid) == PERMISSION_GRANTED;
if (isCurrentlyGranted) {
mPackageManager.revokeRuntimePermission(mPackageInfo.packageName,
permission.getName(), mUserHandle);
}
}
}
int flags = (permission.isUserSet() ? PackageManager.FLAG_PERMISSION_USER_SET : 0)
| (permission.isUserFixed() ? PackageManager.FLAG_PERMISSION_USER_FIXED : 0)
| (permission.shouldRevokeOnUpgrade()
? PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE : 0)
| (permission.isPolicyFixed() ? PackageManager.FLAG_PERMISSION_POLICY_FIXED : 0)
| (permission.isReviewRequired()
? PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED : 0);
mPackageManager.updatePermissionFlags(permission.getName(),
mPackageInfo.packageName,
PackageManager.FLAG_PERMISSION_USER_SET
| PackageManager.FLAG_PERMISSION_USER_FIXED
| PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE
| PackageManager.FLAG_PERMISSION_POLICY_FIXED
| PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED,
flags, mUserHandle);
if (permission.affectsAppOp()) {
if (!permission.isSystemFixed()) {
// Enabling/Disabling an app op may put the app in a situation in which it has
// a handle to state it shouldn't have, so we have to kill the app. This matches
// the revoke runtime permission behavior.
if (permission.isAppOpAllowed()) {
shouldKillApp |= allowAppOp(permission, uid);
} else {
shouldKillApp |= disallowAppOp(permission, uid);
}
}
}
}
if (mayKillBecauseOfAppOpsChange && shouldKillApp) {
killApp(KILL_REASON_APP_OP_CHANGE);
}
if (mTriggerLocationAccessCheckOnPersist) {
new LocationAccessCheck(mContext, null).checkLocationAccessSoon();
mTriggerLocationAccessCheckOnPersist = false;
}
}