背景
Android 通过分离用户账号和应用数据,支持在一台设备上添加多个用户 通过多用户,可以实现应用双开等需求,不同用户下同一个包名的App,数据是完全独立的
常见 adb 命令
- 查看所有用户
pm list users
- 创建用户
pm create-user xxx
- 为某个用户安装程序
adb shell pm install xxx.apk
- 启动某个用户下的 apk
am start --user USER_ID 启动参数
- 删除用户
remove-user USER_ID
- 查看某个用户下包名
adb shell pm list packages --user 10
- 查看没有被禁止的包
adb shell pm list packages --user 10 -e
- dumpsys user
adb shell dumpsys user
可以看到当前系统的所有 user,关于 user 的设置,以及对不同 user type 的 package 的限制
// ...
User types version: 0
User types (9 types):
android.os.usertype.profile.TEST:
mName: android.os.usertype.profile.TEST
mBaseType: PROFILE
// ...
android.os.usertype.system.HEADLESS:
mName: android.os.usertype.system.HEADLESS
mBaseType: SYSTEM
// ...
android.os.usertype.full.SYSTEM:
mName: android.os.usertype.full.SYSTEM
mBaseType: FULL|SYSTEM
// ...
Whitelisted packages per user type
Mode: 5 (enforced) (implicit)
Legend
0 -> android.os.usertype.full.DEMO
1 -> android.os.usertype.full.GUEST
2 -> android.os.usertype.full.RESTRICTED
3 -> android.os.usertype.full.SECONDARY
4 -> android.os.usertype.full.SYSTEM
5 -> android.os.usertype.profile.CLONE
6 -> android.os.usertype.profile.MANAGED
7 -> android.os.usertype.profile.TEST
8 -> android.os.usertype.system.HEADLESS
71 packages:
com.android.cts.priv.ctsshim: 0 1 2 3 4 8
com.android.car.companiondevicesupport: 0 1 2 3 4 8
com.android.providers.telephony: 0 1 2 3 4 8
com.android.car.calendar: 0 1 2 3 4
android.car.cluster: 4 8
com.android.providers.calendar: 0 1 2 3 4 8
com.android.providers.media: 0 1 2 3 4
com.android.wallpapercropper: 0 1 2 3 4
// ...
对不同 user type 的 package 的限制在 /system/etc/sysconfig/ 目录下,比如 android.car.cluster在配置文件中对应中 user-type 为 SYSTEM,dumpsys 出来的信息为 4 8,因为 android.os.usertype.full.SYSTEM 和 android.os.usertype.system.HEADLESS 的 type 都为 system,此进程可以在 user-type 为 SYSTEM 的用户下运行(不关注 mode 的情况下)
<install-in-user-type package="android.car.cluster">
<install-in user-type="SYSTEM" />
</install-in-user-type>
User 介绍
Categories of users
- System user
添加到设备的第一个用户,无法删除,始终运行,权限最高
- Headless system user
Automotive 可以开启这一模式,始终在后台运行
- Secondary user
可以被删除,且不会影响其它用户
- Guest user
临时用户
- Admin user
管理员用户,可以创建或者删除其它用户,一般 System User 是 Admin
User types
创建用户时,由 type 指定用户类别,有以下 type
- android.os.usertype.full.SYSTEM
- android.os.usertype.full.SECONDARY
- android.os.usertype.full.GUEST
- android.os.usertype.full.DEMO
- android.os.usertype.full.RESTRICTED
- android.os.usertype.profile.MANAGED
- android.os.usertype.system.HEADLESS
- android.os.usertype.profile.CLONE
用命令行创建,默认为 android.os.usertype.full.SECONDARY
常见 API
- 创建用户
UserManager#createProfileForUser(String name, String userType, int flag,
int userId, String[] disallowedPackages)
- name 用户名
- userType 用户类型,比如 GUEST、DEMO、MANAGED 等,不同类型,权限不同,场景也不同,一般双用户可创建 MANAGED
- flag 表示用户信息,FLAG_MANAGED_PROFILE、FLAG_DISABLED、FLAG_INITIALIZED 等,FLAG_MANAGED_PROFILE 表示该用户成为另一个用户的资料,FLAG_DISABLED 表示该用户被禁止
- userId 父用户的id
- disallowedPackages 禁止的应用
用户创建完成后,也可以使用 PackageManager#setApplicationEnabledSetting 方法设置应用是否可用
- 删除用户
UserManager#removeUser(int)
常见问题介绍
- 不同用户间进程通信
默认情况下,如在 user id 为 10 的用户下使用 bindService 方法,那么会在当前用户进程下寻找 Service,如果使用的 Service 没有再 user id 为 10 的用户下运行,会提示找不到该 Service,应当使用 bindServiceAsUser 指定 user
- Automotive 多用户
- 在 Android 10 后,Automotive 会启动多用户,以此来实现公用设备体验,由 ro.fw.headless_system_user、android.car.user_hal_enabled 属性控制
- 对于多用户,也有新增了控制多用户安装程序的权限,白名单在 /system/etc/sysconfig/ 下
<!-- Whether to only install system packages on a user if they're allowlisted for that user
type. Override the default value in framework config file.
0 - disable allowlist (install all system packages; no logging)
1 - enforce (only install system packages if they are allowlisted)
2 - log (log when a non-allowlisted package is run)
4 - any package not mentioned in the allowlist file is implicitly allowlisted on all users
8 - same as 4, but just for the SYSTEM user
16 - ignore OTAs (don't install system packages during OTAs)
Common scenarios for auto:
- to enable feature (fully enforced) for a complete allowlist: 1
- to enable feature for an incomplete allowlist (so use implicit allowlist mode): 5 -->
<integer name="config_userTypePackageWhitelistMode">5</integer> <!-- 1+4 -->