Android Framework权限篇一之RuntimePermission全体流程

Android Framework权限篇二之RuntimePermission数据结构解析

Android Framework权限篇三之后台定位权限源码分析

Android Framework权限篇四之AppOps机制

Android Framework权限篇五之完成敏感权限行为提醒

概述

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

数据结构

在上篇文章中说到的权限授权、吊销授权、判别是否授权等都会经过如下数据结构读取写入;这儿画了个图帮助大家阅览源码了解,由于嵌套比较深;

Android Framework权限篇二之RuntimePermission数据结构解析

这儿两张图结合起来看下,

  1. 第一个ArrayMap键是包名,值是Package类;Package类中有对应的PermissionsState类。
  2. PermissionsState类中是一个ArrayMap<String, PermissionData>,键是权限名,值是PermissionData类;
  3. PermissionData类中是一个SparaseArray<PermissionState>,键是整型userId,值是PermissionState(注意细节少了个s);
  4. PermissionState类则是对应权限详细的称号、是否授权、和对应flag; 全体数据结构对应下图:

Android Framework权限篇二之RuntimePermission数据结构解析

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

持久化存储

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

Android Framework权限篇二之RuntimePermission数据结构解析

装置使用授权流程

假如在使用声明了以下权限,装置使用时权限是如何授权的?如下几种权限等级都是上篇文章有说到的,第一种是默许授权的,第二种是签名权限,第三种是运行时权限

Android Framework权限篇二之RuntimePermission数据结构解析

这儿涉及到使用装置流程,能够看下如下流程图:

Android Framework权限篇二之RuntimePermission数据结构解析

这儿首要看下PermissionManagerService.restorePermissionState()(ard10上,ard9上方法称号为grantPermissions());如下代码是ard9上的源码摘录;这儿源码会判别targetsdkVersion是否大于等于23,装置完使用权限授权结果也有所不一样:

  1. >= 23 则只要一个install权限即INTERNET权限得到授权,runtime权限需求运行时申请,signature权限无法取得授权;
  2. <23 则会将runtime权限和siganture权限认为是install权限所以7个权限都得到授权

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

adb指令

这儿供给一个排查的adb指令能够看使用当前的权限状态

adb shell dumpsys package 使用包名
  • requested permissions ——使用在AndroidManifest.xml中声明的权限
  • install permissions —— normal权限授权状况,包含signature权限
  • runtime permissions —— 风险权限授权状况

Android Framework权限篇二之RuntimePermission数据结构解析

结语

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