本文引用博客:
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代表以下内容:

  1. UID(User ID):每个应用程序都有一个唯一的UID,用于标识该应用程序的所有进程和数据。UID是一个整数,通常在安装应用程序时分配,并且在应用程序的整个生命周期中保持不变。UID用于实现应用程序之间的隔离和安全性,以及控制应用程序对系统资源的访问权限。

  2. 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(主用户)下面的应用,userid0,id是94,普通应用程序的UID都是从10000开始的,所以 最终计算出的 appid10094uid0 * 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相关推荐

  1. Android中的APK,TASK,PROCESS,USERID之间的关系

    开发Android已经有一段时间了,今天接触到底层的东西,所以对于进程,用户的id以及Android中的Task,Apk之间的关系,要做一个研究,下面就是研究结果: apk一般占一个dalvik,一个 ...

  2. 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 ...

  3. uid(组件id) = userId + appId (android多用户)

    public static final int getUid(int userId, int appId) {if (MU_ENABLED) {return userId * PER_USER_RAN ...

  4. Android中userId的作用

    每个应用在安装成功后,系统都会为其分配一个用户Id(userId),一个应用对应一个userId,而一个userId可以对应多个应用.当多个应用的userId相同时,可以访问对方的私有目录,如/dat ...

  5. android 获取当前应用的userid

    dumpsys activity | grep ActivityRecord 得到当前应用的包名com.xxx.xxx dumpsys package com.xxx.xxx  | grep user ...

  6. adb命令查看android系统用户userid

    adb shell :/ $ pm list users Users:         UserInfo{0:机主:c13} running         UserInfo{10:system_cl ...

  7. Android 支付宝H5 没有回调

    今天测试反馈问题,说,手机上没有安装支付宝的,调用支付宝支付之后,没有回调.不提示成功也不提示失败. 我自己试了半天也都是没有问题 .后来终于可以试出来了. 发现原来是,清单里面注册的Activity ...

  8. Android学习 —— 数据的存储与访问方式一: 文件存取

    笔记摘要: 在Android中主要提供了四种数据存储与访问的方式,文件.SharedPreference(偏好参数保存).SOLite数据库.内容提供者(Content provider)和网络, 本 ...

  9. android数据库降级_Android SQLite (二.数据库创建,升级及降级)

    上篇文章简介和常用语法介绍了SQLite数据库的基本信息和一些常用的语法操作,本篇文章主要介绍Android开发过程中SQLite数据库的创建使用和常见问题处理. 一.SQLiteOpenHelper ...

最新文章

  1. 微软Win8将有多个版本 四款面向ARM平台
  2. centos导出mysql数据库_centos5.8系统下MySQL数据库导出与导入操作
  3. Node js开发中的那些旮旮角角 第一部
  4. 关于ArcGIS Rest API
  5. Linux 常用的 命令,移动,创建,删除等
  6. 腾讯云三大自研数据库之一 TBase 开源后首次重磅升级,复杂查询性能最高提升十倍
  7. c语言50个小程序,C语言50小程序.doc
  8. 托福考试前你需要知道哪些事情
  9. 【揭秘】过于真实,培训机构那些不为人知的秘密(二)
  10. Labview心电信号处理
  11. 修改PPT文档属性工具使用教程
  12. 7-45 航空公司 VIP 客户查询(25 分)
  13. 服务器中内存不够的原因
  14. 腾讯云购买服务器操作步骤
  15. macbook pro黑屏没反应无法开机的解决方法
  16. git与github使用
  17. Linux系统连接校园网指南(JLU)
  18. linux密码配置文件详解,用户配置文件与密码配置文件
  19. 使用CGLIB enhancer实现类的增强
  20. Redis Essentials 读书笔记 - 第一章: Getting Started (The Baby Steps)

热门文章

  1. 12563 - Jin Ge Jin Qu hao 【DP】
  2. java里jlp是什么意思_如何在Java中使用Selp提交表单
  3. Linux图形界面与字符界面切换
  4. PLX31-EIP-MBS 以太网/IP到Modbus串行
  5. java 输入 输出 方法_Java常用的输入输出方法
  6. 台式计算机属于什么资产设备,办公用的电脑,属于固定资产的那一类??谢谢 – 手机爱问...
  7. SRC挖洞之文件上传/下载漏洞的实战案例
  8. 环境管理:开发、测试和生产环境
  9. Java事务编程-弱隔离级别之写倾斜与幻读
  10. 事缓则圆,人缓则安,语迟则贵