美文网首页
Android 权限管理--02:RuntimePermissi

Android 权限管理--02:RuntimePermissi

作者: DarcyZhou | 来源:发表于2023-12-18 08:42 被阅读0次

    本文转载自:Android Framework权限篇二之RuntimePermission数据结构解析

    本文基于Android 9.0源码分析

    1.概述

      继上文介绍,我们继续介绍下运行时权限的数据结构和应用安装时权限授权流程。

    2.数据结构

      在上篇文章中提到的权限授权、撤销授权、判断是否授权等都会通过如下数据结构读取写入;这里画了个图帮助大家阅读源码理解,因为嵌套比较深。

    权限管理2-1.PNG

    这里两张图结合起来看下:

    • 第一个ArrayMap键是包名,值是Package类;Package类中有对应的PermissionsState类。

    • PermissionsState类中是一个ArrayMap<String, PermissionData>,键是权限名,值是PermissionData类;

    • PermissionData类中是一个SparaseArray<PermissionState>,键是整型userId,值是PermissionState(注意细节少了个s);

    • PermissionState类则是对应权限具体的名称、是否授权、和对应flag;整体数据结构对应下图:

    权限管理2-2.PNG

    理解了以上之后,再回过头去看源码里关于PermissionsState类的相关方法去进行授权和判断是否授权等就容易看了

    3.持久化存储

      运行时权限会持久化存储在/data/system/users/0/runtime-permissions.xml,这里表示userid对应是0,如果有多用户则对应在其他users目录下;xml文件存储内容如下,对应上面数据结构的name、granted、flag等属性。

    权限管理2-3.PNG

    4.安装应用授权流程

      如果在应用声明了以下权限,安装应用时权限是如何授权的?如下几种权限级别都是上篇文章有提到的,第一种是默认授权的,第二种是签名权限,第三种是运行时权限。

    权限管理2-4.PNG

    这里涉及到应用安装流程,可以看下如下流程图:

    权限管理2-5.png

    这里主要看下PermissionManagerService.restorePermissionState()(android 10.0上,android 9.0上方法名称为grantPermissions());如下代码是android 9.0上的源码摘录;这里源码会判断targetsdkVersion是否大于等于23,安装完应用权限授权结果也有所不一样:

    = 23 则只有一个install权限即INTERNET权限得到授权,runtime权限需要运行时申请,signature权限无法获得授权;

    <23 则会将runtime权限和siganture权限认为是install权限所以7个权限都得到授权。

    // frameworks/base/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
    private void grantPermissions(PackageParser.Package pkg, boolean replace,String packageOfInterest, PermissionCallback callback) {
    ...
    //取出应用在AndroidManifest.xml中声明的权限,进行遍历判断是否允许安装时授权
    final int N = pkg.requestedPermissions.size();
    for (int i = 0; i < N; i++) {
        final String permName = pkg.requestedPermissions.get(i);
        //判断sdk版本号是否大于等于23;
        final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M;
    
        ...
        //1\. install权限默认直接授权   
        if (bp.isNormal()) {
            // For all apps normal permissions are install time ones.
            grant = GRANT_INSTALL;
        } else if (bp.isRuntime()) {
            //这里targetsdkversion小于23的runtime权限会设置为GRANT_INSTALL,直接授权
            if (!appSupportsRuntimePermissions && !mSettings.mPermissionReviewRequired) {
                // For legacy apps dangerous permissions are install time ones.
                grant = GRANT_INSTALL;
            } else if (origPermissions.hasInstallPermission(bp.getName())) {
                //2\. runtime权限:如果之前的权限是install,现在升级为runtime权限,则为GRANT_UPGRADE
                // For legacy apps that became modern, install becomes runtime.
                grant = GRANT_UPGRADE;
            } else if (isLegacySystemApp) {
                // For legacy system apps, install becomes runtime.
                // We cannot check hasInstallPermission() for system apps since those
                // permissions were granted implicitly and not persisted pre-M.
                grant = GRANT_UPGRADE;
            } else {
                //3\. 其余情况则为GRANT_RUNTIME
                // For modern apps keep runtime permissions unchanged.
                grant = GRANT_RUNTIME;
            }
        } else if (bp.isSignature()) {
            // For all apps signature permissions are install time ones.
            //4\. signature权限:这里会判断是否满足签名条件(如targetSdkVersion小于23返回true),为true才会设置为GRANT_INSTALL并默认授权,否则为GRANT_DENIED
            //见下5返回true
            allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
            if (allowedSig) {
                grant = GRANT_INSTALL;
            }
        }    
        ...
       //上面赋值完这里根据grant结果进行操作
       switch (grant) {
           case GRANT_INSTALL: {
               ...
               // Grant an install permission.
               //这里是install权限进行授权
               if (permissionsState.grantInstallPermission(bp) !=
                       PERMISSION_OPERATION_FAILURE) {
                   changedInstallPermission = true;
               }
           } break;
           case GRANT_RUNTIME: {
           ...
           case GRANT_UPGRADE: {
           ...
    }
    
    private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
                  BasePermission bp, PermissionsState origPermissions) {
    ...
     if (!allowed) {
        //5.signature权限判断targetSdkVersion<23则返回true
        if (!allowed
                && bp.isPre23()
                && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
            // If this was a previously normal/dangerous permission that got moved
            // to a system permission as part of the runtime permission redesign, then
            // we still want to blindly grant it to old apps.
            allowed = true;
        }
        ...
    

    5.adb命令

      这里提供一个排查的adb命令可以看应用当前的权限状态。

    adb shell dumpsys package 应用包名
    
    • requested permissions —— 应用在AndroidManifest.xml中声明的权限;

    • install permissions —— normal权限授权情况,包括signature权限;

    • runtime permissions —— 危险权限授权情况。

    权限管理2-6.png

    6.总结

      以上是运行时权限的所有介绍了,接下来的文章介绍下权限里的另一个重要角色AppOps,可以想下和运行时权限的关系是什么。

    相关文章

      网友评论

          本文标题:Android 权限管理--02:RuntimePermissi

          本文链接:https://www.haomeiwen.com/subject/vfuhidtx.html