资讯详情

[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-grup.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 对应的解析代码


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

安卓系统用户管理

——————————

查询用户

%%%%%

查看用户列表

cmcc_jiangsu:/ # pm list users
Users:
        UserInfo{0:机主:13} running
cmcc_jiangsu:/ # 

%%%%%

查看当前登录用户

cmcc_jiangsu:/ # whoami
root
cmcc_jiangsu:/ # 

——————————

添加用户

        非常注意:

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

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

%%%%%

创建新用户

        语法如下:

pm create-user 用户名

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

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

        无奈只好换上旧手机:

C:\Users\byme>adb devices    /* USB 插上之后查看连接状态 */
List of devices attached
8OOXXOOXXxxooxxF        device


C:\Users\byme>adb root    /* 看来无法获得 root 权限 */
adbd cannot run as root in production builds

C:\Users\byme>adb shell
shell@GIONEE_G1605A:/ $ pm list users    /* 查看用户列表 */
Users:
        UserInfo{0:机主:13} running
shell@GIONEE_G1605A:/ $ whoami    /* 查看登陆账户 */
shell
shell@GIONEE_G1605A:/ $ pm create-user "ranchui"    /* 创建用户燃吹 */
Success: created user id 10
1|shell@GIONEE_G1605A:/ $ pm list users    /* 用户 UID 是 10 */
Users:
        UserInfo{0:机主:13} running
        UserInfo{10:ranchui:0}
shell@GIONEE_G1605A:/ $ 

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

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

——————————

切换用户

%%%%%

切换账号

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

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

        启动指定用户:

shell@GIONEE_G1605A:/ $ pm list users    /* 当前 ranchui 未上线 */
Users:
        UserInfo{0:机主:13} running
        UserInfo{10:ranchui:0}
shell@GIONEE_G1605A:/ $ am start-user 10    /* 根据 UID 启用用户 ranchui */
Success: user started
shell@GIONEE_G1605A:/ $ pm list users    /* 用户 ranchui 已经在线 */
Users:
        UserInfo{0:机主:13} running
        UserInfo{10:ranchui:10} running
shell@GIONEE_G1605A:/ $ 

        切换成指定用户:

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

        正在切换用户:

正在切换用户

        然后就发现无法调试了:

shell@GIONEE_G1605A:/ $     /* 这边莫名退出去了 */
C:\Users\byme>adb shell    /* 查看连接还在 但是不支持调试 */
adb.exe: device unauthorized.
This adb server's $ADB_VENDOR_KEYS is not set
Try 'adb kill-server' if that seems wrong.
Otherwise check for a confirmation dialog on your device.

C:\Users\byme>adb kill-server    /* 关掉一次 adb */

C:\Users\byme>adb devices    /* 发现不是 device 是个未经授权的 unauthorized */
* daemon not running; starting now at tcp:5037
* daemon started successfully
List of devices attached
8ooxxOOOXXXooxxF        unauthorized


C:\Users\byme>

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

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

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

C:\Users\byme>adb devices    /* 此时还未授权 */
List of devices attached
8ooxxOOOXXXooxxF        unauthorized


C:\Users\byme>adb devices    /* 授权过后 */
List of devices attached
8ooxxOOOXXXooxxF        device


C:\Users\byme>

——————————

删除用户

%%%%%

删除一个账户

        语法如下:

pm remove-user USER_ID

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

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

    Android 在创建每个用户时 都会分配一个整型的 userId
    对于主用户 就是正常下的默认用户 来说 userId 为 0
    之后创建的 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 :

cmcc_jiangsu:/ # ps -A | grep system_server    /* 得到 PID 为 3620 */
system        3620  2604 1386312 181192 SyS_epoll_wait      0 S system_server
cmcc_jiangsu:/ # cat /proc/3620/status    /* 查看该进程的 status */
Name:   system_server
Umask:  0077
State:  S (sleeping)
Tgid:   3620
Ngid:   0
Pid:    3620
PPid:   2604
TracerPid:      0
Uid:    1000    1000    1000    1000
Gid:    1000    1000    1000    1000
FDSize: 512
Groups: 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1018 1021 1023 1024 10
32 1065 3001 3002 3003 3006 3007 3009 3010
VmPeak:  1419816 kB
VmSize:  1386312 kB
VmLck:         0 kB
VmPin:         0 kB
VmHWM:    206464 kB
VmRSS:    181088 kB
RssAnon:           15028 kB
RssFile:          165708 kB
RssShmem:            352 kB
VmData:  1018244 kB
VmStk:      8192 kB
VmExe:        24 kB
VmLib:     80572 kB
VmPTE:       524 kB
VmPMD:         0 kB
VmSwap:        0 kB
Threads:        97
SigQ:   0/10948
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000001204
SigIgn: 0000000000000001
SigCgt: 00000006400084f8
CapInh: 0000001806897c20
CapPrm: 0000001806897c20
CapEff: 0000001806897c20
CapBnd: 0000000000000000
CapAmb: 0000000000000000
Seccomp:        0
Speculation_Store_Bypass:       unknown
Cpus_allowed:   f
Cpus_allowed_list:      0-3
Mems_allowed:   1
Mems_allowed_list:      0
voluntary_ctxt_switches:        2526
nonvoluntary_ctxt_switches:     1818
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 目录:

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

%%%%%

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

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

        也是以用户 UID 命名

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

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

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

cmcc_jiangsu:/ # ls /data/user -alh
total 6.0K
drwx--x--x  2 system system 4.0K 2015-01-01 08:00 .
drwxrwx--x 40 system system 4.0K 2015-01-01 08:00 ..
lrwxrwxrwx  1 root   root     10 2015-01-01 08:00 0 -> /data/data
cmcc_jiangsu:/ # ls -l /data/user/0/
android.ext.services/                   com.android.sharedstoragebackup/
android.ext.shared/                     com.android.shell/
android/                                com.android.statementservice/
com.android.backupconfirm/              com.android.superuser/
com.android.bluetooth/                  com.android.systemui/
com.android.certinstaller/              com.android.vpndialogs/
com.android.companiondevicemanager/     com.android.webview/
com.android.defcontainer/               com.cmcc.mid.softdetector/
com.android.externalstorage/            com.dangbei.tvlauncher/
com.android.inputdevices/               com.dangbeimarket/
com.android.inputmethod.latin/          com.droidlogic.BluetoothRemote/
com.android.keychain/                   com.droidlogic.inputmethod.remote/
com.android.location.fused/             com.droidlogic/
com.android.managedprovisioning/        com.fengyun.live/
com.android.packageinstaller/           com.iflytek.bt.auto/
com.android.pacprocessor/               com.iflytek.xiri/
com.android.providers.downloads/        com.iflytek.xiri2.system/
com.android.providers.media/            com.mylejia.store/
com.android.providers.settings/         com.tv.kuaisou/
com.android.proxyhandler/               com.xiaodianshi.tv.yst/
com.android.se/                         jackpal.androidterm/
com.android.settings/                   me.thomastv.rebootupdate/
cmcc_jiangsu:/ # ls -lh /data/user/0/com.android.shell/
total 4.0K
drwxrws--x 2 shell shell 4.0K 2015-01-01 08:00 cache
drwxrws--x 2 shell shell 4.0K 2015-01-01 08:00 code_cache
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 中:

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

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

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

        第三步 准备文件系统

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

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

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

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

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

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

cmcc_jiangsu:/ # ls /data/user/0/
android                            com.android.sharedstoragebackup
android.ext.services               com.android.shell
android.ext.shared                 com.android.statementservice
com.android.backupconfirm          com.android.superuser
com.android.bluetooth              com.android.systemui
com.android.certinstaller          com.android.vpndialogs
com.android.companiondevicemanager com.android.webview
com.android.defcontainer           com.cmcc.mid.softdetector
com.android.externalstorage        com.dangbei.tvlauncher
com.android.inputdevices           com.dangbeimarket
com.android.inputmethod.latin      com.droidlogic
com.android.keychain               com.droidlogic.BluetoothRemote
com.android.location.fused         com.droidlogic.inputmethod.remote
com.android.managedprovisioning    com.fengyun.live
com.android.packageinstaller       com.iflytek.bt.auto
com.android.pacprocessor           com.iflytek.xiri
com.android.providers.downloads    com.iflytek.xiri2.system
com.android.providers.media        com.mylejia.store
com.android.providers.settings     com.tv.kuaisou
com.android.proxyhandler           com.xiaodianshi.tv.yst
com.android.se                     jackpal.androidterm
com.android.settings               me.thomastv.rebootupdate
cmcc_jiangsu:/ # 

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

cmcc_jiangsu:/ # cat /data/system/users/0/package-restrictions.xml
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<package-restrictions>
    <pkg name="com.iflytek.xiri" ceDataInode="-4294967186" />
    <pkg name="com.droidlogic.inputmethod.remote" ceDataInode="-4294967182" />
    <pkg name="com.xiaodianshi.tv.yst" ceDataInode="-4294966764" />
    <pkg name="com.android.providers.media" ceDataInode="-4294967179" />
    <pkg name="com.mylejia.store" ceDataInode="-4294966914" stopped="true" nl="t
rue" />
    <pkg name="com.android.externalstorage" ceDataInode="-4294967176" />
    <pkg name="com.android.companiondevicemanager" ceDataInode="-4294967173" />
    <pkg name="com.android.providers.downloads" ceDataInode="-4294967170" />
    <pkg name="com.fengyun.live" ceDataInode="-4294966943" stopped="true" nl="tr
ue" />
    <pkg name="com.droidlogic" ceDataInode="-4294967167" />
    <pkg name="com.dangbei.tvlauncher" ceDataInode="-4294967163" />
    <pkg name="com.android.defcontainer" ceDataInode="-4294967266" />
    <pkg name="com.android.pacprocessor" ceDataInode="-4294967160" />
    <pkg name="com.android.certinstaller" ceDataInode="-4294967156" />
    <pkg name="me.thomastv.rebootupdate" ceDataInode="-4294966923" />
    <pkg name="android" ceDataInode="-4294967258" />
    <pkg name="com.android.backupconfirm" ceDataInode="-4294967153" />
    <pkg name="com.android.statementservice" ceDataInode="-4294967150" />
    <pkg name="com.android.superuser" ceDataInode="-4294967147" />
    <pkg name="com.android.providers.settings" ceDataInode="-4294967250" />
    <pkg name="com.android.sharedstoragebackup" ceDataInode="-4294967144" />
    <pkg name="com.iflytek.xiri2.system" ceDataInode="-4294967141" />
    <pkg name="com.android.webview" ceDataInode="-4294967137" enabled="1" />
    <pkg name="com.android.se" ceDataInode="-4294967133" />
    <pkg name="com.android.inputdevices" ceDataInode="-4294967242" />
    <pkg name="com.droidlogic.BluetoothRemote" ceDataInode="-4294967128" />
    <pkg name="android.ext.shared" ceDataInode="-4294967235" />
    <pkg name="com.android.keychain" ceDataInode="-4294967123" />
    <pkg name="android.ext.services" ceDataInode="-4294967229" />
    <pkg name="com.android.packageinstaller" ceDataInode="-4294967223" />
    <pkg name="com.android.proxyhandler" ceDataInode="-4294967217" />
    <pkg name="com.android.inputmethod.latin" ceDataInode="-4294967210">
        <disabled-components>
            <item name="com.android.inputmethod.latin.setup.SetupActivity" />
        </disabled-components>
    </pkg>
    <pkg name="com.android.managedprovisioning" ceDataInode="-4294967118" />
    <pkg name="jackpal.androidterm" ceDataInode="-4294966708" />
    <pkg name="com.iflytek.bt.auto" ceDataInode="-4294967115" />
    <pkg name="com.android.settings" ceDataInode="-4294967112" />
    <pkg name="com.android.vpndialogs" ceDataInode="-4294967108" />
    <pkg name="com.android.shell" ceDataInode="-4294967203" />
    <pkg name="com.dangbeimarket" ceDataInode="-4294966928" />
    <pkg name="com.android.location.fused" ceDataInode="-4294967196" />
    <pkg name="com.android.systemui" ceDataInode="-4294967189">
        <disabled-components>
            <item name="com.android.systemui.tuner.TunerActivity" />
        </disabled-components>
    </pkg>
    <pkg name="com.tv.kuaisou" ceDataInode="-4294966800" stopped="true" nl="true
" />
    <pkg name="com.android.bluetooth" ceDataInode="-4294967104" enabled="1" />
    <pkg name="com.cmcc.mid.softdetector" ceDataInode="-4294967100" />
    <preferred-activities />
    <persistent-preferred-activities />
    <crossProfile-intent-filters />
    <default-apps />
</package-restrictions>
cmcc_jiangsu:/ # 

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

cmcc_jiangsu:/ # cat /data/system/packages.list
com.iflytek.xiri 10021 0 /data/user/0/com.iflytek.xiri default:targetSdkVersion=19 3002,3003,3001
com.droidlogic.inputmethod.remote 10022 0 /data/user/0/com.droidlogic.inputmethod.remote default:targetSdkVersion=28 none
com.xiaodianshi.tv.yst 10032 0 /data/user_de/0/com.xiaodianshi.tv.yst default:targetSdkVersion=26 3003
com.android.providers.media 10002 0 /data/user/0/com.android.providers.media media:privapp:targetSdkVersion=28 2001,1065,1023,1015,3003,3007,1024
com.mylejia.store 10026 0 /data/user_de/0/com.mylejia.store default:targetSdkVersion=24 3003,1007
com.android.externalstorage 10004 0 /data/user/0/com.android.externalstorage platform:privapp:targetSdkVersion=28 1023,1015
com.android.companiondevicemanager 10012 0 /data/user/0/com.android.companiondevicemanager default:targetSdkVersion=28 3002,3001
com.android.providers.downloads 10002 0 /data/user/0/com.android.providers.downloads media:privapp:targetSdkVersion=28 2001,1065,1023,1015,3003,3007,1024
com.fengyun.live 10027 0 /data/user_de/0/com.fengyun.live default:targetSdkVersion=24 3003
com.droidlogic 1000 0 /data/user/0/com.droidlogic platform:privapp:targetSdkVersion=28 1065,3002,1023,1015,3003,3001,1007
com.dangbei.tvlauncher 10016 0 /data/user/0/com.dangbei.tvlauncher default:targetSdkVersion=22 3002,3003,3001
com.android.defcontainer 10000 0 /data/user_de/0/com.android.defcontainer platform:privapp:targetSdkVersion=28 2001
com.android.pacprocessor 10017 0 /data/user/0/com.android.pacprocessor platform:targetSdkVersion=28 3003
com.android.certinstaller 10013 0 /data/user/0/com.android.certinstaller platform:targetSdkVersion=28 none
me.thomastv.rebootupdate 10024 0 /data/user_de/0/me.thomastv.rebootupdate default:targetSdkVersion=25 none
android 1000 0 /data/system platform:privapp:targetSdkVersion=28 1065,3002,1023,1015,3003,3001,1007
com.android.backupconfirm 10001 0 /data/user/0/com.android.backupconfirm platform:privapp:targetSdkVersion=28 none
com.android.statementservice 10009 0 /data/user/0/com.android.statementservice default:privapp:targetSdkVersion=28 3003
com.android.superuser 10019 1 /data/user/0/com.android.superuser default:targetSdkVersion=22 none
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
com.android.sharedstoragebackup 10007 0 /data/user/0/com.android.sharedstoragebackup platform:privapp:targetSdkVersion=28 1023,1015
com.iflytek.xiri2.system 1000 0 /data/user/0/com.iflytek.xiri2.system platform:privapp:targetSdkVersion=28 1065,3002,1023,1015,3003,3001,1007
com.android.webview 10023 0 /data/user/0/com.android.webview default:targetSdkVersion=28 3003
com.android.se 1068 0 /data/user/0/com.android.se platform:privapp:targetSdkVersion=28 none
com.android.inputdevices 1000 0 /data/user_de/0/com.android.inputdevices platform:privapp:targetSdkVersion=28 1065,3002,1023,1015,3003,3001,1007
com.droidlogic.BluetoothRemote 1000 0 /data/user/0/com.droidlogic.BluetoothRemote platform:privapp:targetSdkVersion=28 1065,3002,1023,1015,3003,3001,1007
android.ext.shared 10015 0 /data/user_de/0/android.ext.shared platform:targetSdkVersion=28 none
com.android.keychain 1000 0 /data/user/0/com.android.keychain platform:privapp:targetSdkVersion=28 1065,3002,1023,1015,3003,3001,1007
android.ext.services 10003 0 /data/user_de/0/android.ext.services platform:privapp:targetSdkVersion=28 none
com.android.packageinstaller 10008 0 /data/user_de/0/com.android.packageinstaller platform:privapp:targetSdkVersion=28 1065
com.android.proxyhandler 10006 0 /data/user_de/0/com.android.proxyhandler platform:privapp:targetSdkVersion=28 3003
com.android.inputmethod.latin 10020 0 /data/user_de/0/com.android.inputmethod.latin default:targetSdkVersion=23 none
com.android.managedprovisioning 10005 0 /data/user/0/com.android.managedprovisioning platform:privapp:targetSdkVersion=28 3003
jackpal.androidterm 10031 0 /data/user_de/0/jackpal.androidterm default:targetSdkVersion=22 3003
com.iflytek.bt.auto 10014 0 /data/user/0/com.iflytek.bt.auto default:targetSdkVersion=28 3002,3001
com.android.settings 1000 1 /data/user/0/com.android.settings platform:privapp:targetSdkVersion=28 1065,3002,1023,1015,3003,3001,1007
com.android.vpndialogs 10010 0 /data/user/0/com.android.vpndialogs platform:privapp:targetSdkVersion=28 none
com.android.shell 2000 0 /data/user_de/0/com.android.shell platform:privapp:targetSdkVersion=28 1065,3002,1023,1015,1002,3010,3011
com.dangbeimarket 10025 0 /data/user_de/0/com.dangbeimarket default:targetSdkVersion=19 3002,3003,3001
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
com.android.systemui 10011 0 /data/user_de/0/com.android.systemui platform:privapp:targetSdkVersion=28 1065,3002,1023,1015,3001,3006
com.tv.kuaisou 10028 0 /data/user_de/0/com.tv.kuaisou default:targetSdkVersion=22 3002,3003,3001
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
com.cmcc.mid.softdetector 10018 0 /data/user/0/com.cmcc.mid.softdetector default:targetSdkVersion=17 3003
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

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

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

        解冻屏幕和输入

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

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

        第七步 完成切换用户

        如果是后台切换

        则直接调用 UserController.finishUserBoot()

        如果是前台切换

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

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

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

        设置切换用户的状态为 STATE_RUNNING_LOCKED

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

——————————

应用权限记录

%%%%%

安装时权限存储位置

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

/data/system/packages.xml

cmcc_jiangsu:/ # cat /data/system/packages.xml | grep xiaodianshi    /* 查看关于 bilibili tv 的权限 */
        <item name="com.xiaodianshi.tv.yst.permission.BLKV" package="com.xiaodia
nshi.tv.yst" protection="2" />
    <package name="com.xiaodianshi.tv.yst" codePath="/data/app/com.xiaodianshi.t
v.yst-Gq1cdiX3Aho20N4EPrC5gw==" nativeLibraryPath="/data/app/com.xiaodianshi.tv.
yst-Gq1cdiX3Aho20N4EPrC5gw==/lib" primaryCpuAbi="armeabi-v7a" publicFlags="94530
7204" privateFlags="0" ft="1822bb3ec60" it="1822bb3f274" ut="1822bb3f274" versio
n="105100" userId="10030">
            <item name="com.xiaodianshi.tv.yst.permission.BLKV" granted="true" f
lags="0" />
cmcc_jiangsu:/ # cat /data/system/packages.xml | grep jackpal.androidterm
        <item name="jackpal.androidterm.permission.PREPEND_TO_PATH" package="jac
kpal.androidterm" protection="1" />
        <item name="jackpal.androidterm.permission.RUN_SCRIPT" package="jackpal.
androidterm" protection="1" />
        <item name="jackpal.androidterm.permission.APPEND_TO_PATH" package="jack
pal.androidterm" protection="1" />
    <package name="jackpal.androidterm" codePath="/data/app/jackpal.androidterm-
sAgHElvcbHuZtUuQdCSIdQ==" nativeLibraryPath="/data/app/jackpal.androidterm-sAgHE
lvcbHuZtUuQdCSIdQ==/lib" primaryCpuAbi="armeabi" publicFlags="940097092" private
Flags="0" ft="1822bc31730" it="1822bc31983" ut="1822bc31983" version="71" userId
="10031">
cmcc_jiangsu:/ # pm list packages -3    /* 查看第三方应用 */
package:com.xiaodianshi.tv.yst
package:com.mylejia.store
package:com.fengyun.live
package:me.thomastv.rebootupdate
package:jackpal.androidterm
package:com.dangbeimarket
package:com.tv.kuaisou
cmcc_jiangsu:/ # cat /data/system/packages.xml  | grep com.dangbeimarket    /* 查看当贝市场权限 */
        <item name="baidu.push.permission.WRITE_PUSHINFOPROVIDER.com.dangbeimark
et" package="com.dangbeimarket" protection="2" />
        <item name="com.dangbeimarket.permission.JPUSH_MESSAGE" package="com.dan
gbeimarket" protection="2" />
        <item name="com.dangbeimarket.permission.MIPUSH_RECEIVE" package="com.da
ngbeimarket" protection="2" />
    <package name="com.dangbeimarket" codePath="/data/app/com.dangbeimarket-Gvch
ZCDlwKegHBtoXBQhwg==" nativeLibraryPath="/data/app/com.dangbeimarket-GvchZCDlwKe
gHBtoXBQhwg==/lib" primaryCpuAbi="armeabi-v7a" publicFlags="945307204" privateFl
ags="0" ft="14aa2cb6b80" it="14aa2cb6f96" ut="14aa2cb6f96" version="286" userId=
"10025">
            <item name="baidu.push.permission.WRITE_PUSHINFOPROVIDER.com.dangbei
market" granted="true" flags="0" />
            <item name="com.dangbeimarket.permission.JPUSH_MESSAGE" granted="tru
e" flags="0" />
            <item name="com.dangbeimarket.permission.MIPUSH_RECEIVE" granted="tr
ue" flags="0" />
cmcc_jiangsu:/ # 

%%%%%

运行时权限存储位置

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

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

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

%%%%%

权限声明存储位置

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

/etc/permissions/

        目录下:

cmcc_jiangsu:/ # ls /etc/permissions/
android.hardware.bluetooth.xml    com.android.media.remotedisplay.xml
android.hardware.bluetooth_le.xml com.android.mediadrm.signer.xml
android.hardware.hdmi.cec.xml     platform.xml
android.software.webview.xml      privapp-permissions-platform.xml
com.android.location.provider.xml
cmcc_jiangsu:/ # 

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

cat /etc/permissions/platform.xml | more

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

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

——————————

权限控制

%%%%%

授予/移除 权限

        语法如下:

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

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

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

        其她常用权限:

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

%%%%%

User ID 和 Group ID

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

        关于用户 ID

    我们在安装一个应用的时候系统就会为这个应用分配一个 userid
这个 userid 是全局唯一的
	在同一 Android 系统的机器上不可能存在两个相同 userid 的应用
	也就是说 userid 对于一个应用来说是唯一不变的 除非你卸载重新安装了该应用
但是 userid 并不像 MAC 地址一样是全球唯一的 同一个应用在不同的设备上 userid 可能会不同
	这里所说的唯一是指在同一个 Android 设备上

	Android 的安全机制是进程级别的
	通常情况下一个应用就是一个进程
	并且一个应用也只有一个进程
	当然应用内实现多进程这个是没有任何问题的
	这里是说一般情况下
应用 A 是无法直接运行在应用 B 的进程当中的

	但是有一点就是除非应用 A 和应用 B 使用了相同的 shareduserid
	配置了相同的 shareduserid 的应用被系统视作同一个应用 对应的 userid 和权限都是相同的
	但是如果仅仅是配置了相同的 shareduserid 就能够到达目的 显然这是一个很大的漏洞
	为此谷歌做了另外一个限制 就是必须保证签名一致
	一般的 A 公司的签名肯定是跟 B 公司的签名是不一样的
	也就是说想要应用 A 和应用 B 运行在同一个进程当中那么肯定得保证签名和 shareduserid 是一致的
	shareduserid 保持一致这个很容易满足 但是签名一致恐怕只能是同一个公司

	应用的数据和 user id 是相对应的 默认情况下其她应用是无法访问的
	但是如果我们设置了 MODE_WORLD_READABLE 或者 MODE_WORLD_WRITEABLE 的 flag
	那么其她应用就可以变得可读可写了 也就是说这些数据就变成了全局的数据

	我们知道 Android 系统从 4.2 版本开始支持多用户
	也就产生了用户 id 的概念 uid
	在这里 uid 和 userid 是两个完全不同的概念
	android 中的用户是存在物理文件级数据差异的
	例如有两个用户 用户 id 分别是 0 和 10
	用户 10 安装了应用 A 此时对于用户 0 来说是完全不可见的
	不像两个应用 A 和 B 两者的数据虽然默认情况下是不能互相访问的 但是我们有办法能够实现

        那么用户 id 到底是什么:

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

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

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

%%%%%

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

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

cmcc_jiangsu:/ # dumpsys package jackpal.androidterm
Activity Resolver Table:
  Full MIME Types:
      */*:
        6eb5070 jackpal.androidterm/.TermHere filter 85f0431
          Action: "android.intent.action.SEND"
          Category: "android.intent.category.DEFAULT"
          Type: "*"
          mPriority=0, mOrder=0, mHasPartialTypes=true
        b538fe9 jackpal.androidterm/.shortcuts.FSNavigator filter e12d733
          Action: "android.intent.action.GET_CONTENT"
          Category: "android.intent.category.DEFAULT"
          Category: "android.intent.category.OPENABLE"
          Type: "*"
          mPriority=0, mOrder=0, mHasPartialTypes=true

  Wild MIME Types:
      *:
        6eb5070 jackpal.androidterm/.TermHere filter 85f0431
          Action: "android.intent.action.SEND"
          Category: "android.intent.category.DEFAULT"
          Type: "*"
          mPriority=0, mOrder=0, mHasPartialTypes=true
        b538fe9 jackpal.androidterm/.shortcuts.FSNavigator filter e12d733
          Action: "android.intent.action.GET_CONTENT"
          Category: "android.intent.category.DEFAULT"
          Category: "android.intent.category.OPENABLE"
          Type: "*"
          mPriority=0, mOrder=0, mHasPartialTypes=true

  Non-Data Actions:
      jackpal.androidterm.RUN_SHORTCUT:
        3602f82 jackpal.androidterm/.RunShortcut filter 45c4897
          Action: "jackpal.androidterm.RUN_SHORTCUT"
          Category: "android.intent.category.DEFAULT"
      jackpal.androidterm.private.SWITCH_WINDOW:
        65c1ce jackpal.androidterm/.TermInternal filter 2d8abbb
          Action: "jackpal.androidterm.private.SWITCH_WINDOW"
          Category: "android.intent.category.DEFAULT"
      jackpal.androidterm.OPEN_NEW_WINDOW:
        d877d32 jackpal.androidterm/.RemoteInterface filter 83648d8
          Action: "jackpal.androidterm.OPEN_NEW_WINDOW"
          Category: "android.intent.category.DEFAULT"
      android.intent.action.MAIN:
        6ee9b65 jackpal.androidterm/.Term filter 8b301b5
          Action: "android.intent.action.MAIN"
          Category: "android.intent.category.LAUNCHER"
          Category: "android.intent.category.MULTIWINDOW_LAUNCHER"
        c0f203a jackpal.androidterm/.shortcuts.AddShortcut filter 5331a84
          Action: "android.intent.action.MAIN"
      android.intent.action.PICK:
        b538fe9 jackpal.androidterm/.shortcuts.FSNavigator filter 34d5ea2
          Action: "android.intent.action.PICK"
          Category: "android.intent.category.DEFAULT"
      jackpal.androidterm.RUN_SCRIPT:
        c6dd21d jackpal.androidterm/.RunScript filter 2a1e716
          Action: "jackpal.androidterm.RUN_SC

标签: exact传感器z9530速度式振动变送器参数传感器10045本安型红外传感器1b振动变送器参数8b型高稳定性传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台