当前位置:   article > 正文

[CM311-1A]-全网最全 Android 用户管理及用户应用权限_cm311-1a root

cm311-1a root

##################################################

目录

安卓系统用户管理

查询用户

查看用户列表

查看当前登录用户

添加用户

创建新用户

切换用户

切换账号

删除用户

删除一个账户

安卓系统用户应用权限

Android 是一个多用户系统

Android 用户机制

uid

gid

gids

查看 uid/gid/gids

应用的 appid 和 appuid

用户内部外部家目录

外部存储器 /storage/emulated/用户_UID 家目录

内部存储器 /data/user/用户_UID 家目录

Android 是如何创造出来一个虚拟的多用户运行环境的?

Android 多用户的本质

创建多用户流程解析

多用户切换流程解析

应用权限记录

安装时权限存储位置

运行时权限存储位置

权限声明存储位置

权限控制

授予/移除 权限

User ID 和 Group ID

利用 dumpsys package 从指定应用信息中获取 userid 和 gids

查看用户权限

查看应用权限

权限组详解

平台版本与 API 级别

CM311-1A 盒子 Android 9 所有已知的权限组

联系人权限组 android.permission-group.CONTACTS

电话权限组 android.permission-group.PHONE

日历权限组 android.permission-group.CALENDAR

通话记录权限组 android.permission-group.CALL_LOG

相机权限组 android.permission-group.CAMERA

身体传感器权限组 android.permission-group.SENSORS

位置信息权限组 android.permission-group.LOCATION

存储空间权限组 android.permission-group.STORAGE

系统控制权限组 androidlogic.permission-group.SYSTEM_CONTROL

麦克风权限组 android.permission-group.MICROPHONE

短信权限组 android.permission-group.SMS

CM311-1A 盒子和手机设备都没有看到 WIFI 网络相关的权限

三层 Android 权限详解

第三层 —— 系统权限以及软件安装权限真相

Android 底层映射为 Linux 权限

Android 应用程序权限机制

安装一个 APK 的详细过程

声明时权限 安全等级/protectionLevel 分类

第一层 —— 开发层 AndroidManifest.xml

AndroidManifest.xml 配置文件权限分类

AndroidManifest.xml 配置文件详解

第二层 —— 框架层 preferences.xml

示例一个 root 过的手机修改板子 sd 权限

CM311-1A 的 platform.xml 配置文件详解

platform.xml 对应的解析代码


##################################################

安卓系统用户管理

——————————

查询用户

%%%%%

查看用户列表

  1. cmcc_jiangsu:/ # pm list users
  2. Users:
  3. UserInfo{0:机主:13} running
  4. cmcc_jiangsu:/ #

%%%%%

查看当前登录用户

  1. cmcc_jiangsu:/ # whoami
  2. root
  3. cmcc_jiangsu:/ #


——————————

添加用户

        非常注意:

        多用户的创建、启动、停止等行为是系统级的

        因此只有具有 root、system 权限的进程才能操作

%%%%%

创建新用户

        语法如下:

pm create-user 用户名

        然后发现盒子竟然也不能创建用户!!!

  1. cmcc_jiangsu:/ # pm create-user "user_1"
  2. Error: couldn't create User.
  3. 1|cmcc_jiangsu:/ #

        无奈只好换上旧手机:

  1. C:\Users\byme>adb devices /* USB 插上之后查看连接状态 */
  2. List of devices attached
  3. 8OOXXOOXXxxooxxF device
  4. C:\Users\byme>adb root /* 看来无法获得 root 权限 */
  5. adbd cannot run as root in production builds
  6. C:\Users\byme>adb shell
  7. shell@GIONEE_G1605A:/ $ pm list users /* 查看用户列表 */
  8. Users:
  9. UserInfo{0:机主:13} running
  10. shell@GIONEE_G1605A:/ $ whoami /* 查看登陆账户 */
  11. shell
  12. shell@GIONEE_G1605A:/ $ pm create-user "ranchui" /* 创建用户燃吹 */
  13. Success: created user id 10
  14. 1|shell@GIONEE_G1605A:/ $ pm list users /* 用户 UID 是 10 */
  15. Users:
  16. UserInfo{0:机主:13} running
  17. UserInfo{10:ranchui:0}
  18. shell@GIONEE_G1605A:/ $

        如果之前创建多了也没关系 删除多余的用户之后重启手机 UID 就会重新计算:

  1. shell@GIONEE_G1605A:/ $ pm create-user "user"
  2. Success: created user id 10
  3. 1|shell@GIONEE_G1605A:/ $ pm list users
  4. Users:
  5. UserInfo{0:机主:13} running
  6. UserInfo{10:user:0}
  7. shell@GIONEE_G1605A:/ $


——————————

切换用户

%%%%%

切换账号

        启动和切换用户语法如下:

  1. am start-user USER_ID /* 启用一个账户 */
  2. am switch-user USER_ID /* 切换到指定账户 */

        启动指定用户:

  1. shell@GIONEE_G1605A:/ $ pm list users /* 当前 ranchui 未上线 */
  2. Users:
  3. UserInfo{0:机主:13} running
  4. UserInfo{10:ranchui:0}
  5. shell@GIONEE_G1605A:/ $ am start-user 10 /* 根据 UID 启用用户 ranchui */
  6. Success: user started
  7. shell@GIONEE_G1605A:/ $ pm list users /* 用户 ranchui 已经在线 */
  8. Users:
  9. UserInfo{0:机主:13} running
  10. UserInfo{10:ranchui:10} running
  11. shell@GIONEE_G1605A:/ $

        切换成指定用户:

  1. shell@GIONEE_G1605A:/ $ am switch-user 10 /* 切换成 ranchui 用户 */
  2. shell@GIONEE_G1605A:/ $

        正在切换用户:

正在切换用户

        然后就发现无法调试了:

  1. shell@GIONEE_G1605A:/ $ /* 这边莫名退出去了 */
  2. C:\Users\byme>adb shell /* 查看连接还在 但是不支持调试 */
  3. adb.exe: device unauthorized.
  4. This adb server's $ADB_VENDOR_KEYS is not set
  5. Try 'adb kill-server' if that seems wrong.
  6. Otherwise check for a confirmation dialog on your device.
  7. C:\Users\byme>adb kill-server /* 关掉一次 adb */
  8. C:\Users\byme>adb devices /* 发现不是 device 是个未经授权的 unauthorized */
  9. * daemon not running; starting now at tcp:5037
  10. * daemon started successfully
  11. List of devices attached
  12. 8ooxxOOOXXXooxxF unauthorized
  13. C:\Users\byme>

        然后手机竟然开始首次登陆配置:

首次登陆配置

首次登陆配置

首次登陆配置

        这个新建立的用户确确实实不允许 USB 调试:

不允许 USB 调试

        无奈 只好重启手机之后默认登陆主账户再次开启调试功能:

  1. C:\Users\byme>adb devices /* 此时还未授权 */
  2. List of devices attached
  3. 8ooxxOOOXXXooxxF unauthorized
  4. C:\Users\byme>adb devices /* 授权过后 */
  5. List of devices attached
  6. 8ooxxOOOXXXooxxF device
  7. C:\Users\byme>


——————————

删除用户

%%%%%

删除一个账户

        语法如下:

pm remove-user USER_ID

        示例删除刚刚创建的 ranchui 用户:

  1. C:\Users\byme>adb shell
  2. shell@GIONEE_G1605A:/ $ pm list users /* 查看用户列表 */
  3. Users:
  4. UserInfo{0:机主:13} running
  5. UserInfo{10:ranchui:10}
  6. shell@GIONEE_G1605A:/ $ pm remove-user 10 /* 根据 UID 删除用户 */
  7. Success: removed user
  8. shell@GIONEE_G1605A:/ $ pm list users /* 再次查看用户列表 */
  9. Users:
  10. UserInfo{0:机主:13} running
  11. shell@GIONEE_G1605A:/ $ am start-user 10 /* 因为没有该账户所以报错 */
  12. Error: could not start user
  13. shell@GIONEE_G1605A:/ $ am switch-user 10 /* 没有该账户所以屏幕也没切换过去 */
  14. shell@GIONEE_G1605A:/ $

##################################################

安卓系统用户应用权限

——————————

Android 是一个多用户系统

        Android 4.0 开始 Google 就开始在 Android 上布局多用户
        UserManager 由此诞生 然而此时尚未对应的 Binder 服务 真正支持多用户是从 Android 4.2 开始
        即使如此系统中也依然存在各类 Bug 和兼容性问题

        直到 Android 6.0 多用户才比较完善

        国内外的厂家也纷纷开始针对多用户这个噱头来作各类 花里胡哨 的操作

手机分身

分身应用

应用双开

        等等等等 不得不说 国内的厂家在多用户这方面定制化到现在已经很是稳定和完善了

——————————

Android 用户机制

        对于 Android 中的每一个进程都有一个单独的 uid、gid 以及 gids 集合
        经过这三者 Android 系统实现了一套文件和数据访问权限规则系统

        例如 访问某个文件 文件系统规定了该文件在磁盘中的 rwx 权限

%%%%%

uid

        UID 是用户 id

        在 Linux 上一个用户 uid 标识着一个给定的用户 而 Android 上也沿用了 Linux 用户的概念

root 用户 uid 为 0
system Uid 为 1000

  1. Android 在创建每个用户时 都会分配一个整型的 userId
  2. 对于主用户 就是正常下的默认用户 来说 userId 为 0
  3. 之后创建的 userId 将从 10 开始计算 每增加一个用户 userId 就会加 1

        而且每一个应用程序在安装时也被赋予了单独的 uid
        这个 uid 将伴随着应用从安装到卸载包括缓存

%%%%%

gid

        GID 是用户组 id

Linux 上规定每一个应用都应该有一个用户组
对于 Android 应用程序来讲每一个应用的所属用户组与 uid 相同

%%%%%

gids

        GIDS 是应用在安装后所得到权限的 id 集合

在 Android 上每一个权限均可能对应一个或多个 group 而每一个 group 都有一个 gid name
所以 gids 就是经过对每一个 gid name 计算得出的 id 集合

    一个 uid 能够关联 gids 代表该 uid 拥有多种权限

%%%%%

查看 uid/gid/gids


        获取 system_server 的 PID 然后根据这个 PID 查看 UID/GID/Groups :

  1. cmcc_jiangsu:/ # ps -A | grep system_server /* 得到 PID 为 3620 */
  2. system 3620 2604 1386312 181192 SyS_epoll_wait 0 S system_server
  3. cmcc_jiangsu:/ # cat /proc/3620/status /* 查看该进程的 status */
  4. Name: system_server
  5. Umask: 0077
  6. State: S (sleeping)
  7. Tgid: 3620
  8. Ngid: 0
  9. Pid: 3620
  10. PPid: 2604
  11. TracerPid: 0
  12. Uid: 1000 1000 1000 1000
  13. Gid: 1000 1000 1000 1000
  14. FDSize: 512
  15. Groups: 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1018 1021 1023 1024 10
  16. 32 1065 3001 3002 3003 3006 3007 3009 3010
  17. VmPeak: 1419816 kB
  18. VmSize: 1386312 kB
  19. VmLck: 0 kB
  20. VmPin: 0 kB
  21. VmHWM: 206464 kB
  22. VmRSS: 181088 kB
  23. RssAnon: 15028 kB
  24. RssFile: 165708 kB
  25. RssShmem: 352 kB
  26. VmData: 1018244 kB
  27. VmStk: 8192 kB
  28. VmExe: 24 kB
  29. VmLib: 80572 kB
  30. VmPTE: 524 kB
  31. VmPMD: 0 kB
  32. VmSwap: 0 kB
  33. Threads: 97
  34. SigQ: 0/10948
  35. SigPnd: 0000000000000000
  36. ShdPnd: 0000000000000000
  37. SigBlk: 0000000000001204
  38. SigIgn: 0000000000000001
  39. SigCgt: 00000006400084f8
  40. CapInh: 0000001806897c20
  41. CapPrm: 0000001806897c20
  42. CapEff: 0000001806897c20
  43. CapBnd: 0000000000000000
  44. CapAmb: 0000000000000000
  45. Seccomp: 0
  46. Speculation_Store_Bypass: unknown
  47. Cpus_allowed: f
  48. Cpus_allowed_list: 0-3
  49. Mems_allowed: 1
  50. Mems_allowed_list: 0
  51. voluntary_ctxt_switches: 2526
  52. nonvoluntary_ctxt_switches: 1818
  53. cmcc_jiangsu:/ #

——————————

应用的 appid 和 appuid

        在 Android 中应用的 uid 是和当前的用户有关的

    同一个应用具有相同的 appId

        其 uid 的计算方式为:

appUid = userId * 1000000 + appId

        在主用户中 uid 就等于 appId

——————————

用户内部外部家目录

        为了多用户下的数据安全性

        在每个新用户创建之初不管是 外部存储器/External Storage 还是 app data 目录

         Android 都为其准备了独立的文件存储

        新用户创建时 Android 在

/storage/emulated

/data/user

        目录下为每个用户都创建了名为用户 id 的家目录

%%%%%

外部存储器 /storage/emulated/用户_UID 家目录

        目录 /storage/emulated/ 下拥有不同的用户分区

        当我们在代码中使用

Environment.getExternalStorageDirectory().absolutePath

        获取外部存储路径时返回的就是当前用户下的对应目录

        例如 userId = 11 则返回为

/storage/emulated/11

        多用户下的 /storage 分区有不同的用户家目录

        可以看出常用的 /sdcard 目录其实最终也是软链到了 /storage/emulated/0 目录:

  1. cmcc_jiangsu:/ # ls -l /storage/emulated/
  2. total 8
  3. drwxrwx--x 32 root sdcard_rw 4096 2022-07-25 11:35 0
  4. drwxrwx--x 2 root sdcard_rw 4096 2015-01-01 08:00 obb
  5. cmcc_jiangsu:/ # ls -l /sdcard
  6. lrwxrwxrwx 1 root root 21 1970-01-01 08:00 /sdcard -> /storage/self/primary
  7. cmcc_jiangsu:/ # ls -l /storage/self/primary
  8. lrwxrwxrwx 1 root root 19 2015-01-01 08:00 /storage/self/primary -> /mnt/user/0/primary
  9. cmcc_jiangsu:/ # ls -l /mnt/user/0/primary
  10. lrwxrwxrwx 1 root reserved_disk 19 2015-01-01 08:00 /mnt/user/0/primary -> /storage/emulated/0
  11. cmcc_jiangsu:/ #

%%%%%

内部存储器 /data/user/用户_UID 家目录

        多用户下的 /data 分区也有不同用户的家目录

        也是以用户 UID 命名

        与 External Storage/外部存储器 相同
        新用户创建时 Android 也会在 /data/user 目录下创建名为 userId 的目录
        用于存储该用户中所有 App 的隐私数据

    如果在代码中使用 Context.getFilesDir() 来获取应用的 data 目录不同 User 下也会有不同

        也可以看出来平常说到的 /data/data 目录其实也是软链到了 /data/user/0

  1. cmcc_jiangsu:/ # ls /data/user -alh
  2. total 6.0K
  3. drwx--x--x 2 system system 4.0K 2015-01-01 08:00 .
  4. drwxrwx--x 40 system system 4.0K 2015-01-01 08:00 ..
  5. lrwxrwxrwx 1 root root 10 2015-01-01 08:00 0 -> /data/data
  6. cmcc_jiangsu:/ # ls -l /data/user/0/
  7. android.ext.services/ com.android.sharedstoragebackup/
  8. android.ext.shared/ com.android.shell/
  9. android/ com.android.statementservice/
  10. com.android.backupconfirm/ com.android.superuser/
  11. com.android.bluetooth/ com.android.systemui/
  12. com.android.certinstaller/ com.android.vpndialogs/
  13. com.android.companiondevicemanager/ com.android.webview/
  14. com.android.defcontainer/ com.cmcc.mid.softdetector/
  15. com.android.externalstorage/ com.dangbei.tvlauncher/
  16. com.android.inputdevices/ com.dangbeimarket/
  17. com.android.inputmethod.latin/ com.droidlogic.BluetoothRemote/
  18. com.android.keychain/ com.droidlogic.inputmethod.remote/
  19. com.android.location.fused/ com.droidlogic/
  20. com.android.managedprovisioning/ com.fengyun.live/
  21. com.android.packageinstaller/ com.iflytek.bt.auto/
  22. com.android.pacprocessor/ com.iflytek.xiri/
  23. com.android.providers.downloads/ com.iflytek.xiri2.system/
  24. com.android.providers.media/ com.mylejia.store/
  25. com.android.providers.settings/ com.tv.kuaisou/
  26. com.android.proxyhandler/ com.xiaodianshi.tv.yst/
  27. com.android.se/ jackpal.androidterm/
  28. com.android.settings/ me.thomastv.rebootupdate/
  29. cmcc_jiangsu:/ # ls -lh /data/user/0/com.android.shell/
  30. total 4.0K
  31. drwxrws--x 2 shell shell 4.0K 2015-01-01 08:00 cache
  32. drwxrws--x 2 shell shell 4.0K 2015-01-01 08:00 code_cache
  33. cmcc_jiangsu:/ #

——————————

Android 是如何创造出来一个虚拟的多用户运行环境的?

%%%%%

Android 多用户的本质

        多用户其实是系统为应用的 data 目录和 storage 目录分配了一份不同且独立的存储空间

        不同用户下的存储空间互不影响且没有权限访问

        /storage 目录不可以跨用户访问
例如用户 10 的 app 是无法访问 /storage/emulated/0 下的文件的
        是不可以互相访问的

        同时系统中的 AMS、PMS、WMS 等各大服务都会针对 userId/UserHandle 进行多用户适配

        并在用户启动、切换、停止、删除等生命周期时做出相应策略的改变

%%%%%

创建多用户流程解析

        多用户的创建流程主要在

UserManagerService.createUserInternalUnchecked()

        函数中完成

        用户创建的过程主要是应用运行环境例如文件系统、权限等的准备过程

        主要可以分为六个步骤

        第一步 为新用户创建一个新的 userId

        新用户的 userId 从 10 开始递增

        第二步 固化新用户信息和创建状态

        构造包含新用户信息的 UserData 并固化到 /data/system/users/${userId}.xml 中:

  1. cmcc_jiangsu:/ # cat /data/system/users/0.xml
  2. <?xml version='1.0' encoding='utf-8' standalone='yes' ?>
  3. <user id="0" serialNumber="0" flags="19" created="0" lastLoggedIn="1420070414617
  4. " lastLoggedInFingerprint="CM311-1a-YST/CM311-1a-YST/CM311-1a-YST:9/PPR1.180610.
  5. 011/V.955.05:userdebug/test-keys" profileBadge="0">
  6. <restrictions />
  7. </user>
  8. cmcc_jiangsu:/ #

        将新创建新 userId 固化到 /data/system/users/userlist.xml 中:

  1. cmcc_jiangsu:/ # cat /data/system/users/userlist.xml
  2. <?xml version='1.0' encoding='utf-8' standalone='yes' ?>
  3. <users nextSerialNumber="10" version="7">
  4. <guestRestrictions>
  5. <restrictions no_sms="true" no_install_unknown_sources="true" no_config_
  6. wifi="true" no_outgoing_calls="true" />
  7. </guestRestrictions>
  8. <deviceOwnerUserId id="-10000" />
  9. <user id="0" />
  10. </users>
  11. cmcc_jiangsu:/ #

        第三步 准备文件系统

        通过 vold 这个 Android 存储守护进程为新用户进行文件系统加密
        创建 /data/system/users/${userId} 并设置 0700 权限

  1. cmcc_jiangsu:/ # ls -alh /data/system/users/
  2. total 10K
  3. drwxrwxr-x 3 system system 4.0K 2015-01-01 08:00 .
  4. drwxrwxr-x 19 system system 4.0K 2022-07-27 19:29 ..
  5. drwx------ 2 system system 4.0K 2022-07-27 19:20 0
  6. -rw------- 1 system system 298 2015-01-01 08:00 0.xml
  7. -rw------- 1 system system 335 2015-01-01 08:00 userlist.xml
  8. cmcc_jiangsu:/ #

        创建 /data/misc/users/${userId} 并设置 0750 权限

  1. cmcc_jiangsu:/ # ls /data/misc/user/ -alh
  2. total 6.0K
  3. drwxrwx--x 3 root root 4.0K 2015-01-01 08:00 .
  4. drwxrwx--t 43 system misc 4.0K 2015-01-01 08:00 ..
  5. drwxr-x--- 2 system everybody 4.0K 2015-01-01 08:00 0
  6. cmcc_jiangsu:/ #

        第四步 为已安装应用准备数据目录并记录其组件和默认权限配置

        在 /data/user/${userId}/ 下创建各个已安装应用的 package 目录

  1. cmcc_jiangsu:/ # ls /data/user/0/
  2. android com.android.sharedstoragebackup
  3. android.ext.services com.android.shell
  4. android.ext.shared com.android.statementservice
  5. com.android.backupconfirm com.android.superuser
  6. com.android.bluetooth com.android.systemui
  7. com.android.certinstaller com.android.vpndialogs
  8. com.android.companiondevicemanager com.android.webview
  9. com.android.defcontainer com.cmcc.mid.softdetector
  10. com.android.externalstorage com.dangbei.tvlauncher
  11. com.android.inputdevices com.dangbeimarket
  12. com.android.inputmethod.latin com.droidlogic
  13. com.android.keychain com.droidlogic.BluetoothRemote
  14. com.android.location.fused com.droidlogic.inputmethod.remote
  15. com.android.managedprovisioning com.fengyun.live
  16. com.android.packageinstaller com.iflytek.bt.auto
  17. com.android.pacprocessor com.iflytek.xiri
  18. com.android.providers.downloads com.iflytek.xiri2.system
  19. com.android.providers.media com.mylejia.store
  20. com.android.providers.settings com.tv.kuaisou
  21. com.android.proxyhandler com.xiaodianshi.tv.yst
  22. com.android.se jackpal.androidterm
  23. com.android.settings me.thomastv.rebootupdate
  24. cmcc_jiangsu:/ #

        在 /data/system/users/${userId}/package-restrictions.xml 中写入非默认启动组件的信息

  1. cmcc_jiangsu:/ # cat /data/system/users/0/package-restrictions.xml
  2. <?xml version='1.0' encoding='utf-8' standalone='yes' ?>
  3. <package-restrictions>
  4. <pkg name="com.iflytek.xiri" ceDataInode="-4294967186" />
  5. <pkg name="com.droidlogic.inputmethod.remote" ceDataInode="-4294967182" />
  6. <pkg name="com.xiaodianshi.tv.yst" ceDataInode="-4294966764" />
  7. <pkg name="com.android.providers.media" ceDataInode="-4294967179" />
  8. <pkg name="com.mylejia.store" ceDataInode="-4294966914" stopped="true" nl="t
  9. rue" />
  10. <pkg name="com.android.externalstorage" ceDataInode="-4294967176" />
  11. <pkg name="com.android.companiondevicemanager" ceDataInode="-4294967173" />
  12. <pkg name="com.android.providers.downloads" ceDataInode="-4294967170" />
  13. <pkg name="com.fengyun.live" ceDataInode="-4294966943" stopped="true" nl="tr
  14. ue" />
  15. <pkg name="com.droidlogic" ceDataInode="-4294967167" />
  16. <pkg name="com.dangbei.tvlauncher" ceDataInode="-4294967163" />
  17. <pkg name="com.android.defcontainer" ceDataInode="-4294967266" />
  18. <pkg name="com.android.pacprocessor" ceDataInode="-4294967160" />
  19. <pkg name="com.android.certinstaller" ceDataInode="-4294967156" />
  20. <pkg name="me.thomastv.rebootupdate" ceDataInode="-4294966923" />
  21. <pkg name="android" ceDataInode="-4294967258" />
  22. <pkg name="com.android.backupconfirm" ceDataInode="-4294967153" />
  23. <pkg name="com.android.statementservice" ceDataInode="-4294967150" />
  24. <pkg name="com.android.superuser" ceDataInode="-4294967147" />
  25. <pkg name="com.android.providers.settings" ceDataInode="-4294967250" />
  26. <pkg name="com.android.sharedstoragebackup" ceDataInode="-4294967144" />
  27. <pkg name="com.iflytek.xiri2.system" ceDataInode="-4294967141" />
  28. <pkg name="com.android.webview" ceDataInode="-4294967137" enabled="1" />
  29. <pkg name="com.android.se" ceDataInode="-4294967133" />
  30. <pkg name="com.android.inputdevices" ceDataInode="-4294967242" />
  31. <pkg name="com.droidlogic.BluetoothRemote" ceDataInode="-4294967128" />
  32. <pkg name="android.ext.shared" ceDataInode="-4294967235" />
  33. <pkg name="com.android.keychain" ceDataInode="-4294967123" />
  34. <pkg name="android.ext.services" ceDataInode="-4294967229" />
  35. <pkg name="com.android.packageinstaller" ceDataInode="-4294967223" />
  36. <pkg name="com.android.proxyhandler" ceDataInode="-4294967217" />
  37. <pkg name="com.android.inputmethod.latin" ceDataInode="-4294967210">
  38. <disabled-components>
  39. <item name="com.android.inputmethod.latin.setup.SetupActivity" />
  40. </disabled-components>
  41. </pkg>
  42. <pkg name="com.android.managedprovisioning" ceDataInode="-4294967118" />
  43. <pkg name="jackpal.androidterm" ceDataInode="-4294966708" />
  44. <pkg name="com.iflytek.bt.auto" ceDataInode="-4294967115" />
  45. <pkg name="com.android.settings" ceDataInode="-4294967112" />
  46. <pkg name="com.android.vpndialogs" ceDataInode="-4294967108" />
  47. <pkg name="com.android.shell" ceDataInode="-4294967203" />
  48. <pkg name="com.dangbeimarket" ceDataInode="-4294966928" />
  49. <pkg name="com.android.location.fused" ceDataInode="-4294967196" />
  50. <pkg name="com.android.systemui" ceDataInode="-4294967189">
  51. <disabled-components>
  52. <item name="com.android.systemui.tuner.TunerActivity" />
  53. </disabled-components>
  54. </pkg>
  55. <pkg name="com.tv.kuaisou" ceDataInode="-4294966800" stopped="true" nl="true
  56. " />
  57. <pkg name="com.android.bluetooth" ceDataInode="-4294967104" enabled="1" />
  58. <pkg name="com.cmcc.mid.softdetector" ceDataInode="-4294967100" />
  59. <preferred-activities />
  60. <persistent-preferred-activities />
  61. <crossProfile-intent-filters />
  62. <default-apps />
  63. </package-restrictions>
  64. cmcc_jiangsu:/ #

        更新 /data/system/packages.list 文件主要是最后一串 gids 可能会改变

  1. cmcc_jiangsu:/ # cat /data/system/packages.list
  2. com.iflytek.xiri 10021 0 /data/user/0/com.iflytek.xiri default:targetSdkVersion=19 3002,3003,3001
  3. com.droidlogic.inputmethod.remote 10022 0 /data/user/0/com.droidlogic.inputmethod.remote default:targetSdkVersion=28 none
  4. com.xiaodianshi.tv.yst 10032 0 /data/user_de/0/com.xiaodianshi.tv.yst default:targetSdkVersion=26 3003
  5. com.android.providers.media 10002 0 /data/user/0/com.android.providers.media media:privapp:targetSdkVersion=28 2001,1065,1023,1015,3003,3007,1024
  6. com.mylejia.store 10026 0 /data/user_de/0/com.mylejia.store default:targetSdkVersion=24 3003,1007
  7. com.android.externalstorage 10004 0 /data/user/0/com.android.externalstorage platform:privapp:targetSdkVersion=28 1023,1015
  8. com.android.companiondevicemanager 10012 0 /data/user/0/com.android.companiondevicemanager default:targetSdkVersion=28 3002,3001
  9. com.android.providers.downloads 10002 0 /data/user/0/com.android.providers.downloads media:privapp:targetSdkVersion=28 2001,1065,1023,1015,3003,3007,1024
  10. com.fengyun.live 10027 0 /data/user_de/0/com.fengyun.live default:targetSdkVersion=24 3003
  11. com.droidlogic 1000 0 /data/user/0/com.droidlogic platform:privapp:targetSdkVersion=28 1065,3002,1023,1015,3003,3001,1007
  12. com.dangbei.tvlauncher 10016 0 /data/user/0/com.dangbei.tvlauncher default:targetSdkVersion=22 3002,3003,3001
  13. com.android.defcontainer 10000 0 /data/user_de/0/com.android.defcontainer platform:privapp:targetSdkVersion=28 2001
  14. com.android.pacprocessor 10017 0 /data/user/0/com.android.pacprocessor platform:targetSdkVersion=28 3003
  15. com.android.certinstaller 10013 0 /data/user/0/com.android.certinstaller platform:targetSdkVersion=28 none
  16. me.thomastv.rebootupdate 10024 0 /data/user_de/0/me.thomastv.rebootupdate default:targetSdkVersion=25 none
  17. android 1000 0 /data/system platform:privapp:targetSdkVersion=28 1065,3002,1023,1015,3003,3001,1007
  18. com.android.backupconfirm 10001 0 /data/user/0/com.android.backupconfirm platform:privapp:targetSdkVersion=28 none
  19. com.android.statementservice 10009 0 /data/user/0/com.android.statementservice default:privapp:targetSdkVersion=28 3003
  20. com.android.superuser 10019 1 /data/user/0/com.android.superuser default:targetSdkVersion=22 none
  21. com.android.providers.settings 1000 0 /data/user_de/0/com.android.providers.settings platform:privapp:targetSdkVersion=28 1065,3002,1023,1015,3003,3001,1007
  22. com.android.sharedstoragebackup 10007 0 /data/user/0/com.android.sharedstoragebackup platform:privapp:targetSdkVersion=28 1023,1015
  23. com.iflytek.xiri2.system 1000 0 /data/user/0/com.iflytek.xiri2.system platform:privapp:targetSdkVersion=28 1065,3002,1023,1015,3003,3001,1007
  24. com.android.webview 10023 0 /data/user/0/com.android.webview default:targetSdkVersion=28 3003
  25. com.android.se 1068 0 /data/user/0/com.android.se platform:privapp:targetSdkVersion=28 none
  26. com.android.inputdevices 1000 0 /data/user_de/0/com.android.inputdevices platform:privapp:targetSdkVersion=28 1065,3002,1023,1015,3003,3001,1007
  27. com.droidlogic.BluetoothRemote 1000 0 /data/user/0/com.droidlogic.BluetoothRemote platform:privapp:targetSdkVersion=28 1065,3002,1023,1015,3003,3001,1007
  28. android.ext.shared 10015 0 /data/user_de/0/android.ext.shared platform:targetSdkVersion=28 none
  29. com.android.keychain 1000 0 /data/user/0/com.android.keychain platform:privapp:targetSdkVersion=28 1065,3002,1023,1015,3003,3001,1007
  30. android.ext.services 10003 0 /data/user_de/0/android.ext.services platform:privapp:targetSdkVersion=28 none
  31. com.android.packageinstaller 10008 0 /data/user_de/0/com.android.packageinstaller platform:privapp:targetSdkVersion=28 1065
  32. com.android.proxyhandler 10006 0 /data/user_de/0/com.android.proxyhandler platform:privapp:targetSdkVersion=28 3003
  33. com.android.inputmethod.latin 10020 0 /data/user_de/0/com.android.inputmethod.latin default:targetSdkVersion=23 none
  34. com.android.managedprovisioning 10005 0 /data/user/0/com.android.managedprovisioning platform:privapp:targetSdkVersion=28 3003
  35. jackpal.androidterm 10031 0 /data/user_de/0/jackpal.androidterm default:targetSdkVersion=22 3003
  36. com.iflytek.bt.auto 10014 0 /data/user/0/com.iflytek.bt.auto default:targetSdkVersion=28 3002,3001
  37. com.android.settings 1000 1 /data/user/0/com.android.settings platform:privapp:targetSdkVersion=28 1065,3002,1023,1015,3003,3001,1007
  38. com.android.vpndialogs 10010 0 /data/user/0/com.android.vpndialogs platform:privapp:targetSdkVersion=28 none
  39. com.android.shell 2000 0 /data/user_de/0/com.android.shell platform:privapp:targetSdkVersion=28 1065,3002,1023,1015,1002,3010,3011
  40. com.dangbeimarket 10025 0 /data/user_de/0/com.dangbeimarket default:targetSdkVersion=19 3002,3003,3001
  41. com.android.location.fused 1000 0 /data/user_de/0/com.android.location.fused platform:privapp:targetSdkVersion=28 1065,3002,1023,1015,3003,3001,1007
  42. com.android.systemui 10011 0 /data/user_de/0/com.android.systemui platform:privapp:targetSdkVersion=28 1065,3002,1023,1015,3001,3006
  43. com.tv.kuaisou 10028 0 /data/user_de/0/com.tv.kuaisou default:targetSdkVersion=22 3002,3003,3001
  44. com.android.bluetooth 1002 0 /data/user_de/0/com.android.bluetooth platform:privapp:targetSdkVersion=28 3002,3003,3001,3007,1002,3010,3011,3005,1016
  45. com.cmcc.mid.softdetector 10018 0 /data/user/0/com.cmcc.mid.softdetector default:targetSdkVersion=17 3003
  46. cmcc_jiangsu:/ #

        这个改变的可能性是根据 permUser 的配置来决定

        第五步 固化新用户创建完成的状态、通知 PMS 为新用户和应用赋予默认的权限

        第六步 发送 ACTION_USER_ADDED 广播 新用户创建完成

%%%%%

多用户切换流程解析


        Android 多用户的切换函数入口是

ActivityManagerService.switchUser()

        AMS 的 startUser 方法只是判断了是否展示切换用户的 Dialog
        最终都会调用到 UserController.startUser 这个函数中
        方法很长 涉及到 AMS 和 WMS 的方法分支也很多

        切换分为前台切换和后台切换 这里从前台切换 并且对用户未启动的情况总结下关键的切换过程

        第一步 切换前冻结屏幕 禁止一切输入操作

这个过程在屏幕旋转的过程中也会执行 因此截取屏幕并展示也是采用和横竖屏切换一样的方式

        冻结输入事件
        强制结束 App 动画
        截取当前屏幕并显示

        如果是待启动用户 则初始化待启动用户的状态为 STATE_BOOTING

        第二步 为待切换用户更改系统配置 设置 Keyguard

从 SettingsProvider 读取待切换用户的字体、语言、地区等配置并更新到系统

        如果是初创用户 则字体使用默认配置 语言和地区使用当前用户的配置

为待切换用户更新资源 如 Attributes、Drawable、Color、Animator、StateList 等

        有兴趣可以重点看下 AMS 的 updateGlobalConfiguration()

        修改当前用户下所有 Window 的可见性 启动 Keyguard 切换过程中关闭 Keyguard 的指纹监听 并设置锁屏

            在 Android 8.0 以前 Keyguard 是一个单独的 System App
        8.0 后将其移至 SystemUI 中 该模块的功能主要有 展示和隐藏锁屏界面 认证和校验锁屏密码、指纹密码 等

        如果是待启动用户 为待启动用户设置权限 校验或准备待启动用户的 App 存储目录
        通知系统所有服务新用户正在启动 如 JobSchedulerService 会根据 Job 对应的用户是否启动来决定 Job 的维护

        第三步 并行通知系统所有服务用户开始切换

        系统所有服务及相关监听者在收到开始切换的消息后进行一系列的操作

        也是用户切换所要完成的核心任务

        所有系统服务及相关监听者完成切换任务后 执行 UserController.continueUserSwitch()

        第四步 设置切换超时定时器

        设置 3s 的延迟消息

        如果 3s 内没有完成用户切换 则取消该消息 终止切换过程并执行 UserController.continueUserSwitch()

        第五步 将待切换用户拉到前台

        stop 当前用户下所有的 Activity

        修改所有 ActivityStack 中 TaskRecord 的顺序 将切换用户或者在两个用户中都能运行的 Task 移动到栈顶

        将最顶端 Task 对应的 Window 移动到最顶端

        取出切换应用之前存在的前台 Activity 置于前台并 resume 如果没有前台应用 则启动 HomeActivity

        发送用户切换广播

        如果是后台切换 则发送 ACTION_USER_BACKGROUND
        如果是前台切换 则发送 ACTION_USER_FOREGROUND 和 ACTION_USER_SWITCHED

        第六步 切换超时消息到达时需要继续进行的切换操作

  1. 设置切换超时定时器
  2. 将待切换用户拉到前台
  3. 中切换超时消息到达时需要继续进行的切换操作 continueUserSwitch

        解冻屏幕和输入


        设置 Keyguard 如果切换用户设置了指纹 则需要开始监听指纹信息

        通知监听者用户已经完成了切换

        第七步 完成切换用户

        如果是后台切换

        则直接调用 UserController.finishUserBoot()

        如果是前台切换

        ActivityThread 会在 handleResumeActivity 时设置 Main 线程 MessageQueue 的 mIdleHandlers

        在 MessageQueue 执行 next() 会检查该列表并最终调用到 AMS 的 activityIdle() 中

        此时会检查正在切换的用户列表并调用最终调用到 UserController.finishUserBoot()

        设置切换用户的状态为 STATE_RUNNING_LOCKED

  1. 如果是新启动的用户,则通知系统所有用户监听者用户已经启动
  2. 并发送 ACTION_LOCKED_BOOT_COMPLETED 广播
  3. 在 Keyguard 第一次解锁时 会发送 ACTION_BOOT_COMPLETED 广播

——————————

应用权限记录

%%%%%

安装时权限存储位置

        安装 APP 时权限的获取记录存储在

/data/system/packages.xml

  1. cmcc_jiangsu:/ # cat /data/system/packages.xml | grep xiaodianshi /* 查看关于 bilibili tv 的权限 */
  2. <item name="com.xiaodianshi.tv.yst.permission.BLKV" package="com.xiaodia
  3. nshi.tv.yst" protection="2" />
  4. <package name="com.xiaodianshi.tv.yst" codePath="/data/app/com.xiaodianshi.t
  5. v.yst-Gq1cdiX3Aho20N4EPrC5gw==" nativeLibraryPath="/data/app/com.xiaodianshi.tv.
  6. yst-Gq1cdiX3Aho20N4EPrC5gw==/lib" primaryCpuAbi="armeabi-v7a" publicFlags="94530
  7. 7204" privateFlags="0" ft="1822bb3ec60" it="1822bb3f274" ut="1822bb3f274" versio
  8. n="105100" userId="10030">
  9. <item name="com.xiaodianshi.tv.yst.permission.BLKV" granted="true" f
  10. lags="0" />
  11. cmcc_jiangsu:/ # cat /data/system/packages.xml | grep jackpal.androidterm
  12. <item name="jackpal.androidterm.permission.PREPEND_TO_PATH" package="jac
  13. kpal.androidterm" protection="1" />
  14. <item name="jackpal.androidterm.permission.RUN_SCRIPT" package="jackpal.
  15. androidterm" protection="1" />
  16. <item name="jackpal.androidterm.permission.APPEND_TO_PATH" package="jack
  17. pal.androidterm" protection="1" />
  18. <package name="jackpal.androidterm" codePath="/data/app/jackpal.androidterm-
  19. sAgHElvcbHuZtUuQdCSIdQ==" nativeLibraryPath="/data/app/jackpal.androidterm-sAgHE
  20. lvcbHuZtUuQdCSIdQ==/lib" primaryCpuAbi="armeabi" publicFlags="940097092" private
  21. Flags="0" ft="1822bc31730" it="1822bc31983" ut="1822bc31983" version="71" userId
  22. ="10031">
  23. cmcc_jiangsu:/ # pm list packages -3 /* 查看第三方应用 */
  24. package:com.xiaodianshi.tv.yst
  25. package:com.mylejia.store
  26. package:com.fengyun.live
  27. package:me.thomastv.rebootupdate
  28. package:jackpal.androidterm
  29. package:com.dangbeimarket
  30. package:com.tv.kuaisou
  31. cmcc_jiangsu:/ # cat /data/system/packages.xml | grep com.dangbeimarket /* 查看当贝市场权限 */
  32. <item name="baidu.push.permission.WRITE_PUSHINFOPROVIDER.com.dangbeimark
  33. et" package="com.dangbeimarket" protection="2" />
  34. <item name="com.dangbeimarket.permission.JPUSH_MESSAGE" package="com.dan
  35. gbeimarket" protection="2" />
  36. <item name="com.dangbeimarket.permission.MIPUSH_RECEIVE" package="com.da
  37. ngbeimarket" protection="2" />
  38. <package name="com.dangbeimarket" codePath="/data/app/com.dangbeimarket-Gvch
  39. ZCDlwKegHBtoXBQhwg==" nativeLibraryPath="/data/app/com.dangbeimarket-GvchZCDlwKe
  40. gHBtoXBQhwg==/lib" primaryCpuAbi="armeabi-v7a" publicFlags="945307204" privateFl
  41. ags="0" ft="14aa2cb6b80" it="14aa2cb6f96" ut="14aa2cb6f96" version="286" userId=
  42. "10025">
  43. <item name="baidu.push.permission.WRITE_PUSHINFOPROVIDER.com.dangbei
  44. market" granted="true" flags="0" />
  45. <item name="com.dangbeimarket.permission.JPUSH_MESSAGE" granted="tru
  46. e" flags="0" />
  47. <item name="com.dangbeimarket.permission.MIPUSH_RECEIVE" granted="tr
  48. ue" flags="0" />
  49. cmcc_jiangsu:/ #

%%%%%

运行时权限存储位置

        运行时权限的获取记录存储在

/data/system/users/$userId/runtime-permissions.xml

  1. cmcc_jiangsu:/ # cat /data/system/users/0/runtime-permissions.xml
  2. <?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
  3. <runtime-permissions fingerprint="CM311-1a-YST/CM311-1a-YST/CM311-1a-YST:9/PPR1.180610.011/V.955.05:userdebug/test-keys" />
  4. cmcc_jiangsu:/ #

%%%%%

权限声明存储位置

        Android 系统和应用安装后的权限声明保存在

/etc/permissions/

        目录下:

  1. cmcc_jiangsu:/ # ls /etc/permissions/
  2. android.hardware.bluetooth.xml com.android.media.remotedisplay.xml
  3. android.hardware.bluetooth_le.xml com.android.mediadrm.signer.xml
  4. android.hardware.hdmi.cec.xml platform.xml
  5. android.software.webview.xml privapp-permissions-platform.xml
  6. com.android.location.provider.xml
  7. cmcc_jiangsu:/ #

        如果要查看最常使用的 platform 权限可以:

cat /etc/permissions/platform.xml | more

        可以简单看一下这个配置文件 每个我们常见的权限都可能对应一个或多个 group gid

        而我们上面说的 gids 就是由这个 group gid 生成的集合

——————————

权限控制

%%%%%

授予/移除 权限

        语法如下:

  1. pm grant 包名 权限 /* 授予权限 */
  2. pm revoke 包名 权限 /* 移除权限*/

        示例为终端模拟器添加删除写文件权限:

  1. cmcc_jiangsu:/ # pm grant jackpal.androidterm android.permission.WRITE_EXTERNAL_STORAGE
  2. cmcc_jiangsu:/ # pm revoke jackpal.androidterm android.permission.WRITE_EXTERNAL_STORAGE
  3. cmcc_jiangsu:/ #

        其她常用权限:

  1. android.permission.CAMERA /* 相机权限 */
  2. android.permission.READ_EXTERNAL_STORAGE /* 读文件权限 */
  3. android.permission.WRITE_EXTERNAL_STORAGE /* 写文件权限 */

%%%%%

User ID 和 Group ID

        Android 系统上每一个独立的应用运行在不同的系统空间
        以 User ID 和 Group ID 来标识
        不同应用之间互相访问数据接口资源就牵涉到权限问题

        关于用户 ID

  1. 我们在安装一个应用的时候系统就会为这个应用分配一个 userid
  2. 这个 userid 是全局唯一的
  3. 在同一 Android 系统的机器上不可能存在两个相同 userid 的应用
  4. 也就是说 userid 对于一个应用来说是唯一不变的 除非你卸载重新安装了该应用
  5. 但是 userid 并不像 MAC 地址一样是全球唯一的 同一个应用在不同的设备上 userid 可能会不同
  6. 这里所说的唯一是指在同一个 Android 设备上
  7. Android 的安全机制是进程级别的
  8. 通常情况下一个应用就是一个进程
  9. 并且一个应用也只有一个进程
  10. 当然应用内实现多进程这个是没有任何问题的
  11. 这里是说一般情况下
  12. 应用 A 是无法直接运行在应用 B 的进程当中的
  13. 但是有一点就是除非应用 A 和应用 B 使用了相同的 shareduserid
  14. 配置了相同的 shareduserid 的应用被系统视作同一个应用 对应的 userid 和权限都是相同的
  15. 但是如果仅仅是配置了相同的 shareduserid 就能够到达目的 显然这是一个很大的漏洞
  16. 为此谷歌做了另外一个限制 就是必须保证签名一致
  17. 一般的 A 公司的签名肯定是跟 B 公司的签名是不一样的
  18. 也就是说想要应用 A 和应用 B 运行在同一个进程当中那么肯定得保证签名和 shareduserid 是一致的
  19. shareduserid 保持一致这个很容易满足 但是签名一致恐怕只能是同一个公司
  20. 应用的数据和 user id 是相对应的 默认情况下其她应用是无法访问的
  21. 但是如果我们设置了 MODE_WORLD_READABLE 或者 MODE_WORLD_WRITEABLE 的 flag
  22. 那么其她应用就可以变得可读可写了 也就是说这些数据就变成了全局的数据
  23. 我们知道 Android 系统从 4.2 版本开始支持多用户
  24. 也就产生了用户 id 的概念 uid
  25. 在这里 uid 和 userid 是两个完全不同的概念
  26. android 中的用户是存在物理文件级数据差异的
  27. 例如有两个用户 用户 id 分别是 0 和 10
  28. 用户 10 安装了应用 A 此时对于用户 0 来说是完全不可见的
  29. 不像两个应用 A 和 B 两者的数据虽然默认情况下是不能互相访问的 但是我们有办法能够实现

        那么用户 id 到底是什么:

简单的说用户 id 就是当前用户下为了各个应用之间数据共享和访问的

        在 Android 系统中有些常用的 userid 是提前定义好的

        例如 system 的用户 id 就是 1000 这个是在代码中提前定义好的

%%%%%

利用 dumpsys package 从指定应用信息中获取 userid 和 gids

        示例使用 dumpsys package 命令获取 终端模拟器 这个应用的所有信息:

  1. cmcc_jiangsu:/ # dumpsys package jackpal.androidterm
  2. Activity Resolver Table:
  3. Full MIME Types:
  4. */*:
  5. 6eb5070 jackpal.androidterm/.TermHere filter 85f0431
  6. Action: "android.intent.action.SEND"
  7. Category: "android.intent.category.DEFAULT"
  8. Type: "*"
  9. mPriority=0, mOrder=0, mHasPartialTypes=true
  10. b538fe9 jackpal.androidterm/.shortcuts.FSNavigator filter e12d733
  11. Action: "android.intent.action.GET_CONTENT"
  12. Category: "android.intent.category.DEFAULT"
  13. Category: "android.intent.category.OPENABLE"
  14. Type: "*"
  15. mPriority=0, mOrder=0, mHasPartialTypes=true
  16. Wild MIME Types:
  17. *:
  18. 6eb5070 jackpal.androidterm/.TermHere filter 85f0431
  19. Action: "android.intent.action.SEND"
  20. Category: "android.intent.category.DEFAULT"
  21. Type: "*"
  22. mPriority=0, mOrder=0, mHasPartialTypes=true
  23. b538fe9 jackpal.androidterm/.shortcuts.FSNavigator filter e12d733
  24. Action: "android.intent.action.GET_CONTENT"
  25. Category: "android.intent.category.DEFAULT"
  26. Category: "android.intent.category.OPENABLE"
  27. Type: "*"
  28. mPriority=0, mOrder=0, mHasPartialTypes=true
  29. Non-Data Actions:
  30. jackpal.androidterm.RUN_SHORTCUT:
  31. 3602f82 jackpal.androidterm/.RunShortcut filter 45c4897
  32. Action: "jackpal.androidterm.RUN_SHORTCUT"
  33. Category: "android.intent.category.DEFAULT"
  34. jackpal.androidterm.private.SWITCH_WINDOW:
  35. 65c1ce jackpal.androidterm/.TermInternal filter 2d8abbb
  36. Action: "jackpal.androidterm.private.SWITCH_WINDOW"
  37. Category: "android.intent.category.DEFAULT"
  38. jackpal.androidterm.OPEN_NEW_WINDOW:
  39. d877d32 jackpal.androidterm/.RemoteInterface filter 83648d8
  40. Action: "jackpal.androidterm.OPEN_NEW_WINDOW"
  41. Category: "android.intent.category.DEFAULT"
  42. android.intent.action.MAIN:
  43. 6ee9b65 jackpal.androidterm/.Term filter 8b301b5
  44. Action: "android.intent.action.MAIN"
  45. Category: "android.intent.category.LAUNCHER"
  46. Category: "android.intent.category.MULTIWINDOW_LAUNCHER"
  47. c0f203a jackpal.androidterm/.shortcuts.AddShortcut filter 5331a84
  48. Action: "android.intent.action.MAIN"
  49. android.intent.action.PICK:
  50. b538fe9 jackpal.androidterm/.shortcuts.FSNavigator filter 34d5ea2
  51. Action: "android.intent.action.PICK"
  52. Category: "android.intent.category.DEFAULT"
  53. jackpal.androidterm.RUN_SCRIPT:
  54. c6dd21d jackpal.androidterm/.RunScript filter 2a1e716
  55. Action: "jackpal.androidterm.RUN_SCRIPT"
  56. Category: "android.intent.category.DEFAULT"
  57. jackpal.androidterm.private.OPEN_NEW_WINDOW:
  58. 65c1ce jackpal.androidterm/.TermInternal filter 5bb104a
  59. Action: "jackpal.androidterm.private.OPEN_NEW_WINDOW"
  60. Category: "android.intent.category.DEFAULT"
  61. android.intent.action.CREATE_SHORTCUT:
  62. c0f203a jackpal.androidterm/.shortcuts.AddShortcut filter eeeb26d
  63. Action: "android.intent.action.CREATE_SHORTCUT"
  64. MIME Typed Actions:
  65. android.intent.action.SEND:
  66. 6eb5070 jackpal.androidterm/.TermHere filter 85f0431
  67. Action: "android.intent.action.SEND"
  68. Category: "android.intent.category.DEFAULT"
  69. Type: "*"
  70. mPriority=0, mOrder=0, mHasPartialTypes=true
  71. android.intent.action.GET_CONTENT:
  72. b538fe9 jackpal.androidterm/.shortcuts.FSNavigator filter e12d733
  73. Action: "android.intent.action.GET_CONTENT"
  74. Category: "android.intent.category.DEFAULT"
  75. Category: "android.intent.category.OPENABLE"
  76. Type: "*"
  77. mPriority=0, mOrder=0, mHasPartialTypes=true
  78. Service Resolver Table:
  79. Non-Data Actions:
  80. jackpal.androidterm.action.START_TERM.v1:
  81. 3f40e99 jackpal.androidterm/.TermService filter f7579ec
  82. Action: "jackpal.androidterm.action.START_TERM.v1"
  83. Category: "android.intent.category.DEFAULT"
  84. Permissions:
  85. Permission [jackpal.androidterm.permission.PREPEND_TO_PATH] (40775e5):
  86. sourcePackage=jackpal.androidterm
  87. uid=10031 gids=null type=0 prot=dangerous
  88. perm=Permission{13728ba jackpal.androidterm.permission.PREPEND_TO_PATH}
  89. packageSetting=PackageSetting{cc1336b jackpal.androidterm/10031}
  90. Permissions:
  91. Permission [jackpal.androidterm.permission.RUN_SCRIPT] (9ec705e):
  92. sourcePackage=jackpal.androidterm
  93. uid=10031 gids=null type=0 prot=dangerous
  94. perm=Permission{a9cac3f jackpal.androidterm.permission.RUN_SCRIPT}
  95. packageSetting=PackageSetting{cc1336b jackpal.androidterm/10031}
  96. Permissions:
  97. Permission [jackpal.androidterm.permission.APPEND_TO_PATH] (13fd63a):
  98. sourcePackage=jackpal.androidterm
  99. uid=10031 gids=null type=0 prot=dangerous
  100. perm=Permission{65012eb jackpal.androidterm.permission.APPEND_TO_PATH}
  101. packageSetting=PackageSetting{cc1336b jackpal.androidterm/10031}
  102. Key Set Manager:
  103. [jackpal.androidterm]
  104. Signing KeySets: 17
  105. Packages:
  106. Package [jackpal.androidterm] (cc1336b):
  107. userId=10031
  108. pkg=Package{ab23cd9 jackpal.androidterm}
  109. codePath=/data/app/jackpal.androidterm-sAgHElvcbHuZtUuQdCSIdQ==
  110. resourcePath=/data/app/jackpal.androidterm-sAgHElvcbHuZtUuQdCSIdQ==
  111. legacyNativeLibraryDir=/data/app/jackpal.androidterm-sAgHElvcbHuZtUuQdCSIdQ=
  112. =/lib
  113. primaryCpuAbi=armeabi
  114. secondaryCpuAbi=null
  115. versionCode=71 minSdk=4 targetSdk=22
  116. versionName=1.0.70
  117. splits=[base]
  118. apkSigningVersion=1
  119. applicationInfo=ApplicationInfo{544369e jackpal.androidterm}
  120. flags=[ HAS_CODE ALLOW_CLEAR_USER_DATA ALLOW_BACKUP ]
  121. privateFlags=[ DEFAULT_TO_DEVICE_PROTECTED_STORAGE DIRECT_BOOT_AWARE ]
  122. dataDir=/data/user_de/0/jackpal.androidterm
  123. supportsScreens=[small, medium, large, xlarge, resizeable, anyDensity]
  124. usesLibraries:
  125. org.apache.http.legacy
  126. usesLibraryFiles:
  127. /system/framework/org.apache.http.legacy.boot.jar
  128. timeStamp=2022-07-23 23:53:02
  129. firstInstallTime=2022-07-23 23:53:02
  130. lastUpdateTime=2022-07-23 23:53:02
  131. signatures=PackageSignatures{2e3957f version:1, signatures:[e7b54ff0], past
  132. signatures:[]}
  133. installPermissionsFixed=true
  134. pkgFlags=[ HAS_CODE ALLOW_CLEAR_USER_DATA ALLOW_BACKUP ]
  135. declared permissions:
  136. jackpal.androidterm.permission.RUN_SCRIPT: prot=dangerous, INSTALLED
  137. jackpal.androidterm.permission.APPEND_TO_PATH: prot=dangerous, INSTALLED
  138. jackpal.androidterm.permission.PREPEND_TO_PATH: prot=dangerous, INSTALLED
  139. requested permissions:
  140. android.permission.INTERNET
  141. android.permission.READ_EXTERNAL_STORAGE
  142. android.permission.WRITE_EXTERNAL_STORAGE
  143. android.permission.ACCESS_SUPERUSER
  144. android.permission.WAKE_LOCK
  145. install permissions:
  146. android.permission.INTERNET: granted=true
  147. android.permission.READ_EXTERNAL_STORAGE: granted=true
  148. android.permission.WRITE_EXTERNAL_STORAGE: granted=true
  149. android.permission.WAKE_LOCK: granted=true
  150. User 0: ceDataInode=-4294966708 installed=true hidden=false suspended=false
  151. stopped=false notLaunched=false enabled=0 instant=false virtual=false
  152. gids=[3003]
  153. runtime permissions:
  154. Package Changes:
  155. Sequence number=0
  156. Dexopt state:
  157. [jackpal.androidterm]
  158. path: /data/app/jackpal.androidterm-sAgHElvcbHuZtUuQdCSIdQ==/base.apk
  159. arm: [status=speed-profile] [reason=install]
  160. Compiler stats:
  161. [jackpal.androidterm]
  162. (No recorded stats)
  163. cmcc_jiangsu:/ #

        获取 userid 可以使用 dumpsys package 搭配 grep 筛选 userId 和 gids:

  1. cmcc_jiangsu:/ # dumpsys package jackpal.androidterm | grep userId
  2. userId=10031
  3. cmcc_jiangsu:/ # dumpsys package jackpal.androidterm | grep gids
  4. uid=10031 gids=null type=0 prot=dangerous
  5. uid=10031 gids=null type=0 prot=dangerous
  6. uid=10031 gids=null type=0 prot=dangerous
  7. gids=[3003]
  8. cmcc_jiangsu:/ #

%%%%%

查看用户权限


        不同用户具有的权限不同

        使用 dumpsys user 命令可以查看所有的用户信息 例如 userId、name、restrictions 等等:

  1. cmcc_jiangsu:/ # dumpsys user
  2. Users:
  3. UserInfo{0:null:13} serialNo=0
  4. State: RUNNING_UNLOCKED
  5. Created: <unknown>
  6. Last logged in: +2762d4h27m19s3ms ago
  7. Last logged in fingerprint: CM311-1a-YST/CM311-1a-YST/CM311-1a-YST:9/PPR1.18
  8. 0610.011/V.955.05:userdebug/test-keys
  9. Start time: +1h8m33s992ms ago
  10. Unlock time: +1h8m33s812ms ago
  11. Has profile owner: false
  12. Restrictions:
  13. none
  14. Device policy global restrictions:
  15. null
  16. Device policy local restrictions:
  17. null
  18. Effective restrictions:
  19. none
  20. Device owner id:-10000
  21. Guest restrictions:
  22. no_sms
  23. no_install_unknown_sources
  24. no_config_wifi
  25. no_outgoing_calls
  26. Device managed: false
  27. Started users state: {0=3}
  28. Max users: 1
  29. Supports switchable users: false
  30. All guests ephemeral: false
  31. cmcc_jiangsu:/ #

        解释一下 访客用户/Guest 的默认权限限制:

  1. Guest restrictions: /* 来宾账户限制 */
  2. no_sms /* 限制发送短信 */
  3. no_install_unknown_sources /* 限制安装软件 */
  4. no_config_wifi /* 限制配置 WiFi */
  5. no_outgoing_calls /* 限制拨打电话 */

        这些权限可以在创建用户时规定也可以后期由系统动态设置

            特殊权限的用户:

  1. 用户 uid
  2. system 1000
  3. radio 1001

%%%%%

查看应用权限

        不同用户下的 App 应用权限也是独立的

        上面说了 uid 与 userId 存在一种计算关系

appUid = userId * 1000000 + appId

        而在系统中对于权限控制也是根据 uid 和对应的 userId 来判定的

        因此不同用户下相同应用可以具有不同的权限

        查看所有已知的权限组和单独权限组的权限:

  1. cmcc_jiangsu:/ # pm list permission-groups /* 查看所有已知的权限组 */
  2. permission group:android.permission-group.CONTACTS
  3. permission group:android.permission-group.PHONE
  4. permission group:android.permission-group.CALENDAR
  5. permission group:android.permission-group.CALL_LOG
  6. permission group:android.permission-group.CAMERA
  7. permission group:android.permission-group.SENSORS
  8. permission group:android.permission-group.LOCATION
  9. permission group:android.permission-group.STORAGE
  10. permission group:droidlogic.permission-group.SYSTEM_CONTROL
  11. permission group:android.permission-group.MICROPHONE
  12. permission group:android.permission-group.SMS
  13. cmcc_jiangsu:/ # pm list permissions android.permission-group.CONTACTS /* 查看单独的权限组都有什么权限 */
  14. All Permissions:
  15. permission:android.permission.WRITE_CONTACTS
  16. permission:android.permission.GET_ACCOUNTS
  17. permission:android.permission.READ_CONTACTS
  18. cmcc_jiangsu:/ # pm list permissions android.permission-group.PHONE
  19. All Permissions:
  20. permission:android.permission.ACCESS_UCE_OPTIONS_SERVICE
  21. permission:android.permission.ANSWER_PHONE_CALLS
  22. permission:android.permission.READ_PHONE_NUMBERS
  23. permission:android.permission.READ_PHONE_STATE
  24. permission:android.permission.CALL_PHONE
  25. permission:android.permission.ACCESS_UCE_PRESENCE_SERVICE
  26. permission:android.permission.ACCEPT_HANDOVER
  27. permission:android.permission.USE_SIP
  28. permission:com.android.voicemail.permission.ADD_VOICEMAIL
  29. cmcc_jiangsu:/ # pm list permissions android.permission-group.CALENDAR
  30. All Permissions:
  31. permission:android.permission.READ_CALENDAR
  32. permission:android.permission.WRITE_CALENDAR
  33. cmcc_jiangsu:/ # pm list permissions android.permission-group.CALL_LOG
  34. All Permissions:
  35. permission:android.permission.READ_CALL_LOG
  36. permission:android.permission.WRITE_CALL_LOG
  37. permission:android.permission.PROCESS_OUTGOING_CALLS
  38. cmcc_jiangsu:/ # pm list permissions android.permission-group.CAMERA
  39. All Permissions:
  40. permission:android.permission.CAMERA
  41. cmcc_jiangsu:/ # pm list permissions android.permission-group.SENSORS
  42. All Permissions:
  43. permission:android.permission.BODY_SENSORS
  44. permission:android.permission.USE_FINGERPRINT
  45. permission:android.permission.USE_BIOMETRIC
  46. cmcc_jiangsu:/ # pm list permissions android.permission-group.LOCATION
  47. All Permissions:
  48. permission:android.permission.ACCESS_FINE_LOCATION
  49. permission:android.permission.ACCESS_COARSE_LOCATION
  50. cmcc_jiangsu:/ # pm list permissions android.permission-group.STORAGE
  51. All Permissions:
  52. permission:android.permission.READ_EXTERNAL_STORAGE
  53. permission:android.permission.WRITE_EXTERNAL_STORAGE
  54. cmcc_jiangsu:/ # pm list permissions droidlogic.permission-group.SYSTEM_CONTROL
  55. All Permissions:
  56. permission:droidlogic.permission.SYSTEM_CONTROL
  57. cmcc_jiangsu:/ # pm list permissions android.permission-group.MICROPHONE
  58. All Permissions:
  59. permission:android.permission.RECORD_AUDIO
  60. cmcc_jiangsu:/ # pm list permissions android.permission-group.SMS
  61. All Permissions:
  62. permission:android.permission.READ_SMS
  63. permission:android.permission.RECEIVE_WAP_PUSH
  64. permission:android.permission.RECEIVE_MMS
  65. permission:android.permission.RECEIVE_SMS
  66. permission:android.permission.SEND_SMS
  67. permission:android.permission.READ_CELL_BROADCASTS
  68. cmcc_jiangsu:/ #

        permissions 的参数可以组合使用:

  1. -g 按组进行列出权限
  2. -f 打印所有信息
  3. -s 简短的摘要
  4. -d 只有危险的权限列表
  5. -u 只有权限的用户将看到列表 用户自定义权限

        例如:

pm list permissions -g -d 权限组

        示例:

  1. cmcc_jiangsu:/ # pm list permissions -g -d android.permission-group.CONTACTS
  2. Dangerous Permissions:
  3. group:android.permission-group.CONTACTS
  4. permission:android.permission.WRITE_CONTACTS
  5. permission:android.permission.GET_ACCOUNTS
  6. permission:android.permission.READ_CONTACTS
  7. group:android.permission-group.PHONE
  8. permission:android.permission.ANSWER_PHONE_CALLS
  9. permission:android.permission.READ_PHONE_NUMBERS
  10. permission:android.permission.READ_PHONE_STATE
  11. permission:android.permission.CALL_PHONE
  12. permission:android.permission.ACCEPT_HANDOVER
  13. permission:android.permission.USE_SIP
  14. permission:com.android.voicemail.permission.ADD_VOICEMAIL
  15. group:android.permission-group.CALENDAR
  16. permission:android.permission.READ_CALENDAR
  17. permission:android.permission.WRITE_CALENDAR
  18. group:android.permission-group.CALL_LOG
  19. permission:android.permission.READ_CALL_LOG
  20. permission:android.permission.WRITE_CALL_LOG
  21. permission:android.permission.PROCESS_OUTGOING_CALLS
  22. group:android.permission-group.CAMERA
  23. permission:android.permission.CAMERA
  24. group:android.permission-group.SENSORS
  25. permission:android.permission.BODY_SENSORS
  26. group:android.permission-group.LOCATION
  27. permission:android.permission.ACCESS_FINE_LOCATION
  28. permission:android.permission.ACCESS_COARSE_LOCATION
  29. group:android.permission-group.STORAGE
  30. permission:android.permission.READ_EXTERNAL_STORAGE
  31. permission:android.permission.WRITE_EXTERNAL_STORAGE
  32. group:droidlogic.permission-group.SYSTEM_CONTROL
  33. group:android.permission-group.MICROPHONE
  34. permission:android.permission.RECORD_AUDIO
  35. group:android.permission-group.SMS
  36. permission:android.permission.READ_SMS
  37. permission:android.permission.RECEIVE_WAP_PUSH
  38. permission:android.permission.RECEIVE_MMS
  39. permission:android.permission.RECEIVE_SMS
  40. permission:android.permission.SEND_SMS
  41. permission:android.permission.READ_CELL_BROADCASTS
  42. ungrouped:
  43. cmcc_jiangsu:/ #

        再或者查看描述:

  1. cmcc_jiangsu:/ # pm list permissions -s
  2. All Permissions:
  3. 通讯录: 修改您的通讯录, 查找设备上的帐号, 读取联系人
  4. 电话: null, 接听来电, 读取电话号码, 读取手机状态和身份, 拨打电话, null, null, 拨
  5. 打/接听SIP电话, 添加语音邮件
  6. 日历: 读取日历活动和详情, 添加或修改日历活动,并在所有者不知情的情况下向邀请对象
  7. 发送电子邮件
  8. 通话记录: 读取通话记录, 新建/修改/删除通话记录, 重新设置外拨电话的路径
  9. 相机: 拍摄照片和视频
  10. 身体传感器: 访问身体传感器(如心率监测器), 使用指纹硬件, 使用生物特征硬件
  11. 位置信息: 访问确切位置信息(以 GPS 和网络为依据), 访问大致位置信息(以网络为依
  12. 据)
  13. 存储空间: 读取您的USB存储设备中的内容, 修改或删除您的USB存储设备中的内容
  14. droidlogic权限组: droidlogic 系统控制权限
  15. 麦克风: 录音
  16. 短信: 读取短信, 接收讯息 (WAP), 接收讯息(彩信), 接收讯息(短信), 发送短信, 读
  17. 取小区广播消息
  18. ungrouped:
  19. null, null, null, null, null, null, null, 修改系统设置, null, null, null, null,
  20. null, 建立或中断 WiMAX 网络连接, null, null, null, null, null, null, null, null,
  21. 关闭其他应用, null, null, null, null, null, null, null, null, 更改您的音频设置,
  22. null, null, null, null, “勿扰”模式使用权限, null, null, null, null, null, nul
  23. l, null, null, null, null, null, null, null, null, null, null, null, null, 此应
  24. 用可显示在其他应用上方, null, 绑定到运营商服务, null, null, null, null, null, nu
  25. ll, null, null, null, null, 将蓝牙设备列入访问权限白名单。, null, null, null, nu
  26. ll, null, null, 控制近距离通信, null, null, null, null, null, null, null, null,
  27. null, null, 发送下载通知。, null, null, null, null, null, 更改网络连接性, null,
  28. null, 运行前台服务, 让应用始终运行, null, 启用和停用同步, null, 在后台使用数据,
  29. null, null, null, null, 开机启动, null, null, null, null, null, null, 设置时区,
  30. null, null, null, 展开/收拢状态栏, 卸载快捷方式, 管理个人资料和设备所有者, 请求
  31. 忽略电池优化, null, null, 与蓝牙设备配对, null, 允许接收WLAN多播, null, null, nu
  32. ll, 设置闹钟, null, null, null, null, null, null, null, null, 检索正在运行的应用
  33. , null, null, null, null, null, 拥有完全的网络访问权限, null, null, 发射红外线,
  34. null, 对正在运行的应用重新排序, null, null, null, 在后台运行, 访问蓝牙设置, null
  35. , null, null, null, null, null, null, null, null, null, null, null, null, null,
  36. null, null, null, null, null, null, null, 计算应用存储空间, null, null, null, nu
  37. ll, null, null, null, null, 访问所有系统下载内容, null, null, null, null, null,
  38. null, null, null, null, null, null, null, null, null, null, null, null, null, nu
  39. ll, null, null, null, null, null, null, null, null, null, null, null, null, 获取
  40. 额外的位置信息提供程序命令, null, null, null, 使用即时通讯通话服务, null, 访问下
  41. 载管理器。, 发送持久广播, null, null, null, null, null, null, null, null, null,
  42. null, null, null, null, null, null, null, null, null, null, null, null, 连接WLAN
  43. 网络和断开连接, null, null, 读取安装会话, null, null, null, null, null, null, nu
  44. ll, null, null, 使用下载管理器。, null, null, null, null, null, null, null, null
  45. , null, null, null, null, null, 查看网络连接, null, null, null, 停用屏幕锁定, nu
  46. ll, null, null, null, null, null, null, null, null, null, 设置壁纸, null, null,
  47. 在后台使用数据, null, null, null, null, null, null, null, null, null, null, null
  48. , null, null, null, null, null, 关闭其他应用, null, null, null, null, null, null
  49. , null, null, null, null, null, 读取同步统计信息, 通过系统转接来电, null, null,
  50. null, null, 保留下载缓存中的空间, null, null, null, null, null, 请求删除文件包,
  51. null, null, null, null, null, null, null, null, null, null, null, null, null, nu
  52. ll, null, null, null, null, null, null, null, null, null, null, null, null, null
  53. , null, 调整您的壁纸大小, null, 读取同步设置, null, null, null, null, 在后台运行
  54. , null, null, null, null, null, null, null, 控制振动, null, null, null, null, nu
  55. ll, null, null, null, null, null, null, null, null, null, null, null, null, null
  56. , null, null, null, null, null, null, null, null, null, null, null, null, null,
  57. 查看WLAN连接, null, null, null, null, null, 更改 WiMAX 状态, null, null, 请求安
  58. 装文件包, null, null, null, null, null, 安装快捷方式, null, null, null, null, nu
  59. ll, null, null, null, null, 防止手机休眠, null, 高级下载管理器功能。, null, null
  60. , null, null, null, null, null, null, null, null, null, null, null
  61. cmcc_jiangsu:/ #

        更简短的:

  1. cmcc_jiangsu:/ # pm list permissions -g -d -s android.permission-group.CONTACTS
  2. Dangerous Permissions:
  3. 通讯录: 修改您的通讯录, 查找设备上的帐号, 读取联系人
  4. 电话: 接听来电, 读取电话号码, 读取手机状态和身份, 拨打电话, null, 拨打/接听SIP电
  5. 话, 添加语音邮件
  6. 日历: 读取日历活动和详情, 添加或修改日历活动,并在所有者不知情的情况下向邀请对象
  7. 发送电子邮件
  8. 通话记录: 读取通话记录, 新建/修改/删除通话记录, 重新设置外拨电话的路径
  9. 相机: 拍摄照片和视频
  10. 身体传感器: 访问身体传感器(如心率监测器)
  11. 位置信息: 访问确切位置信息(以 GPS 和网络为依据), 访问大致位置信息(以网络为依
  12. 据)
  13. 存储空间: 读取您的USB存储设备中的内容, 修改或删除您的USB存储设备中的内容
  14. droidlogic权限组: droidlogic 系统控制权限
  15. 麦克风: 录音
  16. 短信: 读取短信, 接收讯息 (WAP), 接收讯息(彩信), 接收讯息(短信), 发送短信, 读
  17. 取小区广播消息
  18. ungrouped:
  19. cmcc_jiangsu:/ #

——————————

权限组详解

%%%%%

平台版本与 API 级别

  1. 平台版本 版本名称 API 级别 版本代码
  2. Android 1.0 无 1 BASE
  3. Android 1.1 无 2 BASE_1_1
  4. Android 1.5 Cupcake 纸杯蛋糕 3 CUPCAKE
  5. Android 1.6 Donut 甜甜圈 4 DONUT
  6. Android 2.0 Eclair 闪电泡芙 5 ECLAIR
  7. Android 2.0.1 Eclair 闪电泡芙 6 ECLAIR_0_1
  8. Android 2.1.x Eclair 闪电泡芙 7 ECLAIR_MR1
  9. Android 2.2.x Froyo 冻酸奶 8 FROYO
  10. Android 2.3/2.3.1/2.3.2 Gingerbread 姜饼 9 GINGERBREAD
  11. Android 2.3.3/2.3.4 Gingerbread 姜饼 10 GINGERBREAD_MR1
  12. Android 3.0.x Honeycomb 蜂巢 11 HONEYCOMB
  13. Android 3.1.x Honeycomb 蜂巢 12 HONEYCOMB_MR1
  14. Android 3.2 Honeycomb 蜂巢 13 HONEYCOMB_MR2
  15. Android 4.0/4.0.1/4.0.2 Ice Cream Sandwich 冰淇凌三明治 14 ICE_CREAM_SANDWICH
  16. Android 4.0.3/4.0.4 Ice Cream Sandwich 冰淇凌三明治 15 ICE_CREAM_SANDWICH_MR1
  17. Android 4.1/4.1.1 Jelly Bean 糖豆 16 JELLY_BEAN
  18. Android 4.2/4.2.2 Jelly Bean 糖豆 17 JELLY_BEAN_MR2
  19. Android 4.3 Jelly Bean 糖豆 18 JELLY_BEAN_MR3
  20. Android 4.4 KitKat 奇巧巧克力棒 19 KITKAT
  21. Android 4.4W KitKat 奇巧巧克力棒 20 KITKAT_WATCH
  22. Android 5.0 Lollipop 棒棒糖 21 LOLLIPOP
  23. Android 5.1 Lollipop 棒棒糖 22 LOLLIPOP_MR1
  24. Android 6.0 Marshmallow 棉花糖 23 M
  25. Android 7.0 Nougat 牛轧糖 24 N
  26. Android 7.1 Nougat 牛轧糖 25 N_MR1
  27. Android 8.0 Oreo 奥利奥 26 O
  28. Android 8.1 Oreo 奥利奥 27 O_MR1
  29. Android 9.0 Pie 馅饼 28 P
  30. Android 10.0 Android 10 29 Q
  31. Android 11 Android 11 R R

%%%%%

CM311-1A 盒子 Android 9 所有已知的权限组

  1. android.permission-group.CONTACTS /* 联系人权限组 */
  2. 通讯录: 修改您的通讯录, 查找设备上的帐号, 读取联系人
  3. android.permission-group.PHONE /* 电话权限组 */
  4. 电话: 接听来电, 读取电话号码, 读取手机状态和身份, 拨打电话, null, 拨打/接听SIP电
  5. 话, 添加语音邮件
  6. android.permission-group.CALENDAR /* 日历权限组组 */
  7. 日历: 读取日历活动和详情, 添加或修改日历活动,并在所有者不知情的情况下向邀请对象
  8. 发送电子邮件
  9. android.permission-group.CALL_LOG /* 呼叫功能的权限组 */
  10. 通话记录: 读取通话记录, 新建/修改/删除通话记录, 重新设置外拨电话的路径
  11. android.permission-group.CAMERA /* 相机权限组 */
  12. 相机: 拍摄照片和视频
  13. android.permission-group.SENSORS /* 身体传感器权限组 */
  14. 身体传感器: 访问身体传感器(如心率监测器)
  15. android.permission-group.LOCATION /* 位置权限组 */
  16. 位置信息: 访问确切位置信息(以 GPS 和网络为依据), 访问大致位置信息(以网络为依
  17. 据)
  18. android.permission-group.STORAGE /* 外部存储权限组 */
  19. 存储空间: 读取您的USB存储设备中的内容, 修改或删除您的USB存储设备中的内容
  20. droidlogic.permission-group.SYSTEM_CONTROL /* 系统控制权限组 */
  21. droidlogic权限组: droidlogic 系统控制权限
  22. android.permission-group.MICROPHONE /* 麦克风权限组 */
  23. 麦克风: 录音
  24. android.permission-group.SMS /* 短信权限组 */
  25. 短信: 读取短信, 接收讯息 (WAP), 接收讯息(彩信), 接收讯息(短信), 发送短信, 读
  26. 取小区广播消息

%%%%%

联系人权限组 android.permission-group.CONTACTS

android.permission-group.CONTACTS    /* 联系人权限组_API 级别 23_联系人和配置文件相关的运行时权限 */

  1. android.permission.WRITE_CONTACTS /* 写入联系人权限 允许应用写入用户联系人数据_保护等级 危险_API 级别 1 */
  2. android.permission.GET_ACCOUNTS /* 访问谷歌账户权限 国内用不了…… 该权限意味着是否允许访问帐户服务中的帐户列表_保护等级 危险_API 级别 1 */
  3. android.permission.READ_CONTACTS /* 读取联系人权限 允许应用读取用户联系人数据_保护等级 危险_API 级别 1 */

%%%%%

电话权限组 android.permission-group.PHONE

android.permission-group.PHONE    /* 电话权限组_API 级别 23_电话功能相关的权限 */

  1. android.permission.ACCESS_UCE_OPTIONS_SERVICE /* 允许应用访问 UCE-OPTIONS 权限_保护等级 为 签名|专用 */
  2. android.permission.ANSWER_PHONE_CALLS /* 允许应用接听来电权限_保护等级为 危险_API 级别 26 */
  3. android.permission.READ_PHONE_NUMBERS /* 允许应用读取设备的电话号码权限_保护等级为 危险_API 级别 26 */
  4. android.permission.READ_PHONE_STATE /* 读取手机状态权限 就是允许应用访问电话状态_保护等级为 危险_API 级别 1 */
  5. android.permission.CALL_PHONE /* 允许应用在不经过拨号界面的情况下启动电话呼叫以便用户确认呼叫权限_保护等级为 危险_API 级别 1 */
  6. android.permission.ACCESS_UCE_PRESENCE_SERVICE /* 允许应用访问 UCE-Presence 权限_保护等级 为 签名|专用 */
  7. android.permission.ACCEPT_HANDOVER /* 允许呼叫应用继续在其她应用中启动的呼叫权限 如视频通话应用希望在用户的移动网络上继续语音通话_保护等级为 危险_API 级别 28 */
  8. android.permission.USE_SIP /* 允许应用使用 SIP 服务权限_保护等级为 危险_API 级别 9 */
  9. com.android.voicemail.permission.ADD_VOICEMAIL /* 允许应用向系统中添加语音邮件权限_保护等级为 危险_API 级别 14 */
  10. /* 其她权限例如 MANAGE_OWN_CALLS 允许调用应用通过自我管理的 ConnectionService API 管理自己的调用_保护等级为 正常_API 级别 26 */

%%%%%

日历权限组 android.permission-group.CALENDAR

android.permission-group.CALENDAR    /* 日历权限组_API 级别 17_用户日历相关的运行时权限 */

  1. android.permission.READ_CALENDAR /* 允许应用读取用户日历数据权限_保护等级 危险_API 级别 1 */
  2. android.permission.WRITE_CALENDAR /* 允许应用写入用户日历数据权限_保护等级 危险_API 级别 1 */

%%%%%

通话记录权限组 android.permission-group.CALL_LOG

android.permission-group.CALL_LOG    /* 通话记录的权限_API 级别 28 */

  1. android.permission.READ_CALL_LOG /* 允许应用读取用户通话日志权限_危险_16 */
  2. android.permission.WRITE_CALL_LOG /* 允许应用写入用户通话日志_危险_16 */
  3. android.permission.PROCESS_OUTGOING_CALLS /* 允许应用查看拨出呼叫期间拨出的号码_危险_1 */

%%%%%

相机权限组 android.permission-group.CAMERA

android.permission-group.CAMERA    /* 访问相机或从设备捕获 图像/视频 相关的权限_17 */

android.permission.CAMERA	/* 允许访问摄像头_危险|立即_1 */

%%%%%

身体传感器权限组 android.permission-group.SENSORS

android.permission-group.SENSORS    /* 身体或环境传感器相关的权限_23 */

  1. android.permission.BODY_SENSORS /* 允许应用访问身体传感器的数据_危险_20 */
  2. android.permission.USE_FINGERPRINT /* 允许应用使用指纹硬件 API 级别 28 以后不再建议使用_正常_23 */
  3. android.permission.USE_BIOMETRIC /* 允许应用使用设备支持的生物识别模式_正常_28 */

%%%%%

位置信息权限组 android.permission-group.LOCATION

android.permission-group.LOCATION    /* 允许访问设备位置信息的权限_1 */

  1. android.permission.ACCESS_FINE_LOCATION /* 允许应用访问精确的位置_危险_1 */
  2. android.permission.ACCESS_COARSE_LOCATION /* 允许应用访问大概的位置_危险_1 */

%%%%%

存储空间权限组 android.permission-group.STORAGE

android.permission-group.STORAGE    /* 外部存储相关的运行时权限 API 级别 Q 以后不再建议使用_4 */

  1. android.permission.READ_EXTERNAL_STORAGE /* 允许应用读取扩展存储 API 级别 Q 以后不再建议使用_危险_16 */
  2. android.permission.WRITE_EXTERNAL_STORAGE /* 允许应用写入扩展存储 API 级别 Q 以后不再建议使用_危险_4 */

%%%%%

系统控制权限组 androidlogic.permission-group.SYSTEM_CONTROL

droidlogic.permission-group.SYSTEM_CONTROL    /* 未知权限 字面翻译为 安卓逻辑系统.授权-组.系统_控制 */

droidlogic.permission.SYSTEM_CONTROL

%%%%%

麦克风权限组 android.permission-group.MICROPHONE

android.permission-group.MICROPHONE    /* 访问麦克风相关的权限 请注意 电话呼叫也会捕获音频 但属于单独的权限组_17 */

android.permission.RECORD_AUDIO	/* 允许应用录音_危险_1 */

%%%%%

短信权限组 android.permission-group.SMS

android.permission-group.SMS    /* 短信相关的运行时权限_23 */

  1. android.permission.READ_SMS /* 允许应用访问 SMS 信息_危险_1 */
  2. android.permission.RECEIVE_WAP_PUSH /* 允许应用接收 WAP 推送信息_危险_1 */
  3. android.permission.RECEIVE_MMS /* 允许应用监视传入的彩信_危险_1 */
  4. android.permission.RECEIVE_SMS /* 允许应用接收短信_危险_1 */
  5. android.permission.SEND_SMS /* 允许应用发送短信_危险_1 */
  6. android.permission.READ_CELL_BROADCASTS /* 允许应用读取小区广播消息_危险 */

%%%%%

CM311-1A 盒子和手机设备都没有看到 WIFI 网络相关的权限

  1. shell@GIONEE_G1605A:/ $ pm list permission-groups
  2. permission group:android.permission-group.CONTACTS
  3. permission group:android.permission-group.PHONE
  4. permission group:android.permission-group.CALENDAR
  5. permission group:android.permission-group.CAMERA
  6. permission group:android.permission-group.SENSORS
  7. permission group:android.permission-group.LOCATION
  8. permission group:android.permission-group.STORAGE
  9. permission group:android.permission-group.MICROPHONE
  10. permission group:android.permission-group.SMS
  11. shell@GIONEE_G1605A:/ $ pm list permissions -g -d
  12. Dangerous Permissions:
  13. group:android.permission-group.CONTACTS
  14. permission:android.permission.WRITE_CONTACTS
  15. permission:android.permission.GET_ACCOUNTS
  16. permission:android.permission.READ_CONTACTS
  17. group:android.permission-group.PHONE
  18. permission:android.permission.READ_CALL_LOG
  19. permission:android.permission.READ_PHONE_STATE
  20. permission:android.permission.CALL_PHONE
  21. permission:android.permission.WRITE_CALL_LOG
  22. permission:android.permission.USE_SIP
  23. permission:android.permission.PROCESS_OUTGOING_CALLS
  24. permission:com.android.voicemail.permission.ADD_VOICEMAIL
  25. group:android.permission-group.CALENDAR
  26. permission:android.permission.READ_CALENDAR
  27. permission:android.permission.WRITE_CALENDAR
  28. group:android.permission-group.CAMERA
  29. permission:android.permission.CAMERA
  30. group:android.permission-group.SENSORS
  31. permission:android.permission.BODY_SENSORS
  32. group:android.permission-group.LOCATION
  33. permission:android.permission.ACCESS_FINE_LOCATION
  34. permission:android.permission.ACCESS_COARSE_LOCATION
  35. group:android.permission-group.STORAGE
  36. permission:android.permission.READ_EXTERNAL_STORAGE
  37. permission:android.permission.WRITE_EXTERNAL_STORAGE
  38. group:android.permission-group.MICROPHONE
  39. permission:android.permission.RECORD_AUDIO
  40. group:android.permission-group.SMS
  41. permission:android.permission.READ_SMS
  42. permission:android.permission.RECEIVE_WAP_PUSH
  43. permission:android.permission.RECEIVE_MMS
  44. permission:android.permission.RECEIVE_SMS
  45. permission:android.permission.SEND_SMS
  46. permission:android.permission.READ_CELL_BROADCASTS
  47. ungrouped:
  48. shell@GIONEE_G1605A:/ $ pm list permissions -s
  49. All Permissions:
  50. 通讯录: 修改您的通讯录, 查找设备上的帐户, 读取您的通讯录
  51. 电话: 读取通话记录, 读取手机状态和身份, 使用即时通讯通话服务, 直接拨打电话号码,
  52. 写入通话记录, 拨打/接听SIP电话, 重新设置外拨电话的路径, 添加语音邮件
  53. 日历: 读取日历活动和机密信息, 添加或修改日历活动,并在所有者不知情的情况下向邀请
  54. 对象发送电子邮件
  55. 相机: 拍摄照片和视频
  56. 身体传感器: 人体传感器(如心跳速率检测器), 使用指纹硬件
  57. 位置信息: 精确位置(基于GPS和网络), 大致位置(基于网络)
  58. 存储空间: 读取您的SD卡中的内容, 修改或删除您的SD卡中的内容
  59. 麦克风: 录音
  60. 短信: 读取您的讯息(短信或彩信), 接收讯息 (WAP), 接收讯息(彩信), 接收讯息(短
  61. 信), 发送和查看短信, 读取小区广播消息
  62. ungrouped:
  63. null, null, null, null, null, 修改系统设置, null, null, 建立或中断 WiMAX 网络连
  64. 接, null, null, null, null, null, null, Error: java.lang.NullPointerException: A
  65. ttempt to read from field 'java.lang.String android.content.pm.ApplicationInfo.p
  66. ublicSourceDir' on a null object reference
  67. 1|shell@GIONEE_G1605A:/ $

##################################################

三层 Android 权限详解

——————————

第三层 —— 系统权限以及软件安装权限真相

%%%%%

Android 底层映射为 Linux 权限

        每个程序在安装时都有建立一个系统 ID

用以保护数据不被其她应用获取

        例如 app_15

        Android 系统会根据不同的用户和组来分配不同权限

        比如访问 SD 卡、访问网络等等

        底层均映射为 Linux 权限!

%%%%%

Android 应用程序权限机制

        Android 安全模型基于 Linux 的权限管理

android 系统充分利用了 linux 的用户权限管理方法

        使用沙箱隔离机制将每个应用的进程资源隔离

Android 应用程序在安装时赋予一个 UID
UID 不同的应用程序完全隔离

        另一方面 应用如果想使用某种服务 需要在 AndroidManifest.xml 中申请
        比如想使用网络的话需要在 AndroidManifest.xml 中添加:

<uses-permission android:name="android.permission.INTERNET" />

        INTERNET 权限将被映射到底层的 GID
        所以一个应用有一个 UID 可以有多个 GID 来获得多个权限

        Android 本身支持在应用程序的 AndroidManifest.xml 中自定义权限
        但这种自定义的权限没有被映射到系统底层的用户组中 没有独立的 GID
        如果在系统中有一个 C 语言写的服务 只有应用申请了权限才可以使用 我们就需要将这个权限映射到底层
        例如在开发中自定义一个类似于上面的 INTERNET 的系统级权限组

  1. 一个用户可以属于多个组
  2. 一个文件只能属于某个组

        这里主要是在 AndroidManifest.xml 中声明权限

        主要是通过在 AndroidManifest.xml 中显式地声明应用程序需要的权限 防止应用程序错误的使用服务 不恰当访问资源

        Android 中每种权限都用一个独立的标签表示 示例:

  1. <uses-permission android:name="android.permission.WAKE_LOCK" />
  2. <uses-permission android:name="android.permission.INTERNET" />
  3. <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  4. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

        当在安装应用程序时 Android 就会给予一个 UID

        这个 UID 可连接到该应用程序的 AndroidManifest.xml 文件的内容

        所以 User 在安装你的应用程序时在屏幕上的窗口里可以看到这个 AndroidManifest.xml 文件的内容

        用户会看到你对应用程序的目的、权限等说明

        当你接受这支程序的意图、权限说明之后 Android 就安装她 并给她一个 UID

        万一在你的应用程序执行期间有越轨 企图做出非权限范围 的行为时 用户将会得到 Android 的警告讯息

        Android 的系统权限不是由用户控制 而是由开发者根据开发的需要控制相关权限的开放与否

        例如 AndroidManifest.xml 中有如下内容:

  1. <uses-permission android:name="android.permission.RECORD_AUDIO" />
  2. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

        表示需要使用存储设备和录音设备 在安装的时候 就会提示用户她需要的权限

%%%%%

安装一个 APK 的详细过程

        安装 APK 时发生了什么:

  1.         在安装 apk 的时候会解析
  2. AndroidManifest.xml
  3.         把相应的信息保存起来
  4.         解析权限调用的是函数
  5. private Package parsePackage
  6.         这里保存的都是
  7. android.permission.WRITE_EXTERNAL_STORAGE
  8.         这样的字符串
  9.         在解析完后会调用
  10. private void grantPermissionsLP
  11.         函数获取对应的
  12. group_id
  13.         该函数把相应的组都保存到了 gids 中
  14.         当应用程序启动的过程中会调用
  15. private final void startProcessLocked
  16.         这里就是获取前面保存的 gids
  17.         再后面调用创建了一个新的进程 这里传的参数就有 gids
  18.         创建新进程利用 jni 最终调用
  19. static pid_t forkAndSpecializeCommon
  20.         函数
  21.         我们如果研究代码可以看到在子进程里调用
  22. setgroupsIntarray
  23.         设置该进程所属的组 这样她就拥有了该组的权限
  24.         也通过 setgid 及 setuid 决定了应用程序的 uid 及 gid 值

        权限控制主要放置在 AndroidManifest.xml 文件中

        最后镜像生成在 system\etc\permissions\platform.xml 配置文件中

%%%%%

声明时权限 安全等级/protectionLevel 分类

        多用户下的应用其实只安装一次 不同用户下同一个应用的版本和签名都应该相同

        不同用户下相同 App 能够独立运行是因为系统为她们创造了不同的运行环境和权限

        protectionLevel 分为三类:

  1. <permission android:name="android.permission.READ_EXTERNAL_STORAGE"
  2. android:permissionGroup="android.permission-group.STORAGE"
  3. android:label="@string/permlab_sdcardRead"
  4. android:description="@string/permdesc_sdcardRead"
  5. android:protectionLevel="dangerous" />
  6. <!-- Allows applications to access information about Wi-Fi networks./允许应用程序访问有关 Wi-Fi 网络的信息。
  7. <p>Protection level: normal
  8. -->
  9. <permission android:name="android.permission.ACCESS_WIFI_STATE"
  10. android:description="@string/permdesc_accessWifiState"
  11. android:label="@string/permlab_accessWifiState"
  12. android:protectionLevel="normal" />
  13. <!-- @SystemApi Allows applications to set the system time./@SystemApi 允许应用程序设置系统时间。
  14. <p>Not for use by third-party applications. -->
  15. <permission android:name="android.permission.SET_TIME"
  16. android:protectionLevel="signature|privileged" />

        normal 是普通权限

在 AndroidManifest.xml 中声明就可以获取的权限

如 INTERNET 权限


        dangerous 敏感权限

需要动态申请告知用户才能获取

        signature|privileged 签名|特权

具有系统签名的系统应用才可以获取的权限

对应上方的安装在 /system/priv-app 的特权应用!

——————————

第一层 —— 开发层 AndroidManifest.xml

        第一层是在开发人员编写代码时由应用设置 主要是修改 AndroidManifest.xml 文件

        AndroidManifest.xml 是 APP 的运行配置文件 她是一个 XML 描述文件 指定了 APP 的运行配置信息

        一般都存放在 APP 包下的 manifests 目录下

        不过我也见过放在 src/main/res/AndroidManifest.xm 下面的

        AndroidManifest.xml 文件的作用:

  1. 描述 app 的包名
  2. 描述 app 使用的 android 系统版本信息
  3. 描述 app 本身的版本信息 这样对于同一个 app 的两个版本 系统就能区分那个新版本旧版本
  4. 描述应用对外暴露的组件等等

        我们将 apk 文件后缀修改成 zip 就可以使用平常的解压工具进行解压了:

        第一眼看到的就是 AndroidManifest.xml 配置文件:

后缀修改成 zip

        AndroidManifest 官方解释是 应用清单 manifest 意思是货单

        每个应用的根目录中都必须包含一个 并且文件名必须一模一样

        这个文件中包含了 APP 的配置信息 系统需要根据里面的内容运行 APP 的代码 显示界面

        AndroidManifest.xml 是每个 apk 文件解压后根目录下的一个文件

        每个 apk 都必须包含一个 AndroidManifest.xml 文件 且名字必须与此完全一致.

        示例 AndroidManifest.xml 中的一段配置代码:

  1. <!-- 访问网络 -->
  2. <uses-permission android:name="android.permission.INTERNET" />
  3. <!-- 使用振动的权限 -->
  4. <uses-permission android:name="android.permission.VIBRATE"></uses-permission>
  5. <!-- 键盘锁权限Allows applications to disable the keyguard -->
  6. <uses-permission android:name="android.permission.DISABLE_KEYGUARD"></uses-permission>
  7. <!-- 调用相机权限 -->
  8. <uses-permission android:name="android.permission.CAMERA"/>
  9. <!-- 悬浮窗 -->
  10. <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

%%%%%

AndroidManifest.xml 配置文件权限分类

        通过 shareduserid 来实现数据共享有一个限制就是相同的签名

        这个是很高要求的

一般都是同一个公司开发出来的 app 才能满足获取内置到第三方 ROM 里面去才能满足

        通常的做法是通过 uses-permission 来实现 我们自己定义一个权限!

        在需要被访问的地方加上这个权限限制这样就能到达目的!

  1. normal 权限 也就是一般的权限 不需要用户去确认的 例如一个应用申请连接网络等
  2. dangerous 权限 这种权限较 normal 权限高一些 需要用户手动点击确认的 例如应用需要读取联系人的信息 因为这些数据是比较隐私的可能会导致你的数据泄露等
  3. signature 只有当申请权限的应用程序的数字签名与声明此权限的应用程序的数字签名相同时 才能将权限授给她 如果是申请系统权限则需要与系统签名相同
  4. signatureOrSystem 签名相同 或者申请权限的应用为系统应用 在 system image 中

        signature 和 signatureOrSystem 要求是很高 一般的只有是相同公司开发出来的应用才能满足

%%%%%

AndroidManifest.xml 配置文件详解

        我们在安装 Android 软件的时候系统会提示该软件所需要的权限

        相对于其她系统 Android 的权限非常多

        我们在开发软件的时候也需要声明相应的权限,比如希望软件能发短信,需要声明软件调用短信的权限

        否则软件运行的时候就会报错

        Android 的权限在 AndroidManifest.xml 文件里配置

        AndroidManifest 文件中有四个标签与 permission 有关:

<permission>

<permission-group>

<permission-tree>

<uses-permission>

        其中最常用的是 <uses-permission>

        当我们需要获取某个权限的时候就必须在我们的 manifest 文件中声明 <uses-permission>

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest>
  3. <application>
  4. </application>
  5. <uses-permission />
  6. <permission />
  7. <permission-tree />
  8. <permission-group />
  9. ...
  10. </manifest>

        <permission> 和 <uses-permission> 的作用相似 两者之间的不同之处在于

<uses-permission> 是 android 预定义的权限

<permission> 是自己定义的权限

  1.         <permission> 用的相对较少
  2.         <permission-group>   <permission-tree> 这两个标签就更少见了
  3.         简单说 <permission-group> 就是声明一个标签 该标签代表了一组 permissions
  4.         而 <permission-tree> 是为一组 permissions 声明了一个 namespace

        <permission> 定义方法如下:

  1. <permission android:description="string resource"
  2. android:icon="drawable resource"
  3. android:label="string resource"
  4. android:name="string"
  5. android:permissionGroup="string"
  6. android:protectionLevel=["normal" | "dangerous" |
  7. "signature" | "signatureOrSystem"] />

        解释一下:

  1.         propectionLevel 这个属性是必须声明的
  2.         告诉系统通知用户的应用要求许可 或允许谁认为获得许可的情况下
  3.         permissionGroup 这个是可选的 与 <permission-group> 配合使用
  4.         label, name 和 icon 用于描述权限

        <uses-permission> 是我们用的最多的 例如短信和电话权限的定义:

  1. <uses-permission android:name="android.permission.CALL_PHONE" />
  2. <uses-permission android:name="android.permission.SEND_SMS"/>

        常见权限:

  1. <uses-permission android:name="android.permission.ACCESS_CHECKIN_PROPERTIES" ></uses-permission> /* 允许读写访问 properties 表 在 checkin 数据库中 可以修改上传 */
  2. <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" ></uses-permission> /* 允许一个程序访问 CellID 或 WiFi 热点来获取粗略的位置 */
  3. <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" ></uses-permission> /* 允许一个程序访问精良位置 如 GPS */
  4. <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" ></uses-permission> /* 允许应用程序访问额外的位置提供命令 */
  5. <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" ></uses-permission> /* 允许程序创建模拟位置提供用于测试 */
  6. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" ></uses-permission> /* 允许程序访问有关 GSM 网络信息 */
  7. <uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" ></uses-permission> /* 允许程序使用 SurfaceFlinger 底层特性 */
  8. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" ></uses-permission> /* 允许程序访问 Wi-Fi 网络状态信息 */
  9. <uses-permission android:name="android.permission.ADD_SYSTEM_SERVICE" ></uses-permission> /* 允许程序发布系统级服务 */
  10. <uses-permission android:name="android.permission.BATTERY_STATS" ></uses-permission> /* 允许程序更新手机电池统计信息 */
  11. <uses-permission android:name="android.permission.BLUETOOTH" ></uses-permission> /* 允许程序连接到已配对的蓝牙设备 */
  12. <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" ></uses-permission> /* 允许程序发现和配对蓝牙设备 */
  13. <uses-permission android:name="android.permission.BRICK" ></uses-permission> /* 请求能够禁用设备 */
  14. <uses-permission android:name="android.permission.BROADCAST_PACKAGE_REMOVED" ></uses-permission> /* 允许程序广播一个提示消息在一个应用程序包已经移除后 */
  15. <uses-permission android:name="android.permission.BROADCAST_STICKY" ></uses-permission> /* 允许一个程序广播常用 intents */
  16. <uses-permission android:name="android.permission.CALL_PHONE" ></uses-permission> /* 允许一个程序初始化一个电话拨号不需通过拨号用户界面需要用户确认 */
  17. <uses-permission android:name="android.permission.CALL_PRIVILEGED" ></uses-permission> /* 允许一个程序拨打任何号码 包含紧急号码无需通过拨号用户界面需要用户确认 */
  18. <uses-permission android:name="android.permission.CAMERA" ></uses-permission> /* 请求访问使用照相设备 */
  19. <uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" ></uses-permission> /* 允许一个程序是否改变一个组件或其她的启用或禁用 */
  20. <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" ></uses-permission> /* 允许一个程序修改当前设置 如本地化 */
  21. <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" ></uses-permission> /* 允许程序改变网络连接状态 */
  22. <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" ></uses-permission> /* 允许程序改变 Wi-Fi 连接状态 */
  23. <uses-permission android:name="android.permission.CLEAR_APP_CACHE" ></uses-permission> /* 允许一个程序清楚缓存从所有安装的程序在设备中 */
  24. <uses-permission android:name="android.permission.CLEAR_APP_USER_DATA" ></uses-permission> /* 允许一个程序清除用户设置 */
  25. <uses-permission android:name="android.permission.CONTROL_LOCATION_UPDATES" ></uses-permission> /* 允许启用禁止位置更新提示从无线模块 */
  26. <uses-permission android:name="android.permission.DELETE_CACHE_FILES" ></uses-permission> /* 允许程序删除缓存文件 */
  27. <uses-permission android:name="android.permission.DELETE_PACKAGES" ></uses-permission> /* 允许一个程序删除包 */
  28. <uses-permission android:name="android.permission.DEVICE_POWER" ></uses-permission> /* 允许访问底层电源管理 */
  29. <uses-permission android:name="android.permission.DIAGNOSTIC" ></uses-permission> /* 允许程序 RW 诊断资源 */
  30. <uses-permission android:name="android.permission.DISABLE_KEYGUARD" ></uses-permission> /* 允许程序禁用键盘锁 */
  31. <uses-permission android:name="android.permission.DUMP" ></uses-permission> /* 允许程序返回状态抓取信息从系统服务 */
  32. android.permission.EXPAND_STATUS_BAR /* 允许一个程序扩展收缩状态栏 */
  33. android.permission.FACTORY_TEST /* 作为一个工厂测试程序 运行在 root 用户 */
  34. android.permission.FLASHLIGHT /* 访问闪光灯 */
  35. android.permission.FORCE_BACK /* 允许程序强行一个后退操作是否在顶层 activities */
  36. android.permission.FOTA_UPDATE android /* 一个预留权限 */
  37. android.permission.GET_ACCOUNTS /* 访问一个帐户列表在 Accounts Service 中 */
  38. android.permission.GET_PACKAGE_SIZE /* 允许一个程序获取任何 package 占用空间容量 */
  39. android.permission.GET_TASKS /* 允许一个程序获取信息有关当前或最近运行的任务 一个缩略的任务状态 是否活动等等 */
  40. android.permission.HARDWARE_TEST /* 允许访问硬件 */
  41. android.permission.INJECT_EVENTS /* 允许一个程序截获用户事件如按键、触摸、轨迹球等等到一个时间流 */
  42. android.permission.INSTALL_PACKAGES /* 允许一个程序安装 packages */
  43. android.permission.INTERNAL_SYSTEM_WINDOW /* 允许打开窗口使用系统用户界面 */
  44. android.permission.INTERNET /* 允许程序打开网络套接字 */
  45. android.permission.MANAGE_APP_TOKENS /* 允许程序管理程序引用在窗口管理器中 创建、催后、z- order 默认向 z 轴推移 */
  46. android.permission.MASTER_CLEAR /* 恢复出厂设置权限 清除一切用户数据 */
  47. android.permission.MODIFY_AUDIO_SETTINGS /* 允许程序修改全局音频设置 */
  48. android.permission.MODIFY_PHONE_STATE /* 允许修改话机状态,如电源,人机接口等 */
  49. android.permission.MOUNT_UNMOUNT_FILESYSTEMS /* 允许挂载和反挂载文件系统可移动存储 */
  50. android.permission.PERSISTENT_ACTIVITY /* 允许一个程序设置她的 activities 显示 */
  51. android.permission.PROCESS_OUTGOING_CALLS /* 允许程序监视、修改有关播出电话 */
  52. android.permission.READ_CALENDAR /* 允许程序读取用户日历数据 */
  53. android.permission.READ_CONTACTS /* 允许程序读取用户联系人数据 */
  54. android.permission.READ_FRAME_BUFFER /* 允许程序屏幕波或和更多常规的访问帧缓冲数据 */
  55. android.permission.READ_INPUT_STATE /* 允许程序读取底层系统日志文件 */
  56. android.permission.READ_OWNER_DATA /* 允许程序读取所有者数据 */
  57. android.permission.READ_SMS /* 允许程序读取短信息 */
  58. android.permission.READ_SYNC_SETTINGS /* 允许程序读取同步设置 */
  59. android.permission.READ_SYNC_STATS /* 允许程序读取同步状态 */
  60. android.permission.REBOOT /* 请求能够重新启动设备 */
  61. android.permission.RECEIVE_BOOT_COMPLETED /* 允许一个程序接收到 ACTION_BOOT_COMPLETED 广播在系统完成启动 */
  62. android.permission.RECEIVE_MMS /* 允许一个程序监控将收到 MMS 彩信 记录或处理 */
  63. android.permission.RECEIVE_SMS /* 允许程序监控一个将收到短信息 记录或处理 */
  64. android.permission.RECEIVE_WAP_PUSH /* 允许程序监控将收到 WAP PUSH 信息 */
  65. android.permission.RECORD_AUDIO /* 允许程序录制音频 */
  66. android.permission.REORDER_TASKS /* 允许程序改变 Z 轴排列任务 */
  67. android.permission.RESTART_PACKAGES /* 允许程序重新启动其她程序 */
  68. android.permission.SEND_SMS /* 允许程序发送 SMS 短信 */
  69. android.permission.SET_ACTIVITY_WATCHER /* 允许程序监控或控制 activities 已经启动全局系统中 */
  70. android.permission.SET_ALWAYS_FINISH /* 允许程序控制是否活动间接完成在处于后台时 */
  71. android.permission.SET_ANIMATION_SCALE /* 修改全局信息比例 */
  72. android.permission.SET_DEBUG_APP /* 配置一个程序用于调试 */
  73. android.permission.SET_ORIENTATION /* 允许底层访问设置屏幕方向和实际旋转 */
  74. android.permission.SET_PREFERRED_APPLICATIONS /* 允许一个程序修改列表参数 PackageManager.addPackageToPreferred() 和 PackageManager.removePackageFromPreferred() 这两个方法 */
  75. android.permission.SET_PROCESS_FOREGROUND /* 允许程序当前运行程序强行到前台 */
  76. android.permission.SET_PROCESS_LIMIT /* 允许设置最大的运行进程数量 */
  77. android.permission.SET_TIME_ZONE /* 允许程序设置时间区域 */
  78. android.permission.SET_WALLPAPER /* 允许程序设置壁纸 */
  79. android.permission.SET_WALLPAPER_HINTS /* 允许程序设置壁纸 hits */
  80. android.permission.SIGNAL_PERSISTENT_PROCESSES /* 允许程序请求发送信号到所有显示的进程中 */
  81. android.permission.STATUS_BAR /* 允许程序打开、关闭或禁用状态栏及图标 */
  82. android.permission.SUBSCRIBED_FEEDS_READ /* 允许一个程序访问订阅 RSS Feed 内容提供 */
  83. android.permission.SUBSCRIBED_FEEDS_WRITE /* 系统暂时保留改设置 */
  84. android.permission.SYSTEM_ALERT_WINDOW /* 允许一个程序打开窗口使用 TYPE_SYSTEM_ALERT 显示在其她所有程序的顶层 */
  85. android.permission.VIBRATE /* 允许访问振动设备 */
  86. android.permission.WAKE_LOCK /* 允许使用 PowerManager 的 WakeLocks 保持进程在休眠时从屏幕消失 */
  87. android.permission.WRITE_APN_SETTINGS /* 允许程序写入 API 设置 */
  88. android.permission.WRITE_CALENDAR /* 允许一个程序写入但不读取用户日历数据 */
  89. android.permission.WRITE_CONTACTS /* 允许程序写入但不读取用户联系人数据 */
  90. android.permission.WRITE_GSERVICES /* 允许程序修改 Google 服务地图 */
  91. android.permission.WRITE_OWNER_DATA /* 允许一个程序写入但不读取所有者数据 */
  92. android.permission.WRITE_SETTINGS /* 允许程序读取或写入系统设置 */
  93. android.permission.WRITE_SMS /* 允许程序写短信 */
  94. android.permission.WRITE_SYNC_SETTINGS /* 允许程序写入同步设置 */

——————————

第二层 —— 框架层 preferences.xml

        platform.xml 其实是将 aosp 中的配置文件直接拷贝到手机目录中

        AOSP 全称 Android Open Source Project 中文意为 Android 开放源代码项目

  1. 安卓开源项目 开源即开放源代码
  2. Android 是一个基于 Linux 由 Google 主导的开源系统
  3. 严格意义上来说 Android = AOSP + GMS
  4. GMS 即谷歌移动服务 即常刷的谷歌服务包
  5. 国内无法使用 GMS 所以国内的各种定制 ROM 都是 AOSP 的定制修改加上自家的云服务
  6. 比如 MIUI、ColorOS 等
  7. 所以所有的 ROM 最终的根源就是 AOSP 没有 AOSP 也就没有现在的 Android

        应用包中 preferences.xml 文件的位置在 res\xml\preferences.xml

        设备目录存放的位置在 /system/etc/permissions/platform.xml

        在 aosp 中的存放位置是 framework/base/data/etc/platform.xml

%%%%%

示例一个 root 过的手机修改板子 sd 权限

        编辑的是

root/system/etc/permissions/platform.xml

        文件 看到代码如下:

  1. <permission name="android.permission.WRITE_EXTERNAL_STORAGE" >
  2. <group gid="sdcard_r" />
  3. <group gid="sdcard_rw" />
  4. </permission>

        修改为:

  1. <permission name="android.permission.WRITE_EXTERNAL_STORAGE" >
  2. <group gid="sdcard_r" />
  3. <group gid="sdcard_rw" />
  4. <group gid="media_rw" />
  5. </permission>

        再然后重启就行了

%%%%%

CM311-1A 的 platform.xml 配置文件详解

        这是对 platform.xml 的解析 注意看注释:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!-- Copyright (C) 2008 The Android Open Source Project
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. -->
  13. /** 第一部分 >>> 警告部分
  14. 说明这个文件是处理普通用户和系统权限之间映射的 如果擅自改动会造成大的安全漏洞
  15. 此文件用于定义较低级别系统之间的映射 管理的用户和组 ID 以及更高级别的权限名称在平台旁。
  16. 编辑此文件时要非常小心!这里犯的错误可能会打开巨大的安全漏洞。
  17. */
  18. <!-- This file is used to define the mappings between lower-level system
  19. user and group IDs and the higher-level permission names managed
  20. by the platform.
  21. Be VERY careful when editing this file! Mistakes made here can open
  22. big security holes.
  23. -->
  24. <permissions>
  25. <!-- ================================================================== -->
  26. <!-- ================================================================== -->
  27. <!-- ================================================================== -->
  28. /** 第二部分 >>> 权限映射
  29. <permission> 将低等级的 groups id 和权限名称相关联
  30. 通过指定这样的映射 表明了一个授予了给定权限的应用进程将附带这所给的 group id 运行
  31. 因此她可以执行这个群组所允许的读写和执行操作
  32. 以下标记将低级组 ID 与权限名称关联
  33. 通过指定这样一个映射,您的意思是,任何被授予给定权限的应用程序进程也将在其进程附加给定组 ID 的情况下运行
  34. 因此,她可以执行该组允许的任何文件系统 读、写、执行 操作。
  35. */
  36. <!-- The following tags are associating low-level group IDs with
  37. permission names. By specifying such a mapping, you are saying
  38. that any application process granted the given permission will
  39. also be running with the given group ID attached to its process,
  40. so it can perform any filesystem (read, write, execute) operations
  41. allowed for that group. -->
  42. <permission name="android.permission.BLUETOOTH_ADMIN" >
  43. <group gid="net_bt_admin" />
  44. </permission>
  45. <permission name="android.permission.BLUETOOTH" >
  46. <group gid="net_bt" />
  47. </permission>
  48. <permission name="android.permission.BLUETOOTH_STACK" >
  49. <group gid="bluetooth" />
  50. <group gid="wakelock" />
  51. <group gid="uhid" />
  52. </permission>
  53. <permission name="android.permission.NET_TUNNELING" >
  54. <group gid="vpn" />
  55. </permission>
  56. <permission name="android.permission.INTERNET" >
  57. <group gid="inet" />
  58. </permission>
  59. <permission name="android.permission.READ_LOGS" >
  60. <group gid="log" />
  61. </permission>
  62. <permission name="android.permission.WRITE_MEDIA_STORAGE" >
  63. <group gid="media_rw" />
  64. <group gid="sdcard_rw" />
  65. </permission>
  66. <permission name="android.permission.ACCESS_MTP" >
  67. <group gid="mtp" />
  68. </permission>
  69. <permission name="android.permission.NET_ADMIN" >
  70. <group gid="net_admin" />
  71. </permission>
  72. <!-- The group that /cache belongs to, linked to the permission
  73. set on the applications that can access /cache -->
  74. <permission name="android.permission.ACCESS_CACHE_FILESYSTEM" >
  75. <group gid="cache" />
  76. </permission>
  77. <!-- RW permissions to any system resources owned by group 'diag'.
  78. This is for carrier and manufacture diagnostics tools that must be
  79. installable from the framework. Be careful. -->
  80. <permission name="android.permission.DIAGNOSTIC" >
  81. <group gid="input" />
  82. <group gid="diag" />
  83. </permission>
  84. <!-- Group that can read detailed network usage statistics -->
  85. <permission name="android.permission.READ_NETWORK_USAGE_HISTORY">
  86. <group gid="net_bw_stats" />
  87. </permission>
  88. <!-- Group that can modify how network statistics are accounted -->
  89. <permission name="android.permission.UPDATE_DEVICE_STATS">
  90. <group gid="net_bw_acct" />
  91. </permission>
  92. <permission name="android.permission.LOOP_RADIO" >
  93. <group gid="loop_radio" />
  94. </permission>
  95. <!-- Hotword training apps sometimes need a GID to talk with low-level
  96. hardware; give them audio for now until full HAL support is added. -->
  97. <permission name="android.permission.MANAGE_VOICE_KEYPHRASES">
  98. <group gid="audio" />
  99. </permission>
  100. <permission name="android.permission.ACCESS_BROADCAST_RADIO" >
  101. <!-- /dev/fm is gid media, not audio -->
  102. <group gid="media" />
  103. </permission>
  104. <permission name="android.permission.USE_RESERVED_DISK">
  105. <group gid="reserved_disk" />
  106. </permission>
  107. /** 第三部分 >>> 权限映射的例外部分
  108. 这些权限映射到 GID 但我们需要将其保留在此处 直到支持从 L 升级到当前版本
  109. 这些权限是内置的 在 L 中没有存储在包中
  110. 如果在解析包时未在此处定义 则返回 xml
  111. xml 我们将忽略授予应用程序的这些权限 而不传播授予的状态
  112. 从 N 开始 我们将内置权限存储在包中
  113. 与脆弱性相比 作为保存的存储的 xml 可以忽略不计 带有权限的一个标记
  114. 因为可以删除不再需要映射到 GID 和中断授权传播的内置权限
  115. */
  116. <!-- These are permissions that were mapped to gids but we need
  117. to keep them here until an upgrade from L to the current
  118. version is to be supported. These permissions are built-in
  119. and in L were not stored in packages.xml as a result if they
  120. are not defined here while parsing packages.xml we would
  121. ignore these permissions being granted to apps and not
  122. propagate the granted state. From N we are storing the
  123. built-in permissions in packages.xml as the saved storage
  124. is negligible (one tag with the permission) compared to
  125. the fragility as one can remove a built-in permission which
  126. no longer needs to be mapped to gids and break grant propagation. -->
  127. <permission name="android.permission.READ_EXTERNAL_STORAGE" />
  128. <permission name="android.permission.WRITE_EXTERNAL_STORAGE" />
  129. <!-- ================================================================== -->
  130. <!-- ================================================================== -->
  131. <!-- ================================================================== -->
  132. /** 第四部分 >>> 分配权限
  133. <assign-permission> 有些用户比较特殊 她们是系统核心用户
  134. Android 会分配特定的高级权限来允许她们来完成一些高级的操作
  135. 比如 shell 用户有很多权限 这是因为开发者需要比较开放的环境来和 system 进行交互
  136. shell 用户的权限有时候需要 adb root/adb remount 才能享受
  137. 对应的需要 userdebug 或者 root 版本
  138. user 版本下 shell 命令还是有所限制的
  139. */
  140. <!-- The following tags are assigning high-level permissions to specific
  141. user IDs. These are used to allow specific core system users to
  142. perform the given operations with the higher-level framework. For
  143. example, we give a wide variety of permissions to the shell user
  144. since that is the user the adb shell runs under and developers and
  145. others should have a fairly open environment in which to
  146. interact with the system. -->
  147. <assign-permission name="android.permission.MODIFY_AUDIO_SETTINGS" uid="media" />
  148. <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="media" />
  149. <assign-permission name="android.permission.WAKE_LOCK" uid="media" />
  150. <assign-permission name="android.permission.UPDATE_DEVICE_STATS" uid="media" />
  151. <assign-permission name="android.permission.UPDATE_APP_OPS_STATS" uid="media" />
  152. <assign-permission name="android.permission.GET_PROCESS_STATE_AND_OOM_SCORE" uid="media" />
  153. <assign-permission name="android.permission.MODIFY_AUDIO_SETTINGS" uid="audioserver" />
  154. <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="audioserver" />
  155. <assign-permission name="android.permission.WAKE_LOCK" uid="audioserver" />
  156. <assign-permission name="android.permission.UPDATE_DEVICE_STATS" uid="audioserver" />
  157. <assign-permission name="android.permission.UPDATE_APP_OPS_STATS" uid="audioserver" />
  158. <assign-permission name="android.permission.PACKAGE_USAGE_STATS" uid="audioserver" />
  159. <assign-permission name="android.permission.MODIFY_AUDIO_SETTINGS" uid="cameraserver" />
  160. <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="cameraserver" />
  161. <assign-permission name="android.permission.WAKE_LOCK" uid="cameraserver" />
  162. <assign-permission name="android.permission.UPDATE_DEVICE_STATS" uid="cameraserver" />
  163. <assign-permission name="android.permission.UPDATE_APP_OPS_STATS" uid="cameraserver" />
  164. <assign-permission name="android.permission.GET_PROCESS_STATE_AND_OOM_SCORE" uid="cameraserver" />
  165. <assign-permission name="android.permission.PACKAGE_USAGE_STATS" uid="cameraserver" />
  166. <assign-permission name="android.permission.WATCH_APPOPS" uid="cameraserver" />
  167. <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="graphics" />
  168. <assign-permission name="android.permission.MODIFY_AUDIO_SETTINGS" uid="graphics" />
  169. <assign-permission name="android.permission.DUMP" uid="incidentd" />
  170. <assign-permission name="android.permission.PACKAGE_USAGE_STATS" uid="incidentd" />
  171. <assign-permission name="android.permission.INTERACT_ACROSS_USERS" uid="incidentd" />
  172. <assign-permission name="android.permission.ACCESS_LOWPAN_STATE" uid="lowpan" />
  173. <assign-permission name="android.permission.MANAGE_LOWPAN_INTERFACES" uid="lowpan" />
  174. <assign-permission name="android.permission.DUMP" uid="statsd" />
  175. <assign-permission name="android.permission.PACKAGE_USAGE_STATS" uid="statsd" />
  176. <assign-permission name="android.permission.STATSCOMPANION" uid="statsd" />
  177. <assign-permission name="android.permission.UPDATE_APP_OPS_STATS" uid="statsd" />
  178. /** 第五部分 >>> 库
  179. <library> 标签设置应用可以链接到的库
  180. 可以理解为应用可以调用到的 jar 吧?
  181. 这是可供应用程序代码链接的所有库的列表
  182. */
  183. <!-- This is a list of all the libraries available for application
  184. code to link against. -->
  185. <library name="android.test.base"
  186. file="/system/framework/android.test.base.jar" />
  187. <library name="android.test.mock"
  188. file="/system/framework/android.test.mock.jar" />
  189. <library name="android.test.runner"
  190. file="/system/framework/android.test.runner.jar" />
  191. <library name="javax.obex"
  192. file="/system/framework/javax.obex.jar" />
  193. <library name="org.apache.http.legacy"
  194. file="/system/framework/org.apache.http.legacy.boot.jar" />
  195. /** 第六部分 >>> 省电优化白名单
  196. <allow-in-power-save> 表示这个对应于手机中的省电优化设置
  197. 用这个 tag 配置在这张表中就代表该应用不受省电优化显示 可以在后台访问网络
  198. 对应应用在原生设置中的电源菜单也是灰显 不可设置优化的
  199. 这些是白名单上的标准软件包始终具有互联网功能
  200. 可以在省电模式下访问 即使她们不在前台
  201. 这个 tag 也和 doze mode 有些关系
  202. 就是低耗电模式 什么是低耗电模式:
  203. 如果用户设备未插电源、处于静止状态一段时间且屏幕关闭 设备将进入该模式
  204. 该模式下系统会尝试通过限制应用对网络和 CPU 密集型服务的访问来节省电量
  205. 这还可以阻止引用访问网络并推迟其作业、同步和标准闹铃
  206. 系统会定期退出低耗电模式一会儿 好让应用完成其已推迟的 Activity
  207. 在此维护时段内 系统会运行所有特定同步 作业和闹铃并允许应用访问网络
  208. 在每个维护时段结束后系统会再次进入低耗电模式 暂停网络并推迟作业、同步和闹铃
  209. 随着时间推移 系统安排维护时段的次数越来越少 这有助于设备未连接至充电器情况下长期处于不活动状态时降低电池消耗
  210. 一旦用户通过移动设备、打开屏幕或连接到充电器唤醒设备 系统就会立即退出低耗电模式 并且所有应用都将返回到正常 Activity
  211. 低电耗模式限制:
  212. 暂停访问网络
  213. 系统将忽略 wake locks
  214. 标准 AlarmManager 闹铃将推迟到下一维护时段 包括 setExact() 和 setWindow() 如果需要设置低耗电模式下触发的闹铃请使用 setAndAllowWhileIdle()/setExactAndAllowWhileIdle() 一般情况下使用 setAlarmClock() 设置的闹铃将继续出发 但是系统会在这些闹铃出发之前不久退出低耗电模式
  215. 系统不执行 Wi-Fi 扫描
  216. 系统不允许运行 同步适配器
  217. 系统不允许运行 JobScheduler
  218. 可以使用 dumpsys deviceidle whitelist 命令查看:
  219. cmcc_jiangsu:/ # dumpsys deviceidle whitelist
  220. system-excidle,com.android.providers.downloads,10002
  221. system-excidle,com.android.shell,2000
  222. system,com.android.providers.downloads,10002
  223. system,com.android.shell,2000
  224. cmcc_jiangsu:/ #
  225. */
  226. <!-- These are the standard packages that are white-listed to always have internet
  227. access while in power save mode, even if they aren't in the foreground. -->
  228. <allow-in-power-save package="com.android.providers.downloads" />
  229. /** 第七部分 >>> 数据白名单
  230. 这些是白名单上的标准软件包 在数据模式下始终可以访问互联网 即使她们不在前台
  231. */
  232. <!-- These are the standard packages that are white-listed to always have internet
  233. access while in data mode, even if they aren't in the foreground. -->
  234. <allow-in-data-usage-save package="com.android.providers.downloads" />
  235. /** 第八部分 >>> 省电优化白名单
  236. 这是一个需要在后台自由运行的核心平台组件
  237. <allow-in-power-save-except-idle> 是白名单系统提供商
  238. */
  239. <!-- This is a core platform component that needs to freely run in the background -->
  240. <allow-in-power-save package="com.android.cellbroadcastreceiver" />
  241. <allow-in-power-save package="com.android.shell" />
  242. <!-- Whitelist system providers -->
  243. <allow-in-power-save-except-idle package="com.android.providers.calendar" />
  244. <allow-in-power-save-except-idle package="com.android.providers.contacts" />
  245. /** 第九部分 >>> 系统应用白名单
  246. 这些是白名单上的软件包 可以作为系统用户运行
  247. */
  248. <!-- These are the packages that are white-listed to be able to run as system user -->
  249. <system-user-whitelisted-app package="com.android.settings" />
  250. /** 第十部分 >>> 系统应用黑名单
  251. 这些软件包不应作为系统用户运行
  252. */
  253. <!-- These are the packages that shouldn't run as system user -->
  254. <system-user-blacklisted-app package="com.android.wallpaper.livepicker" />
  255. </permissions>

%%%%%

platform.xml 对应的解析代码

        xml 肯定是需要解析才能用的

/frameworks/core/java/com/android/server/SystemConfig.java

        这个 SystemConfig 就是来解析 platform.xml 然后供一个个系统接口用作返回值的依据:

  1. void readPermissions(File libraryDir, int permissionFlag) {
  2. // Read permissions from given directory.
  3. if (!libraryDir.exists() || !libraryDir.isDirectory()) {
  4. if (permissionFlag == ALLOW_ALL) {
  5. Slog.w(TAG, "No directory " + libraryDir + ", skipping");
  6. }
  7. return;
  8. }
  9. if (!libraryDir.canRead()) {
  10. Slog.w(TAG, "Directory " + libraryDir + " cannot be read");
  11. return;
  12. }
  13. // Iterate over the files in the directory and scan .xml files
  14. File platformFile = null;
  15. for (File f : libraryDir.listFiles()) {
  16. // We'll read platform.xml last
  17. if (f.getPath().endsWith("etc/permissions/platform.xml")) {
  18. platformFile = f;
  19. continue;
  20. }
  21. if (!f.getPath().endsWith(".xml")) {
  22. Slog.i(TAG, "Non-xml file " + f + " in " + libraryDir + " directory, ignoring");
  23. continue;
  24. }
  25. if (!f.canRead()) {
  26. Slog.w(TAG, "Permissions library file " + f + " cannot be read");
  27. continue;
  28. }
  29. readPermissionsFromXml(f, permissionFlag);
  30. }
  31. // Read platform permissions last so it will take precedence
  32. if (platformFile != null) {
  33. readPermissionsFromXml(platformFile, permissionFlag);
  34. }
  35. }
  36. private void readPermissionsFromXml(File permFile, int permissionFlag) {
  37. FileReader permReader = null;
  38. try {
  39. permReader = new FileReader(permFile);
  40. } catch (FileNotFoundException e) {
  41. Slog.w(TAG, "Couldn't find or open permissions file " + permFile);
  42. return;
  43. }
  44. final boolean lowRam = ActivityManager.isLowRamDeviceStatic();
  45. try {
  46. XmlPullParser parser = Xml.newPullParser();
  47. parser.setInput(permReader);
  48. int type;
  49. while ((type=parser.next()) != parser.START_TAG
  50. && type != parser.END_DOCUMENT) {
  51. ;
  52. }
  53. if (type != parser.START_TAG) {
  54. throw new XmlPullParserException("No start tag found");
  55. }
  56. if (!parser.getName().equals("permissions") && !parser.getName().equals("config")) {
  57. throw new XmlPullParserException("Unexpected start tag in " + permFile
  58. + ": found " + parser.getName() + ", expected 'permissions' or 'config'");
  59. }
  60. boolean allowAll = permissionFlag == ALLOW_ALL;
  61. boolean allowLibs = (permissionFlag & ALLOW_LIBS) != 0;
  62. boolean allowFeatures = (permissionFlag & ALLOW_FEATURES) != 0;
  63. boolean allowPermissions = (permissionFlag & ALLOW_PERMISSIONS) != 0;
  64. boolean allowAppConfigs = (permissionFlag & ALLOW_APP_CONFIGS) != 0;
  65. boolean allowPrivappPermissions = (permissionFlag & ALLOW_PRIVAPP_PERMISSIONS) != 0;
  66. boolean allowApiWhitelisting = (permissionFlag & ALLOW_HIDDENAPI_WHITELISTING) != 0;
  67. while (true) {
  68. XmlUtils.nextElement(parser);
  69. if (parser.getEventType() == XmlPullParser.END_DOCUMENT) {
  70. break;
  71. }
  72. String name = parser.getName();
  73. if ("group".equals(name) && allowAll) {
  74. String gidStr = parser.getAttributeValue(null, "gid");
  75. if (gidStr != null) {
  76. int gid = android.os.Process.getGidForName(gidStr);
  77. mGlobalGids = appendInt(mGlobalGids, gid);
  78. } else {
  79. Slog.w(TAG, "<group> without gid in " + permFile + " at "
  80. + parser.getPositionDescription());
  81. }
  82. XmlUtils.skipCurrentTag(parser);
  83. continue;
  84. } else if ("permission".equals(name) && allowPermissions) {
  85. String perm = parser.getAttributeValue(null, "name");
  86. if (perm == null) {
  87. Slog.w(TAG, "<permission> without name in " + permFile + " at "
  88. + parser.getPositionDescription());
  89. XmlUtils.skipCurrentTag(parser);
  90. continue;
  91. }
  92. perm = perm.intern();
  93. readPermission(parser, perm);
  94. } else if ("assign-permission".equals(name) && allowPermissions) {
  95. String perm = parser.getAttributeValue(null, "name");
  96. if (perm == null) {
  97. Slog.w(TAG, "<assign-permission> without name in " + permFile + " at "
  98. + parser.getPositionDescription());
  99. XmlUtils.skipCurrentTag(parser);
  100. continue;
  101. }
  102. String uidStr = parser.getAttributeValue(null, "uid");
  103. if (uidStr == null) {
  104. Slog.w(TAG, "<assign-permission> without uid in " + permFile + " at "
  105. + parser.getPositionDescription());
  106. XmlUtils.skipCurrentTag(parser);
  107. continue;
  108. }
  109. int uid = Process.getUidForName(uidStr);
  110. if (uid < 0) {
  111. Slog.w(TAG, "<assign-permission> with unknown uid \""
  112. + uidStr + " in " + permFile + " at "
  113. + parser.getPositionDescription());
  114. XmlUtils.skipCurrentTag(parser);
  115. continue;
  116. }
  117. perm = perm.intern();
  118. ArraySet<String> perms = mSystemPermissions.get(uid);
  119. if (perms == null) {
  120. perms = new ArraySet<String>();
  121. mSystemPermissions.put(uid, perms);
  122. }
  123. perms.add(perm);
  124. XmlUtils.skipCurrentTag(parser);
  125. } else if ("library".equals(name) && allowLibs) {
  126. String lname = parser.getAttributeValue(null, "name");
  127. String lfile = parser.getAttributeValue(null, "file");
  128. if (lname == null) {
  129. Slog.w(TAG, "<library> without name in " + permFile + " at "
  130. + parser.getPositionDescription());
  131. } else if (lfile == null) {
  132. Slog.w(TAG, "<library> without file in " + permFile + " at "
  133. + parser.getPositionDescription());
  134. } else {
  135. //Log.i(TAG, "Got library " + lname + " in " + lfile);
  136. mSharedLibraries.put(lname, lfile);
  137. }
  138. XmlUtils.skipCurrentTag(parser);
  139. continue;
  140. } else if ("feature".equals(name) && allowFeatures) {
  141. String fname = parser.getAttributeValue(null, "name");
  142. int fversion = XmlUtils.readIntAttribute(parser, "version", 0);
  143. boolean allowed;
  144. if (!lowRam) {
  145. allowed = true;
  146. } else {
  147. String notLowRam = parser.getAttributeValue(null, "notLowRam");
  148. allowed = !"true".equals(notLowRam);
  149. }
  150. if (fname == null) {
  151. Slog.w(TAG, "<feature> without name in " + permFile + " at "
  152. + parser.getPositionDescription());
  153. } else if (allowed) {
  154. addFeature(fname, fversion);
  155. }
  156. XmlUtils.skipCurrentTag(parser);
  157. continue;
  158. } else if ("unavailable-feature".equals(name) && allowFeatures) {
  159. String fname = parser.getAttributeValue(null, "name");
  160. if (fname == null) {
  161. Slog.w(TAG, "<unavailable-feature> without name in " + permFile + " at "
  162. + parser.getPositionDescription());
  163. } else {
  164. mUnavailableFeatures.add(fname);
  165. }
  166. XmlUtils.skipCurrentTag(parser);
  167. continue;
  168. } else if ("allow-in-power-save-except-idle".equals(name) && allowAll) {
  169. String pkgname = parser.getAttributeValue(null, "package");
  170. if (pkgname == null) {
  171. Slog.w(TAG, "<allow-in-power-save-except-idle> without package in "
  172. + permFile + " at " + parser.getPositionDescription());
  173. } else {
  174. mAllowInPowerSaveExceptIdle.add(pkgname);
  175. }
  176. XmlUtils.skipCurrentTag(parser);
  177. continue;
  178. } else if ("allow-in-power-save".equals(name) && allowAll) {
  179. String pkgname = parser.getAttributeValue(null, "package");
  180. if (pkgname == null) {
  181. Slog.w(TAG, "<allow-in-power-save> without package in " + permFile + " at "
  182. + parser.getPositionDescription());
  183. } else {
  184. mAllowInPowerSave.add(pkgname);
  185. }
  186. XmlUtils.skipCurrentTag(parser);
  187. continue;
  188. } else if ("allow-in-data-usage-save".equals(name) && allowAll) {
  189. String pkgname = parser.getAttributeValue(null, "package");
  190. if (pkgname == null) {
  191. Slog.w(TAG, "<allow-in-data-usage-save> without package in " + permFile
  192. + " at " + parser.getPositionDescription());
  193. } else {
  194. mAllowInDataUsageSave.add(pkgname);
  195. }
  196. XmlUtils.skipCurrentTag(parser);
  197. continue;
  198. } else if ("allow-unthrottled-location".equals(name) && allowAll) {
  199. String pkgname = parser.getAttributeValue(null, "package");
  200. if (pkgname == null) {
  201. Slog.w(TAG, "<allow-unthrottled-location> without package in "
  202. + permFile + " at " + parser.getPositionDescription());
  203. } else {
  204. mAllowUnthrottledLocation.add(pkgname);
  205. }
  206. XmlUtils.skipCurrentTag(parser);
  207. continue;
  208. } else if ("allow-implicit-broadcast".equals(name) && allowAll) {
  209. String action = parser.getAttributeValue(null, "action");
  210. if (action == null) {
  211. Slog.w(TAG, "<allow-implicit-broadcast> without action in " + permFile
  212. + " at " + parser.getPositionDescription());
  213. } else {
  214. mAllowImplicitBroadcasts.add(action);
  215. }
  216. XmlUtils.skipCurrentTag(parser);
  217. continue;
  218. } else if ("app-link".equals(name) && allowAppConfigs) {
  219. String pkgname = parser.getAttributeValue(null, "package");
  220. if (pkgname == null) {
  221. Slog.w(TAG, "<app-link> without package in " + permFile + " at "
  222. + parser.getPositionDescription());
  223. } else {
  224. mLinkedApps.add(pkgname);
  225. }
  226. XmlUtils.skipCurrentTag(parser);
  227. } else if ("system-user-whitelisted-app".equals(name) && allowAppConfigs) {
  228. String pkgname = parser.getAttributeValue(null, "package");
  229. if (pkgname == null) {
  230. Slog.w(TAG, "<system-user-whitelisted-app> without package in " + permFile
  231. + " at " + parser.getPositionDescription());
  232. } else {
  233. mSystemUserWhitelistedApps.add(pkgname);
  234. }
  235. XmlUtils.skipCurrentTag(parser);
  236. } else if ("system-user-blacklisted-app".equals(name) && allowAppConfigs) {
  237. String pkgname = parser.getAttributeValue(null, "package");
  238. if (pkgname == null) {
  239. Slog.w(TAG, "<system-user-blacklisted-app without package in " + permFile
  240. + " at " + parser.getPositionDescription());
  241. } else {
  242. mSystemUserBlacklistedApps.add(pkgname);
  243. }
  244. XmlUtils.skipCurrentTag(parser);
  245. } else if ("default-enabled-vr-app".equals(name) && allowAppConfigs) {
  246. String pkgname = parser.getAttributeValue(null, "package");
  247. String clsname = parser.getAttributeValue(null, "class");
  248. if (pkgname == null) {
  249. Slog.w(TAG, "<default-enabled-vr-app without package in " + permFile
  250. + " at " + parser.getPositionDescription());
  251. } else if (clsname == null) {
  252. Slog.w(TAG, "<default-enabled-vr-app without class in " + permFile
  253. + " at " + parser.getPositionDescription());
  254. } else {
  255. mDefaultVrComponents.add(new ComponentName(pkgname, clsname));
  256. }
  257. XmlUtils.skipCurrentTag(parser);
  258. } else if ("backup-transport-whitelisted-service".equals(name) && allowFeatures) {
  259. String serviceName = parser.getAttributeValue(null, "service");
  260. if (serviceName == null) {
  261. Slog.w(TAG, "<backup-transport-whitelisted-service> without service in "
  262. + permFile + " at " + parser.getPositionDescription());
  263. } else {
  264. ComponentName cn = ComponentName.unflattenFromString(serviceName);
  265. if (cn == null) {
  266. Slog.w(TAG,
  267. "<backup-transport-whitelisted-service> with invalid service name "
  268. + serviceName + " in "+ permFile
  269. + " at " + parser.getPositionDescription());
  270. } else {
  271. mBackupTransportWhitelist.add(cn);
  272. }
  273. }
  274. XmlUtils.skipCurrentTag(parser);
  275. } else if ("disabled-until-used-preinstalled-carrier-associated-app".equals(name)
  276. && allowAppConfigs) {
  277. String pkgname = parser.getAttributeValue(null, "package");
  278. String carrierPkgname = parser.getAttributeValue(null, "carrierAppPackage");
  279. if (pkgname == null || carrierPkgname == null) {
  280. Slog.w(TAG, "<disabled-until-used-preinstalled-carrier-associated-app"
  281. + " without package or carrierAppPackage in " + permFile + " at "
  282. + parser.getPositionDescription());
  283. } else {
  284. List<String> associatedPkgs =
  285. mDisabledUntilUsedPreinstalledCarrierAssociatedApps.get(
  286. carrierPkgname);
  287. if (associatedPkgs == null) {
  288. associatedPkgs = new ArrayList<>();
  289. mDisabledUntilUsedPreinstalledCarrierAssociatedApps.put(
  290. carrierPkgname, associatedPkgs);
  291. }
  292. associatedPkgs.add(pkgname);
  293. }
  294. XmlUtils.skipCurrentTag(parser);
  295. } else if ("privapp-permissions".equals(name) && allowPrivappPermissions) {
  296. readPrivAppPermissions(parser);
  297. } else if ("hidden-api-whitelisted-app".equals(name) && allowApiWhitelisting) {
  298. String pkgname = parser.getAttributeValue(null, "package");
  299. if (pkgname == null) {
  300. Slog.w(TAG, "<hidden-api-whitelisted-app> without package in " + permFile
  301. + " at " + parser.getPositionDescription());
  302. } else {
  303. mHiddenApiPackageWhitelist.add(pkgname);
  304. }
  305. XmlUtils.skipCurrentTag(parser);
  306. } else {
  307. XmlUtils.skipCurrentTag(parser);
  308. continue;
  309. }
  310. }
  311. } catch (XmlPullParserException e) {
  312. Slog.w(TAG, "Got exception parsing permissions.", e);
  313. } catch (IOException e) {
  314. Slog.w(TAG, "Got exception parsing permissions.", e);
  315. } finally {
  316. IoUtils.closeQuietly(permReader);
  317. }
  318. // Some devices can be field-converted to FBE, so offer to splice in
  319. // those features if not already defined by the static config
  320. if (StorageManager.isFileEncryptedNativeOnly()) {
  321. addFeature(PackageManager.FEATURE_FILE_BASED_ENCRYPTION, 0);
  322. addFeature(PackageManager.FEATURE_SECURELY_REMOVES_USERS, 0);
  323. }
  324. if (ActivityManager.isLowRamDeviceStatic()) {
  325. addFeature(PackageManager.FEATURE_RAM_LOW, 0);
  326. } else {
  327. addFeature(PackageManager.FEATURE_RAM_NORMAL, 0);
  328. }
  329. for (String featureName : mUnavailableFeatures) {
  330. removeFeature(featureName);
  331. }
  332. }
  333. private void addFeature(String name, int version) {
  334. FeatureInfo fi = mAvailableFeatures.get(name);
  335. if (fi == null) {
  336. fi = new FeatureInfo();
  337. fi.name = name;
  338. fi.version = version;
  339. mAvailableFeatures.put(name, fi);
  340. } else {
  341. fi.version = Math.max(fi.version, version);
  342. }
  343. }
  344. private void removeFeature(String name) {
  345. if (mAvailableFeatures.remove(name) != null) {
  346. Slog.d(TAG, "Removed unavailable feature " + name);
  347. }
  348. }
  349. void readPermission(XmlPullParser parser, String name)
  350. throws IOException, XmlPullParserException {
  351. if (mPermissions.containsKey(name)) {
  352. throw new IllegalStateException("Duplicate permission definition for " + name);
  353. }
  354. final boolean perUser = XmlUtils.readBooleanAttribute(parser, "perUser", false);
  355. final PermissionEntry perm = new PermissionEntry(name, perUser);
  356. mPermissions.put(name, perm);
  357. int outerDepth = parser.getDepth();
  358. int type;
  359. while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
  360. && (type != XmlPullParser.END_TAG
  361. || parser.getDepth() > outerDepth)) {
  362. if (type == XmlPullParser.END_TAG
  363. || type == XmlPullParser.TEXT) {
  364. continue;
  365. }
  366. String tagName = parser.getName();
  367. if ("group".equals(tagName)) {
  368. String gidStr = parser.getAttributeValue(null, "gid");
  369. if (gidStr != null) {
  370. int gid = Process.getGidForName(gidStr);
  371. perm.gids = appendInt(perm.gids, gid);
  372. } else {
  373. Slog.w(TAG, "<group> without gid at "
  374. + parser.getPositionDescription());
  375. }
  376. }
  377. XmlUtils.skipCurrentTag(parser);
  378. }
  379. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/134382
推荐阅读
相关标签
  

闽ICP备14008679号