Android 10.0 PackageManagerService(二)权限扫描-[Android取经之路]

摘要:PackageManagerService在systemReady()后,进行了/system/etc/permissions中的各种xml进行扫描,进行相应的权限存储,供以后使用

阅读本文大约需要花费15分钟。

文章的内容主要还是从源码进行分析,虽然又臭又长,但是如果想要学习Android系统源码,这是必要走的路,没有捷径。

相对于碎片学习,我更倾向于静下心来花费1个小时认真的学习一段内容。

文章首发微信公众号:IngresGe

专注于Android系统级源码分析,Android的平台设计,欢迎关注我,谢谢!

欢迎关注我的公众号!

[Android取经之路] 的源码都基于Android-Q(10.0) 进行分析

[Android取经之路] 系列文章:

《系统启动篇》

  1. Android系统架构
  2. Android是怎么启动的
  3. Android 10.0系统启动之init进程
  4. Android10.0系统启动之Zygote进程
  5. Android 10.0 系统启动之SystemServer进程
  6. Android 10.0 系统服务之ActivityMnagerService
  7. Android10.0系统启动之Launcher(桌面)启动流程
  8. Android10.0应用进程创建过程以及Zygote的fork流程
  9. Android 10.0 PackageManagerService(一)工作原理及启动流程
  10. Android 10.0 PackageManagerService(二)权限扫描
  11. Android 10.0 PackageManagerService(三)APK扫描
  12. Android 10.0 PackageManagerService(四)APK安装流程

《日志系统篇》

  1. Android10.0 日志系统分析(一)-logd、logcat 指令说明、分类和属性
  2. Android10.0 日志系统分析(二)-logd、logcat架构分析及日志系统初始化
  3. Android10.0 日志系统分析(三)-logd、logcat读写日志源码分析
  4. Android10.0 日志系统分析(四)-selinux、kernel日志在logd中的实现​

《PackageManagerService系列文章》

  1. Android 10.0 PackageManagerService(一)工作原理及启动流程
  2. Android 10.0 PackageManagerService(二)权限扫描
  3. Android 10.0 PackageManagerService(三)APK扫描
  4. Android 10.0 PackageManagerService(四)APK安装流程

《Binder通信原理》

  1. Android10.0 Binder通信原理(一)Binder、HwBinder、VndBinder概要
  2. Android10.0 Binder通信原理(二)-Binder入门篇
  3. Android10.0 Binder通信原理(三)-ServiceManager篇
  4. Android10.0 Binder通信原理(四)-Native-C\C++实例分析
  5. Android10.0 Binder通信原理(五)-Binder驱动分析
  6. Android10.0 Binder通信原理(六)-Binder数据如何完成定向打击
  7. Android10.0 Binder通信原理(七)-Framework binder示例
  8. Android10.0 Binder通信原理(八)-Framework层分析
  9. Android10.0 Binder通信原理(九)-AIDL Binder示例
  10. Android10.0 Binder通信原理(十)-AIDL原理分析-Proxy-Stub设计模式
  11. Android10.0 Binder通信原理(十一)-Binder总结

  《HwBinder通信原理》

  1. HwBinder入门篇-Android10.0 HwBinder通信原理(一)
  2.  HIDL详解-Android10.0 HwBinder通信原理(二)
  3. HIDL示例-C++服务创建Client验证-Android10.0 HwBinder通信原理(三)
  4. HIDL示例-JAVA服务创建-Client验证-Android10.0 HwBinder通信原理(四)
  5. HwServiceManager篇-Android10.0 HwBinder通信原理(五)
  6. Native层HIDL服务的注册原理-Android10.0 HwBinder通信原理(六)
  7. Native层HIDL服务的获取原理-Android10.0 HwBinder通信原理(七)
  8. JAVA层HIDL服务的注册原理-Android10.0 HwBinder通信原理(八)
  9. JAVA层HIDL服务的获取原理-Android10.0 HwBinder通信原理(九)
  10. HwBinder驱动篇-Android10.0 HwBinder通信原理(十)
  11. HwBinder原理总结-Android10.0 HwBinder通信原理(十一)

《编译原理》

  1. 编译系统入门篇-Android10.0编译系统(一)
  2. 编译环境初始化-Android10.0编译系统(二)
  3. make编译过程-Android10.0编译系统(三)
  4. Image打包流程-Android10.0编译系统(四)
  5. Kati详解-Android10.0编译系统(五)

5 权限扫描

PKMS systemReady()时,通过SystemConfig的readPermissionsFromXml()来扫描读取/system/etc/permissions中的xml文件,包括platform.xml和系统支持的各种硬件模块的feature主要工作:

参考下图:

下面就针对于上述内容,进行分析

 

5.1 [SystemConfig.java] readPermissions()

说明:扫描/system/etc/permissions中文件,调用

readPermissionsFromXml()进行解析,存入SsytemConfig相应的成员数组变量中


void readPermissions(File libraryDir, int permissionFlag) {
  ...
    // Iterate over the files in the directory and scan .xml files
    File platformFile = null;
    for (File f : libraryDir.listFiles()) {
        if (!f.isFile()) {
            continue;
        }

        // 最后读取platform.xml
        if (f.getPath().endsWith("etc/permissions/platform.xml")) {
            platformFile = f;
            continue;
        }
        ...
        readPermissionsFromXml(f, permissionFlag);
    }

    // Read platform permissions last so it will take precedence
    if (platformFile != null) {
        readPermissionsFromXml(platformFile, permissionFlag);
    }
}

解析xml的标签节点,存入mGlobalGids、mPermissions、mSystemPermissions等成员变量中,供其他进行调用


private void readPermissionsFromXml(File permFile, int permissionFlag) {
    FileReader permReader = null;
    permReader = new FileReader(permFile);
    ...
    XmlPullParser parser = Xml.newPullParser();
    parser.setInput(permReader);
    
    while (true) {
        ...
        String name = parser.getName();
         switch (name) {
             //解析 group 标签,前面介绍的 XML 文件中没有单独使用该标签的地方
            case "group": {
                String gidStr = parser.getAttributeValue(null, "gid");
                if (gidStr != null) {
                    int gid = android.os.Process.getGidForName(gidStr);
                    //转换 XML 中的 gid字符串为整型,并保存到 mGlobalGids 中
                    mGlobalGids = appendInt(mGlobalGids, gid);
                } else {
                    Slog.w(TAG, "<" + name + "> without gid in " + permFile + " at "
                            + parser.getPositionDescription());
                }
                ...
            }break;
            case "permission": { //解析 permission 标签
                if (allowPermissions) {
                    String perm = parser.getAttributeValue(null, "name");
                    if (perm == null) {
                        Slog.w(TAG, "<" + name + "> without name in " + permFile + " at "
                                + parser.getPositionDescription());
                        XmlUtils.skipCurrentTag(parser);
                        break;
                    }
                    perm = perm.intern();
                    readPermission(parser, perm); //调用 readPermission 处理,存入mPermissions
                } else {
                    logNotAllowedInPartition(name, permFile, parser);
                    XmlUtils.skipCurrentTag(parser);
                }
            } break;
         }
    }
}

5.2 XML文件

/system/etc/permissions中会存在很多的xml文件,例如我们看下

android.software.webview.xml的文件,内容如下:

<?xml version="1.0" encoding="utf-8"?>
<permissions>
    <feature name="android.software.webview" />
</permissions>

里面只只有一个feature "android.software.webview",大部分的xml都是类似的定义方式。

让我们来简单的看下/system/etc/permissions/platform.xml的内容

<?xml version="1.0" encoding="utf-8"?>
<permissions>
    <permission name="android.permission.BLUETOOTH_ADMIN" >
        <group gid="net_bt_admin" />
    </permission>
    <permission name="android.permission.INTERNET" >
        <group gid="inet" />
    </permission>
    <permission name="android.permission.READ_LOGS" >
        <group gid="log" />
    </permission>
  ...
    <assign-permission name="android.permission.MODIFY_AUDIO_SETTINGS" uid="media" />
    <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="media" />
    <assign-permission name="android.permission.WAKE_LOCK" uid="media" />
  ...
   <split-permission name="android.permission.ACCESS_FINE_LOCATION">
        <new-permission name="android.permission.ACCESS_COARSE_LOCATION" />
    </split-permission>
    <split-permission name="android.permission.WRITE_EXTERNAL_STORAGE">
        <new-permission name="android.permission.READ_EXTERNAL_STORAGE" />
    </split-permission>
    <split-permission name="android.permission.READ_CONTACTS"
                      targetSdk="16">
        <new-permission name="android.permission.READ_CALL_LOG" />
    </split-permission>
  ...
    <library name="android.test.base"
            file="/system/framework/android.test.base.jar" />
    <library name="android.test.mock"
            file="/system/framework/android.test.mock.jar"
            dependency="android.test.base" />
    <library name="android.test.runner"
            file="/system/framework/android.test.runner.jar"
            dependency="android.test.base:android.test.mock" />

    <!-- In BOOT_JARS historically, and now added to legacy applications. -->
    <library name="android.hidl.base-V1.0-java"
            file="/system/framework/android.hidl.base-V1.0-java.jar" />
    <library name="android.hidl.manager-V1.0-java"
            file="/system/framework/android.hidl.manager-V1.0-java.jar"
            dependency="android.hidl.base-V1.0-java" />
  ...
</permissions>

platform.xml中出现的标签种类则较为多样,它们的含义分别是:

  • <group>:根据name获取gid

  • <permission >标签:把属性name所描述的权限赋予给<group>标签中属性gid所表示的用户组,一个权限可以有一个或多个group对象,当一个APK授权于这个这个权限时,它同时属于这几个组

  • <assign-permission>标签:把属性name所描述的权限赋予给uid属性所表示的用户

  • <split-permission>标签:一个权限可以扩展出一个新的权限

  • <library>标签:除framework中动态库以外的,所有系统会自动加载的动态库

  • <feature>标签:硬件支持的一些feature

  • <oem-permission>标签:oem厂商自己定义的一些权限

  • <privapp-permission>标签:来自system、vendor、product、system_ext的privapp权限分别存储,这是防止供应商分区中的xml授权于系统分区中的私有应用权限

 

最后将上面xml解析出来的数据做如下存储:

  • <group>标签gid属性的值会存放在mGlobalGids数组中;

  • <permission>标签,解析得到的值会存放在mPermissions集合中;

  • <assign-permission>标签解析得到的值会存放在mSystemPermissions中;

  • <split-permission>存储在mSplitPermissions

  • <library>标签解析得到的值会存放在mSharedLibraries中;

  • <feature>存储在mAvaliableFeatures

  • <oem-permission>存储在mOemPermissions

  • <privapp-permission>会根据不同的存储路径,分别存储在mVendorPrivAppPermissions、mProductPrivAppPermissions、mSystemExtPrivAppPermissions、mPrivAppPermissions

  •  

下一节将会讲解PKMS 的APK扫描、安装等内容,欢迎关注我

微信公众号:IngresGe

  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值