Android10.0 PKMS 源码解读(三)

五部曲 - PMS之权限扫描
此 “PMS之权限扫描” 学习的目标是: PackageManagerService中执行systemReady()后,需求对
/system/etc/permissions中的各种xml进行扫描,进行相应的权限存储,让以后可以使用,这就是本次
“PMS只权限扫描”学习的目的
权限扫描:
PackageManagerService执行systemReady()时,通过SystemConfig的readPermissionsFromXml()来
扫描读取/system/etc/permissions中的xml文件,包括platform.xml和系统支持的各种硬件模块的
feature主要工作:
整体图:

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

查看 XML文件:
adb devices
adb shell

然后在导出去:

adb pull /system/etc/permissions

/system/etc/permissions中会存在很多的xml文件,例如我们看下 android.software.webview.xml的
文件,内容如下:
里面只只有一个feature "android.software.webview",大部分的xml都是类似的定义方式

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

让我们来简单的看下/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中出现的标签种类则较为多样,它们的含义分别是:

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

总结:权限扫描,扫描/system/etc/permissions中的xml,存入相应的结构体中,供之后权限管理使用

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值