Android UserId
本文引用博客:
https://www.shoco.top/2022/07/19/Android-UID/
https://www.jianshu.com/p/b33dd49f2ae6
最近遇到这么个Bug,关于UserId的,代码是这样的:
// we don't need to show button for secondary user
if (UserHandle.USER_OWNER != UserHandle.myUserId()) {return;
}
经过一顿Google之后,发现代码的意思是:如果当前进程的用户(UserHandle.myUserId())不是默认用户的话,直接return。
Linux UID
Linux会为每个用户分配一个uid,可以用id命令查看:
mi@zsy:~$ id
uid=1000(mi) gid=1000(mi) 组=1000(mi)···
root用户uid=0
root@zsy:/home/mi# id
uid=0(root) gid=0(root) 组=0(root)
Android UID
GPT给的答案
问:Android的uid和userid分别代表什么?
答:在Android系统中,UID和UserID代表以下内容:
UID(User ID):每个应用程序都有一个唯一的UID,用于标识该应用程序的所有进程和数据。UID是一个整数,通常在安装应用程序时分配,并且在应用程序的整个生命周期中保持不变。UID用于实现应用程序之间的隔离和安全性,以及控制应用程序对系统资源的访问权限。
UserID(User Identifier):每个Android用户都有一个唯一的UserID,用于标识该用户的所有应用程序和数据。UserID也是一个整数,通常在创建用户时分配,并且在用户的整个生命周期中保持不变。UserID用于实现多用户环境下的隔离和安全性,以及控制用户对系统资源的访问权限。
总之,UID和UserID都是用于实现Android系统中应用程序和用户之间的隔离和安全性的重要标识符。
下面详细说下:
在Android系统中,uid
在应用安装时被分配,范围[10000, 19999]
,称之为appid
,并且在应用存在于手机上期间,都不会改变,每个进程只能访问uid
的权限范围内的文件。
通过在manifest
文件中指定android:sharedUserId=""
可以使多个应用共享同一个uid,使用相同sharedUserId的应用需要使用相同的签名,应用之间可以直接访问数据, 甚至在同一进程中运行。
UID 的分配
app 的 UID 是安装的时候就确认的, 关键的代码如下:
PMS中:
private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg,final int policyFlags, final int scanFlags, long currentTime, @Nullable UserHandle user)throws PackageManagerException {if (DEBUG_PACKAGE_SCANNING) {if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)Log.d(TAG, "Scanning package " + pkg.packageName);}applyPolicy(pkg, policyFlags);.....................................if (pkgSetting == null) {.......................// SIDE EFFECTS; updates system state; move elsewhereif (origPackage != null) {mSettings.addRenamedPackageLPw(pkg.packageName, origPackage.name);}//主要是这句, PMS 维护着 mSettings 这个数据结构,里面存储着所有应用的安装信息mSettings.addUserToSettingLPw(pkgSetting);} else {// REMOVE SharedUserSetting from method; update in a separate call.//// TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,// secondaryCpuAbi are not known at this point so we always update them// to null here, only to reset them at a later point.Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, suid, destCodeFile,pkg.applicationInfo.nativeLibraryDir, pkg.applicationInfo.primaryCpuAbi,pkg.applicationInfo.secondaryCpuAbi, pkg.applicationInfo.flags,pkg.applicationInfo.privateFlags, pkg.getChildPackageNames(),UserManagerService.getInstance(), usesStaticLibraries,pkg.usesStaticLibrariesVersions);}....................return pkg;
}
frameworks\base\services\core\java\com\android\server\pm\Settings.java:
/*** Registers a user ID with the system. Potentially allocates a new user ID.* @throws PackageManagerException If a user ID could not be allocated.*/
void addUserToSettingLPw(PackageSetting p) throws PackageManagerException {if (p.appId == 0) {// Assign new user IDp.appId = newUserIdLPw(p);} else {// Add new setting to list of user IDsaddUserIdLPw(p.appId, p, p.name);}if (p.appId < 0) {PackageManagerService.reportSettingsProblem(Log.WARN,"Package " + p.name + " could not be assigned a valid UID");throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,"Package " + p.name + " could not be assigned a valid UID");}
}
// uid 的分配// Returns -1 if we could not find an available UserId to assignprivate int newUserIdLPw(Object obj) {// Let's be stupidly inefficient for now...final int N = mUserIds.size();//从0开始,找到第一个未使用的ID,此处对应之前有应用被移除的情况,复用之前的IDfor (int i = mFirstAvailableUid; i < N; i++) {if (mUserIds.get(i) == null) {mUserIds.set(i, obj);return Process.FIRST_APPLICATION_UID + i;}}//最多只能安装 9999 个应用// None left?if (N > (Process.LAST_APPLICATION_UID-Process.FIRST_APPLICATION_UID)) {return -1;}mUserIds.add(obj);// 可以解释为什么普通应用的UID 都是从 10000开始的return Process.FIRST_APPLICATION_UID + N;}
支持多用户后,Android的uid由两部分组成:
uid = userid * 100,000 + appid
使用ps查看进程, 可以看到用户名形如u0_a94
$ ps -ef
UID PID PPID C STIME TTY TIME CMD
u0_a94 21465 1160 0 24:06 ? 00:00:00 com.android.htmlviewer
u0_a133 1493 1160 0 32:03 ? 00:00:05 com.android.camera
u10_nfc 2750 1160 0 05:30 ? 00:00:00 com.android.nfc
u999_a225 22467 1160 0 24:30 ? 00:00:01 com.android.permissioncontroller
这个u0_a94
就表示该应用是 user 0
(主用户)下面的应用,userid
为0
,id是94
,普通应用程序的UID都是从10000开始的,所以 最终计算出的 appid
是 10094
,uid
为0 * 100,000 + 10094 = 10094
编程中使用android.os.Process.myUid()
可以获取当前uid
UserHandle
UserHandle为对userid的封装。
使用android.os.Process.myUserHandle()
可以获取当前UserHandle
UserHandle中包含一些对uid进行转换的方法:
public static final int PER_USER_RANGE = 100000;// uid2userId
public static @UserIdInt int getUserId(int uid) {// 是否支持多用户if (MU_ENABLED) { return uid / PER_USER_RANGE;} else {return UserHandle.USER_SYSTEM; //USER_SYSTEM = 0;}
}// uid2appId
public static @AppIdInt int getAppId(int uid) {return uid % PER_USER_RANGE;
}// (userId + appId)2uid
public static int getUid(@UserIdInt int userId, @AppIdInt int appId) {if (MU_ENABLED) {return userId * PER_USER_RANGE + (appId % PER_USER_RANGE);} else {return appId;}
}
UserHandle中包含一些预定义的userid:
public static final @UserIdInt int USER_ALL = -1; // 全部用户public static final @UserIdInt int USER_CURRENT = -2; // 当前用户public static final @UserIdInt int USER_CURRENT_OR_SELF = -3; // 当前用户或当前应用用户public static final @UserIdInt int USER_NULL = -10000; // 未定义public static final @UserIdInt int USER_OWNER = 0; // 系统默认用户, 已弃用public static final @UserIdInt int USER_SYSTEM = 0; // 系统默认用户
UID System (uid=1000)
使用ps查看进程时,可以看到名为system
的用户:
$ ps -ef
UID PID PPID C STIME TTY TIME CMD
system 32342 1160 0 05:19 ? 00:00:00 com.miui.securitycore.remote
该用户uid
为1000, 开发系统应用时, 指定android:sharedUserId="android.uid.system"
,并使用系统签名, 可以直接访问系统应用数据。
小米手机中的UserInfo:
mi@zsy:~$ adb shell pm list users
Users:UserInfo{0:机主:c13} runningUserInfo{10:security space:413} runningUserInfo{999:XSpace:801010} running0 :系统默认用户
10:security space 手机分身
999:XSpace 双开应用
Android UserId相关推荐
- Android中的APK,TASK,PROCESS,USERID之间的关系
开发Android已经有一段时间了,今天接触到底层的东西,所以对于进程,用户的id以及Android中的Task,Apk之间的关系,要做一个研究,下面就是研究结果: apk一般占一个dalvik,一个 ...
- Android Uid,UserId,AppId,Pid
Android Uid,UserId,AppId,Pid 1.Uid 1.1.Uid来源(android 9.0) 1.2.查看Uid 2.UserId 3.AppId 4.Pid 1.Uid and ...
- uid(组件id) = userId + appId (android多用户)
public static final int getUid(int userId, int appId) {if (MU_ENABLED) {return userId * PER_USER_RAN ...
- Android中userId的作用
每个应用在安装成功后,系统都会为其分配一个用户Id(userId),一个应用对应一个userId,而一个userId可以对应多个应用.当多个应用的userId相同时,可以访问对方的私有目录,如/dat ...
- android 获取当前应用的userid
dumpsys activity | grep ActivityRecord 得到当前应用的包名com.xxx.xxx dumpsys package com.xxx.xxx | grep user ...
- adb命令查看android系统用户userid
adb shell :/ $ pm list users Users: UserInfo{0:机主:c13} running UserInfo{10:system_cl ...
- Android 支付宝H5 没有回调
今天测试反馈问题,说,手机上没有安装支付宝的,调用支付宝支付之后,没有回调.不提示成功也不提示失败. 我自己试了半天也都是没有问题 .后来终于可以试出来了. 发现原来是,清单里面注册的Activity ...
- Android学习 —— 数据的存储与访问方式一: 文件存取
笔记摘要: 在Android中主要提供了四种数据存储与访问的方式,文件.SharedPreference(偏好参数保存).SOLite数据库.内容提供者(Content provider)和网络, 本 ...
- android数据库降级_Android SQLite (二.数据库创建,升级及降级)
上篇文章简介和常用语法介绍了SQLite数据库的基本信息和一些常用的语法操作,本篇文章主要介绍Android开发过程中SQLite数据库的创建使用和常见问题处理. 一.SQLiteOpenHelper ...
最新文章
- 微软Win8将有多个版本 四款面向ARM平台
- centos导出mysql数据库_centos5.8系统下MySQL数据库导出与导入操作
- Node js开发中的那些旮旮角角 第一部
- 关于ArcGIS Rest API
- Linux 常用的 命令,移动,创建,删除等
- 腾讯云三大自研数据库之一 TBase 开源后首次重磅升级,复杂查询性能最高提升十倍
- c语言50个小程序,C语言50小程序.doc
- 托福考试前你需要知道哪些事情
- 【揭秘】过于真实,培训机构那些不为人知的秘密(二)
- Labview心电信号处理
- 修改PPT文档属性工具使用教程
- 7-45 航空公司 VIP 客户查询(25 分)
- 服务器中内存不够的原因
- 腾讯云购买服务器操作步骤
- macbook pro黑屏没反应无法开机的解决方法
- git与github使用
- Linux系统连接校园网指南(JLU)
- linux密码配置文件详解,用户配置文件与密码配置文件
- 使用CGLIB enhancer实现类的增强
- Redis Essentials 读书笔记 - 第一章: Getting Started (The Baby Steps)
热门文章
- 12563 - Jin Ge Jin Qu hao 【DP】
- java里jlp是什么意思_如何在Java中使用Selp提交表单
- Linux图形界面与字符界面切换
- PLX31-EIP-MBS 以太网/IP到Modbus串行
- java 输入 输出 方法_Java常用的输入输出方法
- 台式计算机属于什么资产设备,办公用的电脑,属于固定资产的那一类??谢谢 – 手机爱问...
- SRC挖洞之文件上传/下载漏洞的实战案例
- 环境管理:开发、测试和生产环境
- Java事务编程-弱隔离级别之写倾斜与幻读
- 事缓则圆,人缓则安,语迟则贵