总结:
这篇文章你会学到: PackageManagerSercive
UserManagerService
UserHandle
是一个工具类
在Android
系统中,每个用户都有自己的一套权限和资源,因此需要将系统中的各种资源进行隔离和分配.Android
系统给每个用户分配的资源范围是 100000. 每个用户预留了 100000个UID号.比如 第一个用户的UID=0 那么他的资源就是 0 - 999999 . 如果第二个账户UID=1. 那么他的资源范围就是 100000 - 199999. 为什么要这么干因为每个app都有唯一一个UID号.
在App启动的时候,第一个判断就是判断当期要启动的app是不是属于这个用户的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| class ActivityTaskManagerService{ private int startActivityAsUser(IApplicationThread caller, String callingPackage, @Nullable String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) { assertPackageMatchesCallingUid(callingPackage); enforceNotIsolatedCaller("startActivityAsUser");
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser, Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
return getActivityStartController().obtainStarter(intent, "startActivityAsUser") .setCaller(caller) .setCallingPackage(callingPackage) .setCallingFeatureId(callingFeatureId) .setResolvedType(resolvedType) .setResultTo(resultTo) .setResultWho(resultWho) .setRequestCode(requestCode) .setStartFlags(startFlags) .setProfilerInfo(profilerInfo) .setActivityOptions(bOptions) .setUserId(userId) .execute();
} }
|
1 2 3 4 5 6 7 8 9 10 11
| void assertPackageMatchesCallingUid(@Nullable String packageName) {
final int callingUid = Binder.getCallingUid(); if (isSameApp(callingUid, packageName)) { return; } final String msg = "Permission Denial: package=" + packageName + " does not belong to uid=" + callingUid; Slog.w(TAG, msg); throw new SecurityException(msg); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| private boolean isSameApp(int callingUid, @Nullable String packageName) { try { if (callingUid != 0 && callingUid != SYSTEM_UID) { if (packageName == null) { return false; } final int uid = AppGlobals.getPackageManager().getPackageUid(packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid)); return UserHandle.isSameApp(callingUid, uid); } } catch (RemoteException e) { } return true; }
|
这里就涉及到了另外一个系统级别的服务PackageManagerService
1 2 3 4 5 6 7 8 9 10 11 12
| class PackageManagerSercice{
public int getPackageUid(String packageName, int flags, int userId) { if (!mUserManager.exists(userId)) return -1; final int callingUid = Binder.getCallingUid(); flags = updateFlagsForPackage(flags, userId); enforceCrossUserPermission(callingUid, userId, false , false , "getPackageUid"); return getPackageUidInternal(packageName, flags, userId, callingUid); } }
|
这里又涉及到了另外一个服务UserManagerSercice
,用户判断用户是否存在.
这里就不开枝散叶了,直接看回最终步骤:
1 2 3 4 5 6 7 8 9
| UserHandle.isSameApp(callingUid, uid);
public static boolean isSameApp(int uid1, int uid2) { return getAppId(uid1) == getAppId(uid2); }
public static @AppIdInt int getAppId(int uid) { return uid % PER_USER_RANGE; }
|