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


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

    目录

    安卓系统用户管理

    查询用户

    查看用户列表

    查看当前登录用户

    添加用户

    创建新用户

    切换用户

    切换账号

    删除用户

    删除一个账户

    安卓系统用户应用权限

    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 /* 用户 UID10 */
    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. '1.0' encoding='utf-8' standalone='yes' ?>
    3. 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. cmcc_jiangsu:/ #

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

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

    "android.permission.INTERNET" />

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

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

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

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

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

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

    1. "android.permission.WAKE_LOCK" />
    2. "android.permission.INTERNET" />
    3. "android.permission.READ_PHONE_STATE" />
    4. "android.permission.WRITE_EXTERNAL_STORAGE" />

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

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

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

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

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

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

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

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

    1. "android.permission.RECORD_AUDIO" />
    2. "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. <permission android:name="android.permission.ACCESS_WIFI_STATE"
    7. android:description="@string/permdesc_accessWifiState"
    8. android:label="@string/permlab_accessWifiState"
    9. android:protectionLevel="normal" />
    10. <permission android:name="android.permission.SET_TIME"
    11. 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. <uses-permission android:name="android.permission.INTERNET" />
    2. <uses-permission android:name="android.permission.VIBRATE">uses-permission>
    3. <uses-permission android:name="android.permission.DISABLE_KEYGUARD">uses-permission>
    4. <uses-permission android:name="android.permission.CAMERA"/>
    5. <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 有关:

            其中最常用的是

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

    1. <manifest>
    2. <application>
    3. application>
    4. <uses-permission />
    5. <permission />
    6. <permission-tree />
    7. <permission-group />
    8. ...
    9. manifest>

             的作用相似 两者之间的不同之处在于

    是 android 预定义的权限

    是自己定义的权限

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

            定义方法如下:

    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 这个是可选的 与 配合使用
    4.         label, name 和 icon 用于描述权限

             是我们用的最多的 例如短信和电话权限的定义:

    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. /** 第一部分 >>> 警告部分
    2. 说明这个文件是处理普通用户和系统权限之间映射的 如果擅自改动会造成大的安全漏洞
    3. 此文件用于定义较低级别系统之间的映射 管理的用户和组 ID 以及更高级别的权限名称在平台旁。
    4. 编辑此文件时要非常小心!这里犯的错误可能会打开巨大的安全漏洞。
    5. */
    6. <permissions>
    7. /** 第二部分 >>> 权限映射
    8. <permission> 将低等级的 groups id 和权限名称相关联
    9. 通过指定这样的映射 表明了一个授予了给定权限的应用进程将附带这所给的 group id 运行
    10. 因此她可以执行这个群组所允许的读写和执行操作
    11. 以下标记将低级组 ID 与权限名称关联
    12. 通过指定这样一个映射,您的意思是,任何被授予给定权限的应用程序进程也将在其进程附加给定组 ID 的情况下运行
    13. 因此,她可以执行该组允许的任何文件系统 读、写、执行 操作。
    14. */
    15. <permission name="android.permission.BLUETOOTH_ADMIN" >
    16. <group gid="net_bt_admin" />
    17. permission>
    18. <permission name="android.permission.BLUETOOTH" >
    19. <group gid="net_bt" />
    20. permission>
    21. <permission name="android.permission.BLUETOOTH_STACK" >
    22. <group gid="bluetooth" />
    23. <group gid="wakelock" />
    24. <group gid="uhid" />
    25. permission>
    26. <permission name="android.permission.NET_TUNNELING" >
    27. <group gid="vpn" />
    28. permission>
    29. <permission name="android.permission.INTERNET" >
    30. <group gid="inet" />
    31. permission>
    32. <permission name="android.permission.READ_LOGS" >
    33. <group gid="log" />
    34. permission>
    35. <permission name="android.permission.WRITE_MEDIA_STORAGE" >
    36. <group gid="media_rw" />
    37. <group gid="sdcard_rw" />
    38. permission>
    39. <permission name="android.permission.ACCESS_MTP" >
    40. <group gid="mtp" />
    41. permission>
    42. <permission name="android.permission.NET_ADMIN" >
    43. <group gid="net_admin" />
    44. permission>
    45. <permission name="android.permission.ACCESS_CACHE_FILESYSTEM" >
    46. <group gid="cache" />
    47. permission>
    48. <permission name="android.permission.DIAGNOSTIC" >
    49. <group gid="input" />
    50. <group gid="diag" />
    51. permission>
    52. <permission name="android.permission.READ_NETWORK_USAGE_HISTORY">
    53. <group gid="net_bw_stats" />
    54. permission>
    55. <permission name="android.permission.UPDATE_DEVICE_STATS">
    56. <group gid="net_bw_acct" />
    57. permission>
    58. <permission name="android.permission.LOOP_RADIO" >
    59. <group gid="loop_radio" />
    60. permission>
    61. <permission name="android.permission.MANAGE_VOICE_KEYPHRASES">
    62. <group gid="audio" />
    63. permission>
    64. <permission name="android.permission.ACCESS_BROADCAST_RADIO" >
    65. <group gid="media" />
    66. permission>
    67. <permission name="android.permission.USE_RESERVED_DISK">
    68. <group gid="reserved_disk" />
    69. permission>
    70. /** 第三部分 >>> 权限映射的例外部分
    71. 这些权限映射到 GID 但我们需要将其保留在此处 直到支持从 L 升级到当前版本
    72. 这些权限是内置的 在 L 中没有存储在包中
    73. 如果在解析包时未在此处定义 则返回 xml
    74. xml 我们将忽略授予应用程序的这些权限 而不传播授予的状态
    75. 从 N 开始 我们将内置权限存储在包中
    76. 与脆弱性相比 作为保存的存储的 xml 可以忽略不计 带有权限的一个标记
    77. 因为可以删除不再需要映射到 GID 和中断授权传播的内置权限
    78. */
    79. <permission name="android.permission.READ_EXTERNAL_STORAGE" />
    80. <permission name="android.permission.WRITE_EXTERNAL_STORAGE" />
    81. /** 第四部分 >>> 分配权限
    82. <assign-permission> 有些用户比较特殊 她们是系统核心用户
    83. Android 会分配特定的高级权限来允许她们来完成一些高级的操作
    84. 比如 shell 用户有很多权限 这是因为开发者需要比较开放的环境来和 system 进行交互
    85. shell 用户的权限有时候需要 adb root/adb remount 才能享受
    86. 对应的需要 userdebug 或者 root 版本
    87. user 版本下 shell 命令还是有所限制的
    88. */
    89. <assign-permission name="android.permission.MODIFY_AUDIO_SETTINGS" uid="media" />
    90. <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="media" />
    91. <assign-permission name="android.permission.WAKE_LOCK" uid="media" />
    92. <assign-permission name="android.permission.UPDATE_DEVICE_STATS" uid="media" />
    93. <assign-permission name="android.permission.UPDATE_APP_OPS_STATS" uid="media" />
    94. <assign-permission name="android.permission.GET_PROCESS_STATE_AND_OOM_SCORE" uid="media" />
    95. <assign-permission name="android.permission.MODIFY_AUDIO_SETTINGS" uid="audioserver" />
    96. <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="audioserver" />
    97. <assign-permission name="android.permission.WAKE_LOCK" uid="audioserver" />
    98. <assign-permission name="android.permission.UPDATE_DEVICE_STATS" uid="audioserver" />
    99. <assign-permission name="android.permission.UPDATE_APP_OPS_STATS" uid="audioserver" />
    100. <assign-permission name="android.permission.PACKAGE_USAGE_STATS" uid="audioserver" />
    101. <assign-permission name="android.permission.MODIFY_AUDIO_SETTINGS" uid="cameraserver" />
    102. <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="cameraserver" />
    103. <assign-permission name="android.permission.WAKE_LOCK" uid="cameraserver" />
    104. <assign-permission name="android.permission.UPDATE_DEVICE_STATS" uid="cameraserver" />
    105. <assign-permission name="android.permission.UPDATE_APP_OPS_STATS" uid="cameraserver" />
    106. <assign-permission name="android.permission.GET_PROCESS_STATE_AND_OOM_SCORE" uid="cameraserver" />
    107. <assign-permission name="android.permission.PACKAGE_USAGE_STATS" uid="cameraserver" />
    108. <assign-permission name="android.permission.WATCH_APPOPS" uid="cameraserver" />
    109. <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="graphics" />
    110. <assign-permission name="android.permission.MODIFY_AUDIO_SETTINGS" uid="graphics" />
    111. <assign-permission name="android.permission.DUMP" uid="incidentd" />
    112. <assign-permission name="android.permission.PACKAGE_USAGE_STATS" uid="incidentd" />
    113. <assign-permission name="android.permission.INTERACT_ACROSS_USERS" uid="incidentd" />
    114. <assign-permission name="android.permission.ACCESS_LOWPAN_STATE" uid="lowpan" />
    115. <assign-permission name="android.permission.MANAGE_LOWPAN_INTERFACES" uid="lowpan" />
    116. <assign-permission name="android.permission.DUMP" uid="statsd" />
    117. <assign-permission name="android.permission.PACKAGE_USAGE_STATS" uid="statsd" />
    118. <assign-permission name="android.permission.STATSCOMPANION" uid="statsd" />
    119. <assign-permission name="android.permission.UPDATE_APP_OPS_STATS" uid="statsd" />
    120. /** 第五部分 >>> 库
    121. <library> 标签设置应用可以链接到的库
    122. 可以理解为应用可以调用到的 jar 吧?
    123. 这是可供应用程序代码链接的所有库的列表
    124. */
    125. <library name="android.test.base"
    126. file="/system/framework/android.test.base.jar" />
    127. <library name="android.test.mock"
    128. file="/system/framework/android.test.mock.jar" />
    129. <library name="android.test.runner"
    130. file="/system/framework/android.test.runner.jar" />
    131. <library name="javax.obex"
    132. file="/system/framework/javax.obex.jar" />
    133. <library name="org.apache.http.legacy"
    134. file="/system/framework/org.apache.http.legacy.boot.jar" />
    135. /** 第六部分 >>> 省电优化白名单
    136. <allow-in-power-save> 表示这个对应于手机中的省电优化设置
    137. 用这个 tag 配置在这张表中就代表该应用不受省电优化显示 可以在后台访问网络
    138. 对应应用在原生设置中的电源菜单也是灰显 不可设置优化的
    139. 这些是白名单上的标准软件包始终具有互联网功能
    140. 可以在省电模式下访问 即使她们不在前台
    141. 这个 tag 也和 doze mode 有些关系
    142. 就是低耗电模式 什么是低耗电模式:
    143. 如果用户设备未插电源、处于静止状态一段时间且屏幕关闭 设备将进入该模式
    144. 该模式下系统会尝试通过限制应用对网络和 CPU 密集型服务的访问来节省电量
    145. 这还可以阻止引用访问网络并推迟其作业、同步和标准闹铃
    146. 系统会定期退出低耗电模式一会儿 好让应用完成其已推迟的 Activity
    147. 在此维护时段内 系统会运行所有特定同步 作业和闹铃并允许应用访问网络
    148. 在每个维护时段结束后系统会再次进入低耗电模式 暂停网络并推迟作业、同步和闹铃
    149. 随着时间推移 系统安排维护时段的次数越来越少 这有助于设备未连接至充电器情况下长期处于不活动状态时降低电池消耗
    150. 一旦用户通过移动设备、打开屏幕或连接到充电器唤醒设备 系统就会立即退出低耗电模式 并且所有应用都将返回到正常 Activity
    151. 低电耗模式限制:
    152. 暂停访问网络
    153. 系统将忽略 wake locks
    154. 标准 AlarmManager 闹铃将推迟到下一维护时段 包括 setExact() 和 setWindow() 如果需要设置低耗电模式下触发的闹铃请使用 setAndAllowWhileIdle()/setExactAndAllowWhileIdle() 一般情况下使用 setAlarmClock() 设置的闹铃将继续出发 但是系统会在这些闹铃出发之前不久退出低耗电模式
    155. 系统不执行 Wi-Fi 扫描
    156. 系统不允许运行 同步适配器
    157. 系统不允许运行 JobScheduler
    158. 可以使用 dumpsys deviceidle whitelist 命令查看:
    159. cmcc_jiangsu:/ # dumpsys deviceidle whitelist
    160. system-excidle,com.android.providers.downloads,10002
    161. system-excidle,com.android.shell,2000
    162. system,com.android.providers.downloads,10002
    163. system,com.android.shell,2000
    164. cmcc_jiangsu:/ #
    165. */
    166. <allow-in-power-save package="com.android.providers.downloads" />
    167. /** 第七部分 >>> 数据白名单
    168. 这些是白名单上的标准软件包 在数据模式下始终可以访问互联网 即使她们不在前台
    169. */
    170. <allow-in-data-usage-save package="com.android.providers.downloads" />
    171. /** 第八部分 >>> 省电优化白名单
    172. 这是一个需要在后台自由运行的核心平台组件
    173. <allow-in-power-save-except-idle> 是白名单系统提供商
    174. */
    175. <allow-in-power-save package="com.android.cellbroadcastreceiver" />
    176. <allow-in-power-save package="com.android.shell" />
    177. <allow-in-power-save-except-idle package="com.android.providers.calendar" />
    178. <allow-in-power-save-except-idle package="com.android.providers.contacts" />
    179. /** 第九部分 >>> 系统应用白名单
    180. 这些是白名单上的软件包 可以作为系统用户运行
    181. */
    182. <system-user-whitelisted-app package="com.android.settings" />
    183. /** 第十部分 >>> 系统应用黑名单
    184. 这些软件包不应作为系统用户运行
    185. */
    186. <system-user-blacklisted-app package="com.android.wallpaper.livepicker" />
    187. 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, " 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, " 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, " 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, " 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, " with unknown uid \""
    112. + uidStr + " in " + permFile + " at "
    113. + parser.getPositionDescription());
    114. XmlUtils.skipCurrentTag(parser);
    115. continue;
    116. }
    117. perm = perm.intern();
    118. ArraySet perms = mSystemPermissions.get(uid);
    119. if (perms == null) {
    120. perms = new ArraySet();
    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, " without name in " + permFile + " at "
    130. + parser.getPositionDescription());
    131. } else if (lfile == null) {
    132. Slog.w(TAG, " 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, " 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, " 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, " 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, " 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, " 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, " 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, " 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, " 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, " 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, " + 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, " + permFile
    250. + " at " + parser.getPositionDescription());
    251. } else if (clsname == null) {
    252. Slog.w(TAG, " + 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, " 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. " 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, "
    281. + " without package or carrierAppPackage in " + permFile + " at "
    282. + parser.getPositionDescription());
    283. } else {
    284. List 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, " 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, " without gid at "
    374. + parser.getPositionDescription());
    375. }
    376. }
    377. XmlUtils.skipCurrentTag(parser);
    378. }
    379. }

  • 相关阅读:
    JavaScript基本概念
    OpenCV读取图像时按照BGR的顺序HWC排列,PyTorch按照RGB的顺序CHW排列
    用户行为分析(如何用数据驱动增长)-读书笔记1
    当前JavaEE初阶的阶段知识总结
    不推荐“溜溜球节食法”的10个理由
    MySQL基础
    接口测试,
    django 开启CSRFtoken校验,以及postman实现问题
    进程相关介绍(二)
    项目管理的核心:制定明确的项目进度计划
  • 原文地址:https://blog.csdn.net/m0_67268286/article/details/125959320