我们知道Android 操作系统是基于Linux内核的,所以Android 的UID 是基于 Linux UID的。
Linux UID
Linux 本身就是一个多用户操作系统,每一个用户都会有一个UID,不同UID 之间的资源访问是受限的。
其中,Linux的DAC权限模型,控制的不同UID资源间的读、写、执行。也就是所谓的 “777” 权限。
d: 标识文件夹
r : 读权限
w:写权限
x : 执行权限
Android 平台就是利用基于 Linux 用户的保护机制识别和隔离应用资源,为此,Android 会为每个 Android 应用分配一个唯一的用户 ID (UID),并在自己的进程中运行。
例如,应用的内部存储,data/data/应用包名/ 正是此机制一个直接应用,每个应用都有一个单独的UID,无法对彼此数据的直接访问。
Android appID
在单用户时代, 每个package单独分配一个uid/gid来进行管理(共享uid/gid的除外)。而在支持多用户之后,同一个 app, 在不同的 android user 下运行时, 其 uid 是不同的。 因此,无法使用唯一的 uid 来标识一个 android package。所以引入了 appID 来标识一个 android package, appID 在安装时确定, 与运行状态无关, 因此, 在不同的 android user 下, 同一个 package 的 appID 是不变的
那么这个时候,就需要在多用户环境下,引入另一个概念appID
如果默认不创建多个用户时,android 只有一个用户时 uid == appID
public static final int FIRST_APPLICATION_UID = 10000;
public static final int LAST_APPLICATION_UID = 19999;
size ==> 第几个安装。所以 最多安装9999 个应用
appId = Process.FIRST_APPLICATION_UID + size;
Linux userID
Android在创建每个用户时,都会分配一个整型的 userID。对于主用户(正常下的默认用户)来说,userId为0,之后创建的userId将从10开始计算,每增加一个userId加1。
有了 appID 和 UserID之后,我们就可以通过组合它们来生成新的 UID,但是有两种情况。
如果默认不创建多个用户时,
UserID = 0
uid = appID
创建多用户时:
UserID = 10
uid = UserID * 100000 + appID
我们来看看 UserID 的规则代码
// frameworks/base/core/java/android/os/UserHandle.java
public static @UserIdInt int getUserId(int uid) {
if (MU_ENABLED) {
// public static final int PER_USER_RANGE = 100000;
return uid / PER_USER_RANGE;
} else {
return UserHandle.USER_SYSTEM;
}
}