android4.2引入了多用户的机制,方便于多个用户共用同一台android设备,这样就可以在不同的用户下安装不同应用满足不同的场景需求。那多用户下到底是怎样实现应用安装隔离的呢,下面我们对此做出详细分析。
首先我们想到的就是正常的应用安装流程中的多用户隔离:
1.应用商店下载安装应用最终调到 :
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(fileName)),
"application/vnd.android.package-archive");
startActivity(intent);
这是一个隐式意图,最终调到com.android.packageinstaller.PackageInstallerActivity,他继续传递给com.android.packageinstaller.InstallAppProgress,这是一个系统应用,专门用于处理安装请求。
2,接着应用安装包会通过PackageManager,installPackageWithVerificationAndEncryption()安装应用,而熟悉android源码设计结果的很明显可以看到,这十一个典型的binder跨进程调用,最终实际上会掉到PackageManagerService的同名方法,而这个service是系统中专门复杂应用包管理的系统service,运行于system-server中,当然具体的应用安装详细流程肯定是在这个类里面处理的,下面我们开始详细分析它。
3. public void installPackageWithVerificationAndEncryption(Uri packageURI,
IPackageInstallObserver observer, int flags, String installerPackageName,
VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
..............................
..............................
UserHandle user;
if ((flags&PackageManager.INSTALL_ALL_USERS) != 0) {
user = UserHandle.ALL;
/*ThunderSoft add for container only let install in current user*/
} else {
user = new UserHandle(UserHandle.getUserId(uid));
}
..............................
..............................
final Message msg = mHandler.obtainMessage(INIT_COPY);
msg.obj = new InstallParams(packageURI, observer, filteredFlags, installerPackageName,
verificationParams, encryptionParams, user);
mHandler.sendMessage(msg);
}
加色部分可以看到,我们会指定应用安装的用户user,而UserHandle.getUserId(uid)就是获取调用者所在的用户,从而实现安装到同一用户。
4. 中间handler,message的处理环节,我们省略,因为这不是我们今天的重点,并且网上有很多分析文章,我们直接跳到
private void installNewPackageLI(PackageParser.Package pkg,
int parseFlags, int scanMode, UserHandle user,
String installerPackageName, PackageInstalledInfo res) {
// Remember this for later, in case we need to rollback thi