Android权限 - 动态权限申请系统流程

话不多说直接上流程图:

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;
    }
}

猜你喜欢

转载自blog.csdn.net/hanhan1016/article/details/106004292
今日推荐