尧图精选

Android priv-app 特权权限白名单与开机崩溃排查

🕒 发布时间:2026/10/1 19:25:50 📁 来源:尧图网络
1. 特权应用和白名单机制先把概念边界划清楚做 Android 系统定制的同学多半都遇到过一个很魔性的场景应用代码没动、业务逻辑也没改只是把它从/system/app挪到了/system/priv-app重新刷机之后设备就卡在开机动画里再也起不来串口日志刷得飞快翻上去一看是一行Signature|privileged permissions not in privapp-permissions whitelist。我第一次碰到的时候愣了半天——权限明明在AndroidManifest.xml里声明了protectionLevel也确实写着signature|privileged凭什么不给我答案就藏在privapp-permissions这套白名单机制里。它是 Android 从 8.0 引入、到 9.0 变成强制的权限闸门专门管一件事哪些特权应用被允许申请哪些特权权限。你没写在白名单里系统宁可起不来也绝不放行。这篇文章就把它从设计意图、文件格式、实操补齐一路讲到排查避坑适合做 ROM 定制、系统应用预置、厂商适配的工程师也适合刚接触系统源码、想知道“我这权限到底被谁卡住了”的开发者。1.1/system/priv-app和/system/app的分界线在哪很多新人以为这两个目录只是“重要程度不同”其实它们是两道完全不同的处理路径。放在/system/app里的预置应用跟从应用商店装进来的普通应用在权限视野上没有本质区别而放在/system/priv-app里的应用在PackageManagerService扫描阶段会被额外打上一个privileged标记从此它才有资格持有protectionLevel中带privileged字样的权限。这个特权目录最早是 Android 4.4 引入的当时的动机很朴素有些系统级功能确实需要更高权限但又不该把所有预置应用都变成“想干什么就干什么”的超级用户。于是划出一块区域只有这里的应用才能申请WRITE_SECURE_SETTINGS、MOUNT_UNMOUNT_FILESYSTEMS、PACKAGE_USAGE_STATS、CHANGE_CONFIGURATION、INSTALL_PACKAGES、DELETE_PACKAGES、REBOOT、MODIFY_PHONE_STATE这类动辄影响整机行为的权限。但仅仅划目录是不够的。目录谁都能往里塞东西OEM 塞、方案商塞、外购模块也塞久而久之/system/priv-app就成了一个“权限提权后门”——只要往里面丢个 apk声明一下特权权限重启之后它就有了。Android 8.0 之前这套玩法畅通无阻这才是后来自名单机制被引入的直接原因。1.2 白名单机制解决的是“信任扩散”问题换个生活化的类比以前的/system/priv-app就像公司里一间没上锁的机房只要你把工位搬进去就能直接操作核心设备。现在加了一道门禁门上贴着一张名单写着“某某工号允许操作某某设备”没写上去的人哪怕人已经站在机房里也碰不到设备。这张名单就是privapp-permissions-*.xml。它的价值不在于“多一层校验”而在于把权限授予从隐式变成显式。以前应用在 Manifest 里声明了特权权限就自动拿到现在必须在系统侧的 XML 里再写一遍等于系统工程师必须主动确认“这个应用确实需要这个权限”。这一步人工确认恰好卡住了批量预置、来路不明的 apk 混入、第三方模块私自提权这几类最常见的风险。从 Android 9 开始这套校验默认进入enforce模式也就是发现违规直接抛异常。PackageManagerService在扫描时如果发现某个特权应用请求了白名单之外的权限会打印类似Signature|privileged permissions not in privapp-permissions whitelist: {com.demo.privapp: android.permission.WRITE_SECURE_SETTINGS}的日志然后让system_server挂掉。system_server一起来就崩起来就崩表现出来就是无限开机动画。很多同学第一次遇到会以为是驱动问题、内核问题绕了很大一圈才回到权限上。1.3 哪些角色最容易被这套机制卡住按照我的经验被卡住的场景高度集中在这几类一是 OEM 自研的系统应用从旧版本平台迁移过来时 Manifests 里留着历史权限二是外购或第三方提供的 apk直接被丢进priv-app目录三是把 AOSP 的某个模块移植到自家产品上只搬了应用没搬白名单文件四是刷机包定制玩家兴致勃勃把某个应用放进特权目录结果刷完开不了机。这几类的共同点是它们都绕过了“系统工程师主动确认权限”这一步。所以理解这套机制重点不是背 XML 语法而是建立“进 priv-app 必查权限、加权限必写白名单”的条件反射。后面所有实操内容都是围绕这个反射展开的。2. 权限模型底层三类权限与它们的分工要搞明白白名单为什么存在绕不开 Android 权限体系本身。这个体系里权限的保护级别protectionLevel决定了“谁能拿到它”而保护级别不是只有一个维度它是可以按位或组合的。理解了这个组合规则你就明白为什么有些权限写进白名单也没用。2.1 signature、privileged、dangerous 三种保护级别对比日常打交道最多的三类可以简单概括成签名权限看“血统”特权权限看“位置”运行时权限看“用户点不点头”。下表是我自己整理的一份速查对照放在团队里给新人看很管用保护级别判定依据典型权限是否需要写白名单signature与定义该权限的应用同签名android.permission.BIND_DEVICE_ADMIN不需要但必须同签名signature|privileged位于 priv-app 分区且写入白名单WRITE_SECURE_SETTINGS、PACKAGE_USAGE_STATS需要dangerous用户运行时弹窗授权ACCESS_FINE_LOCATION、CAMERA不需要写了反而报错normal安装即授予INTERNET、ACCESS_NETWORK_STATE不需要signature|privileged|development特权 允许开发版授予部分调试类权限需要这张表里最值得盯住的是signature|privileged这一行它是白名单机制唯一管辖的对象。而dangerous那一行是重灾区——很多人以为“定位权限、相机权限也属于系统权限应该一起写进白名单”结果把ACCESS_FINE_LOCATION塞进privapp-permissions-*.xml编译出来的系统在解析阶段就会报权限类型不匹配或者干脆被静默忽略白折腾半天。2.2 为什么 privileged 权限要单独加锁signature权限的防线是签名你的应用必须和定义权限的那个应用用同一把密钥签密钥拿不到权限就永远拿不到。这条防线足够硬因为密钥是物理隔离的资产。privileged权限没法用签名来防——它面对的是“预装”这个场景而预装 apk 千千万不可能要求每个都跟平台同签名。于是只能用“位置 白名单”组合来兜底位置决定你有没有资格看一眼这份权限白名单决定你能拿走哪几个。两个条件必须同时满足。这里有个容易混淆的点signature|privileged不等于“特权应用一定能拿到”。如果某个权限的定义里同时带signature和privileged两个标志那它其实有两条获取路径——要么跟定义者同签名要么在特权分区且在白名单里。反过来纯signature的权限即使应用在 priv-app 分区、白名单也写了还是需要同签名才能拿到。这一点在做平台签名权限适配时最容易踩坑我们后面第 5 章会专门讲。2.3 白名单校验发生在启动的哪个时刻这个时序问题很关键它决定了你排查的方向。整个链路大致是内核启动 →init解析build.prop和各个分区属性 → 拉起zygote→zygotefork 出system_server→system_server里PackageManagerService开始扫描所有分区 → 扫描到priv-app目录时读取etc/permissions/privapp-permissions-*.xml→ 逐个包比对请求的特权权限 → 有违规就记录日志并按当前策略处理。ro.control_privapp_permissions这个只读属性控制的就是最后一步的处理方式它有三个取值disable表示完全关掉校验log表示只记录日志放行enforce表示严格执行、违规即崩。不同编译类型默认值不一样正式发布的user版本普遍是enforce调试版本更常见配置成log方便定位。这也是为什么很多问题只在量产版本上暴露——userdebug上跑得好好的切到user就开不了机。明白这个时序之后排查思路就清晰了既然校验发生在 PMS 扫描阶段那么只要你能在日志里抓到 PMS 那几行报错就知道是哪个包、缺哪个权限。与其盯着屏幕猜不如直接把logcat的缓冲区全打开捞一遍。3. 白名单文件的写法路径、命名、XML 结构这一章讲文件本身。看起来只有十几行 XML但真正踩过坑的人都知道出问题的地方往往不是“权限写错了”而是“文件根本没被系统看见”。3.1 存放路径与分区对应关系Android 8 到 9 时期权限白名单基本只有两个去处/system/etc/permissions/和/vendor/etc/permissions/。Android 10 引入分区化之后可选位置一下子变多了常见的有这几个/system/etc/permissions/平台级、核心系统模块/system_ext/etc/permissions/系统扩展模块/product/etc/permissions/产品定制模块/vendor/etc/permissions/厂商私有模块/odm/etc/permissions/ODM 层模块PackageManagerService会把这些目录全扫一遍所以理论上你把文件放哪个分区都能生效。但有一个隐含约束必须注意权限定义文件所在的分区通常要跟应用所在的分区有对应关系。比如应用装在/product/priv-app白名单却在/system/etc/permissions里定义早期版本上这是允许的但在不同分区被独立升级的机制下容易失控。稳妥做法是让两边分区保持一致或者把公共权限集中放到平台层统一管理。我个人的习惯是平台通用模块归/system/etc/permissions产品特定模块归/product/etc/permissions厂商硬件相关归/vendor/etc/permissions。这样做的好处是每个团队各管一摊合并代码时冲突少。3.2 文件命名规则踩过坑的都懂这是最容易翻车的一条。文件名必须严格以privapp-permissions-开头以.xml结尾中间那段后缀随便取但要注意后缀是用来区分不同来源的AOSP 自带的是privapp-permissions-platform.xmlGoogle 相关的一般叫privapp-permissions-google.xml厂商自己的通常拿公司名或产品线命名比如privapp-permissions-acme.xml。我亲眼见过一个同事把文件名写成priv-app-permissions-acme.xml多了一个连字符编译进镜像之后一点报错都没有系统照常启动权限却一个都没生效。他查了两个下午最后用dumpsys对比才发现文件压根没被加载。所以记住文件名不匹配前缀系统不会报错也不会解析就是彻底的无视。另一个小坑是同一个包里同一个权限不要在多份白名单文件里重复定义。早期版本对这种情况会抛重复定义错误后期版本虽然容忍度提高了但日志里会冒出一堆警告排查噪音很大。规矩很简单一个包的白名单条目只在一个文件里出现一次。3.3 XML 标签结构逐行拆解结构本身非常朴素只有两层?xml version1.0 encodingutf-8? permissions privapp-permissions packagecom.demo.systemapp permission nameandroid.permission.WRITE_SECURE_SETTINGS/ permission nameandroid.permission.PACKAGE_USAGE_STATS/ /privapp-permissions /permissions根标签是permissions这是 Android 权限配置文件的统一入口名所有etc/permissions下的文件都用它。中间是零到多个privapp-permissions节点每个节点代表一个应用package属性必须写应用的真实包名大小写敏感。再往里是若干permission节点name属性写完整的权限字符串注意是android.permission.XXX这种带前缀的全名不能只写XXX。新手最容易犯的两个语法错误一是漏掉?xml version1.0 encodingutf-8?声明某些老版本的解析器会因此直接跳过整个文件二是权限名前后混入空格或者换行符看起来一样但实际上匹配不上。第二种尤其阴险编辑器格式化之后看不出来只能靠二进制比对或者cat -A查不可见字符。3.4 把文件编译进镜像的几种姿势写完 XML 只是第一步还得让它进到镜像里。用 Android.bp 的话最省事的是prebuilt_etcprebuilt_etc { name: privapp-permissions-acme, src: privapp-permissions-acme.xml, sub_dir: permissions, filename_from_src: true, }然后把这模块名加进产品的PRODUCT_PACKAGES列表里。如果项目还在用 Android.mk等价写法是include $(CLEAR_VARS) LOCAL_MODULE : privapp-permissions-acme.xml LOCAL_MODULE_CLASS : ETC LOCAL_MODULE_PATH : $(TARGET_OUT_ETC)/permissions LOCAL_SRC_FILES : $(LOCAL_MODULE) include $(BUILD_PREBUILT)还有一种更“图省事”的做法让老板看了想骂人的那种就是直接用PRODUCT_COPY_FILES硬拷。这个方式在快速验证阶段确实好用但它绕过了模块依赖检查容易在增量编译时出现“文件没更新”的诡异现象。正式产品里我强烈建议走prebuilt_etc至少编译系统知道这个文件的存在和依赖关系。4. 动手实操给一个特权应用补全白名单理论讲完进入正题。假设现在有个包名com.demo.systemapp的应用要预置到/system/priv-app它在 Manifest 里声明了三个权限。我们从零到一把它调通。4.1 第一步从日志里精确定位缺失的权限最直接、最可靠的方式是抓日志别猜。刷完机之后如果开机卡住连上设备抓 logcatadb logcat -b all -d | grep -iE privapp|not in privapp-permissions正常情况下你会看到类似这样一行关键信息Signature|privileged permissions not in privapp-permissions whitelist: {com.demo.systemapp: android.permission.WRITE_SECURE_SETTINGS, android.permission.PACKAGE_USAGE_STATS}注意这里会一次性把该包所有缺失的权限都列出来用大括号包着包名和权限之间是冒号分隔。如果只有一行日志看不到全可以用grep -A 5多带几行上下文。如果设备已经起不来了、adb 也连不上还有一条路用adb shell dumpsys package com.demo.systemapp在能开机的时候先 dump 一份留底或者直接从源码侧比对。不过在 enforce 模式下开机崩溃时dumpsys往往也调不出来所以养成刷机前先把logcat全量落盘的习惯能省下大量时间。4.2 第二步确认权限是否真的属于 privileged 类抓到了缺失权限的名字别急着往白名单里抄。先确认它到底是什么类型的权限这一步能过滤掉大量“抄了也没用”的情况。如果是 AOSP 定义的平台权限直接去源码里搜定义grep -B 2 -A 6 android.permission.WRITE_SECURE_SETTINGS \ frameworks/base/core/res/AndroidManifest.xml你会看到类似permission android:nameandroid.permission.WRITE_SECURE_SETTINGS android:protectionLevelsignature|privileged /的定义。看到privileged字样就可以放心写进白名单如果只有signature那就得走签名路线写白名单没用如果是dangerous或normal说明这个权限压根不该出现在特权场景讨论里多半是别的地方出了问题。如果权限是 OEM 自己定义的就去定义它的那个应用的 Manifest 里查。还有一种情况是权限来自framework-res.apk的编译产物手边没有源码时可以用aapt从 apk 里反查aapt dump permissions framework-res.apk | grep -i WRITE_SECURE_SETTINGS这一步的产出是一份确认过的权限清单——只有这份清单上的权限才允许出现在白名单里。我通常会把这份清单和日志里的缺失清单做个交集避免把运行时权限误加进去。4.3 第三步批量生成白名单条目手工写几条还行一旦产品线多了、预置应用多了手工维护就变成灾难。AOSP 自带了一个辅助脚本位置在development/tools/privapp_permissions/目录下它的大致思路是读取dumpsys package的输出把每个特权应用请求的权限和系统里定义的 privileged 权限做比对然后生成一份推荐的白名单 XML。具体参数各版本略有差异用之前先--help看一眼本地版本。如果手边没有这套脚本自己写一个也不难。核心逻辑就三步拿到dumpsys package的文本、提取目标包requested permissions段、与signature|privileged权限集合求交集。给个骨架import re import subprocess PRIV_RE re.compile(randroid\.permission\.[A-Z_0-9]) def dump_package(pkg): out subprocess.check_output( [adb, shell, dumpsys, package, pkg]) return out.decode(utf-8, ignore) def requested_permissions(text): # 截取 requested permissions 段直到下一个段落标题 m re.search(rrequested permissions:(.*?)\n\s*\n, text, re.S) if not m: return [] return PRIV_RE.findall(m.group(1)) def main(pkg, allowed): perms requested_permissions(dump_package(pkg)) hit sorted(set(perms) allowed) print(privapp-permissions package%s % pkg) for p in hit: print( permission name%s/ % p) print(/privapp-permissions) if __name__ __main__: # allowed 是从 AndroidManifest.xml 里提取出来的 privileged 权限集合 main(com.demo.systemapp, {android.permission.WRITE_SECURE_SETTINGS})allowed这个集合可以从frameworks/base/core/res/AndroidManifest.xml里用正则捞一遍把所有protectionLevel含privileged的权限名收集起来。脚本跑出来的结果还要人工过一遍——自动生成只能保证语法正确不能保证业务上真的需要这一点后面第 6 章会细说。4.4 第四步编译验证与快速调试手法改完 XML接下来是验证。第一轮建议走完整编译确认文件确实进了镜像source build/envsetup.sh lunch acme_device-userdebug make -j32编完之后可以直接从产物里确认文件在不在ls out/target/product/device/system/etc/permissions/ | grep privapp如果不想每次都完整编译可以走 push 验证这条路但要注意 Android 10 之后/system普遍是 system-as-root 且只读remount 之前得先关掉校验adb root adb disable-verity # 设备会要求重启一次 adb reboot adb root adb remount adb push privapp-permissions-acme.xml /system/etc/permissions/ adb reboot注意ro.control_privapp_permissions是只读属性运行时用setprop改是改不动的只会在日志里报一句只读属性不可修改。想临时切换成log模式只能改编译配置里的属性覆盖项或者 remount 之后编辑build.prop再重启。别在这上面浪费时间。push 验证的坑在于push 进去的文件属于“临时补丁”下一次刷机就没了所以验证通过之后一定要把改动落回源码不然就会出现“我本地明明是好的”这种经典事故。4.5 第五步用 dumpsys 做结果核对重启之后用dumpsys确认权限是不是真的授予了adb shell dumpsys package com.demo.systemapp | grep -A 40 requested permissions输出里会分成两块requested permissions是应用声明要的install permissions是安装时实际授予的。如果某个特权权限出现在前者但不在后者里说明白名单没生效或者权限类型判断有误如果两边都有说明这条权限已经稳稳拿到手了。我通常还会顺手确认一下应用所在的分区避免出现“明明装在/data却以为在 priv-app”的低级失误adb shell pm path com.demo.systemapp输出是/system/priv-app/DemoApp/DemoApp.apk这种形式一眼就能看出分区和目录。如果显示的是/data/app/...那么无论你怎么写白名单都不会生效因为privileged标记只在扫描系统分区时才会打上。5. 常见问题排查实录权限这块的问题有个特点现象一样原因可能完全不同。我把自己和同事踩过的坑整理成下面这几类基本覆盖了日常会碰到的九成情况。5.1 白名单写了权限还是没生效这是问得最多的一个问题。按可能性从高到低排主要查这几处第一文件名前缀不对。必须严格是privapp-permissions-开头。少个字母、多个连字符系统都不会报错直接无视。第二XML 语法有误导致整个文件解析失败。常见的是标签没闭合、属性引号不配对、编码声明缺失。解析失败同样是静默的最多在日志里留一行警告。验证方式是adb shell cat出来看看内容或者用任意 XML 校验工具先过一遍。第三权限名写错。少一个字母、大小写不一致、前后有空格都会导致匹配失败。拿grep -n精确定位别靠眼睛看。第四分区不匹配。应用在/product/priv-app权限写进了/system/etc/permissions早期版本能生效高版本上可能因为分区归属判定而失效。稳妥做法是保持分区一致。第五重复定义冲突。同一个包同一个权限在多份文件里都写了某些版本会直接判定配置非法。排查顺序建议从“文件有没有被加载”入手而不是从“权限写得对不对”入手。因为前者出错时系统几乎不给提示后者出错通常有日志。5.2 签名不匹配导致的静默失败signature|privileged和纯signature的差别前面讲过但实际项目中还是经常混。最典型的场景是应用申请了一个纯signature的权限你把它预置进priv-app并写了白名单结果install permissions里死活看不到它。这种情况下白名单不是问题所在签名才是。解决方案只有两条让应用改用平台签名或者把权限定义改成带privileged标志——但后者意味着放宽了整个平台的权限约束影响面很大一般不建议为了单个应用这么做。还有一个变种情况应用在 priv-app 分区权限也是signature|privileged白名单也写了但权限就是拿不到。这时候去看一下dumpsys package里该应用的signatures和pkgFlags确认PRIVILEGED标志到底有没有打上。如果没打上说明应用其实没被识别为特权应用多半是安装路径或者 apk 头信息有问题。5.3 覆盖升级、OTA 之后白名单丢失这个坑在定制 ROM 上特别常见。原因通常有两种一是 OTA 包只更新了应用 apk没有同步更新对应的权限 XML新版本应用新增了权限白名单还是旧的开机就崩二是产品配置里白名单模块没有被加进PRODUCT_PACKAGES只在某次手工 push 之后能跑正式出包就丢了。第一类的解法是在 OTA 打包流程里做一次校验把新旧两个版本的白名单与应用声明的权限做差分有新增特权权限就报警。第二类的解法更简单粗暴把白名单模块名写进产品配置然后编一个完整包从产物目录里ls一遍确认文件在。这件事我建议固化成出包前的检查项。5.4 常见报错与处理速查表现象 / 日志关键词可能原因处理方向not in privapp-permissions whitelist白名单缺条目补齐所需特权权限开机卡在动画日志无 privapp 字样其他模块崩溃看system_server首个异常全缓冲区抓日志定位首个崩溃点权限写进白名单但install permissions为空权限是纯signature类型检查签名或权限定义白名单文件存在但毫无效果文件名前缀不匹配核对命名规则日志出现 XML 解析警告XML 语法错误用校验工具过一遍dumpsys里没有PRIVILEGED标志应用不在特权分区pm path确认安装位置同一个包在多份文件里出现配置重复合并到单一文件只在 user 版本崩溃属性策略差异检查ro.control_privapp_permissions这张表我打印出来贴在工位上过新人上手期真的省事。里面最有价值的一行是第二行——“日志里没有 privapp 字样”本身就说明问题不在权限白名单上很多同学在权限上死磕半天最后发现是别的模块导致的system_server崩溃白白浪费一整天。6. 工程化维护与经验沉淀单次调通不难难的是几十个产品、上百个预置应用长期维护。这一章聊聊落到工程层面的做法。6.1 多产品线共用同一份白名单的坑早期图省事我们把所有产品的权限都堆在一个privapp-permissions-common.xml里。头两个月很舒服第三个月开始出问题A 产品的某个权限条目被 B 产品的同事删了因为他在自己那边验证时觉得“没用到”C 产品新增的权限被带到了 D 产品上虽然不影响启动但安全审计那边直接打回来问“为什么这个设备允许这个权限”。后来改成三层结构平台通用权限放privapp-permissions-platform.xml产品线共用权限放privapp-permissions-family.xml单个产品差异权限放privapp-permissions-product.xml产品配置里按需拼装。这样职责清楚合并冲突也少了很多。代价是文件变多、维护成本略升但比起“删了别人的权限导致别人开不了机”这点成本完全值得。6.2 权限最小化能不写就不写自动生成白名单的脚本很好用但它有个副作用会把应用声明的所有特权权限一股脑写进去包括那些历史遗留、实际上早就没用的。用过一两次之后我就改了规矩——生成的条目必须人工过一遍逐条问“这个权限删掉会怎样”。问不出答案的就带着这个疑问去代码里搜调用点。搜不到调用点的直接删掉拿去做回归测试。我印象很深的一次清理后删掉了十几个权限跑了一轮完整测试没有任何异常反而整体安全扫描的告警少了一大截。这件事的意义不只是“少写几行 XML”。权限一旦写进白名单就等于平台盖了章承认这个应用有权做这件事。多一条风险多一分。所以宁可写的时候费点劲也别让白名单变成权限垃圾桶。6.3 把校验塞进 CI 的做法手工检查靠不住得靠机器。我们在 CI 上加了三道检查成本不高但很有效第一道语法检查。用任意 XML 解析器把etc/permissions下所有文件跑一遍解析失败直接报错。这个检查能拦住绝大多数低级错误。第二道命名检查。用脚本统一扫一遍文件名不匹配privapp-permissions-*.xml的直接拦下。第三道一致性检查。把每个产品里所有priv-app应用声明的权限和白名单里实际写的权限做交叉比对输出两份清单白名单里写了但应用没声明的多余、应用声明了但白名单没写的缺失。缺失的那份单独报警多余的只提示。第三道检查依赖aapt从编译产物里读权限需要在编译完成之后跑接入 CI 时放在构建后阶段。跑一次大概几秒钟换来的是“再也不会有人因为权限问题把量产机器刷成砖”。6.4 几个我踩过的坑最后分享几个不成体系但很实在的经验。别在生产机上验证权限改动。我见过有人直接拿手头唯一的样机 push 白名单结果文件写错导致开机崩溃又没有救砖手段耽误了半天。改成在备用机或者模拟器上先验证出问题随时刷回。保留每一版白名单的变更记录。权限条目看起来不起眼但每一行背后都是一个业务需求。有次审计追溯某个权限是哪个需求引入的翻遍提交记录才找到三年前的一条提交提交信息只有“add permission”五个字白白花了两小时。理解“权限组”在运行时权限里的角色。有些同学把privapp-permissions和运行时权限的权限组概念混在一起其实两回事。权限组主要影响 UI 展示和同组自动授权行为跟特权权限白名单没有交集。特权权限根本不走用户授权流程是安装时静态授予的。想清楚这一点排查时就不会东一榔头西一棒子。遇到说不清的权限先查定义再动手。这是最省时间的一条。花两分钟去AndroidManifest.xml里确认protectionLevel比花两小时试错划算得多。写到这里其实privapp-permissions这套东西本身不复杂难的从来不是 XML 语法而是建立“权限改动必须有明确来源、必须显式确认、必须可追溯”的工作习惯。我个人的体会是凡是能在 CI 上自动化的检查就别指望人记住凡是自动化覆盖不到的判断就得在评审时多问一句“这权限删了会怎样”。这句话问多了白名单就不会失控。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →