您的位置:首页 > 移动开发 > Android开发

android多用户下应用安装详解三(特殊需求实现)

2015-01-27 16:38 411 查看
前两篇已经对新应用安装和开机加载应用安装信息的流程做了详细梳理,下面来看一个需求。在说这个需求之前,我们了解一个背景:多用户下,如果使用adb install xxx.apk的话,会导致全用户安装。聪明的读者可能就知道了,这实际上破坏了多用户的独立性。而我所在的项目即利用到了多用户,这显然不能让人接受,尤其是很多pc上的android应用安装工具,会直接把一些应用安装到另外一个用户里。实际上这也是我调研这个问题的原因。

下面来分析全用户安装的原因:

1. packagemanagerservice安装入口installPackageWithVerificationAndEncryption()里:

UserHandle user;

if ((flags&PackageManager.INSTALL_ALL_USERS) != 0) {

user = UserHandle.ALL;

} else {

user = new UserHandle(UserHandle.getUserId(uid));

}

看到这里,可以大致猜测就是这个UserHandle.ALL导致的全用户安装的,实际的情况也确实是这样的,在层层传递之后,会进入com.android.server.pm.Settings.getPackageLPw(): 有一段逻辑是这样的:

List<UserInfo> users = getAllUsers();

if (users != null && allowInstall) {

for (UserInfo user : users) {

final boolean installed = installUser == null

|| installUser.getIdentifier() == UserHandle.USER_ALL

|| installUser.getIdentifier() == user.id;

p.setUserState(user.id, COMPONENT_ENABLED_STATE_DEFAULT,

installed,

true, // stopped,

true, // notLaunched

false, // blocked

null, null, null);

writePackageRestrictionsLPr(user.id);

}

}

看到这里肯定就明白了,所以一个直观的想法就是修改这段逻辑

if ((flags&PackageManager.INSTALL_ALL_USERS) != 0) {

user = UserHandle.ALL;

}

改为:user = new UserHandle(ActivityManagerNative.getDefault().getCurrentUser().id); 即如果使用adb install的话就将安装用户设为当前前台用户,避免全用户安装。

2. 这个确实能屏蔽绝大部分情况,但是还是屏蔽不了所有的情况:

比如adb push xxx.apk /data/app, 当然这个需要系统权限,三方安装工具是没有这个权限的。

但还有一种情况,却是真的可能发生。就是安装过程中手机重启,尤其是一些国产手机比较容易出现,这样的情况就会如上篇中所讲,开机扫描到/data/app目录下有新apk的时候就会重新走安装流程。

private void scanDirLI(File dir, int flags, int scanMode, long currentTime) {

for (i=0; i<files.length; i++) {

................................................................................................................

PackageParser.Package pkg = scanPackageLI(file,

flags|PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime, null);

这里面最后一个参数就是installUser, 如果等于null, 根据第一篇第7部分知道也会被全用户安装

................................................................................................................

}

}

3. 所以我们如果想彻底屏蔽全用户安装,需要找到一个所有情况都会走到的地方。

实际这个地方就是com.android.server.pm.Settings.getPackageLPw(String
name, PackageSetting origPackage,

String realName, SharedUserSetting sharedUser, File codePath, File resourcePath,

String nativeLibraryPathString, int vc, int pkgFlags,

UserHandle installUser, boolean add, boolean allowInstall)方法,因为第一篇,第二篇的分析知道,不管是正常的安装流程,还是开机扫描/data/app目录,包括开机之后监听/data/app目录都会最终走到这个方法里。所以我们只需要在这个方法里将installUser设为当前用户即可。

即:
installUser = new UserHandle(ActivityManagerNative.getDefault().getCurrentUser().id);

ok.这就是延伸出来的一个需求修改。网上关于多用户分析的技术文章还比较少,有用的更是不可得,所以这里对自己的分析做一个记录分享。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐