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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
| /*
* This method handles package deletion in general
*/
private boolean deletePackageLI(String packageName, UserHandle user,
boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled,
int flags, PackageRemovedInfo outInfo,
boolean writeSettings) {
if (packageName == null) {
Slog.w(TAG, "Attempt to delete null packageName.");
return false;
}
if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
PackageSetting ps;
boolean dataOnly = false;
int removeUser = -1;
int appId = -1;
synchronized (mPackages) {
ps = mSettings.mPackages.get(packageName);
if (ps == null) {
Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
return false;
}
if ((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
&& user.getIdentifier() != UserHandle.USER_ALL) {
// 设置要卸载的该app的用户状态,修改该app在该用户中的相关信息,标记为卸载,另外要删除在该用户中的沙箱中的数据
if (DEBUG_REMOVE) Slog.d(TAG, "Only deleting for single user");
final int userId = user.getIdentifier();
ps.setUserState(userId,
COMPONENT_ENABLED_STATE_DEFAULT,
false, //installed
true, //stopped
true, //notLaunched
false, //hidden
null, null, null,
false, // blockUninstall
ps.readUserState(userId).domainVerificationStatus, 0);
if (!isSystemApp(ps)) {
// 该app被其他用户也安装了,那么就不能删除该app在/data/app/下面的东西了
// 只能删除对应用用户自己的沙箱目录
if (ps.isAnyInstalled(sUserManager.getUserIds())) {
if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
removeUser = user.getIdentifier();
appId = ps.appId;
// 修改/data/users/<userid>/package-restrictions.xml
// 将上述信息记录其中
scheduleWritePackageRestrictionsLocked(removeUser);
} else {
//只有一个用户安装的时候,要设置其userState中的installed为true
// 前面将其设置为了false
if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
ps.setInstalled(true, user.getIdentifier());
}
} else {
if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
removeUser = user.getIdentifier();
appId = ps.appId;
scheduleWritePackageRestrictionsLocked(removeUser);
}
}
}
// 紧紧处理的是一个用户
// 因为 USER_ALL = -1
if (removeUser >= 0) {
// From above, we determined that we are deleting this only
// for a single user. Continue the work here.
if (DEBUG_REMOVE) Slog.d(TAG, "Updating install state for user: " + removeUser);
if (outInfo != null) {
outInfo.removedPackage = packageName;
outInfo.removedAppId = appId;
outInfo.removedUsers = new int[] {removeUser};
}
// 删除该用户中的该app的沙箱目录
mInstaller.clearUserData(ps.volumeUuid, packageName, removeUser);
removeKeystoreDataIfNeeded(removeUser, appId);
// 发送START_CLEANING_PACKAGE消息
// 处理该消息时调用startCleaningPackages()
// 该方法中会发送“android.content.pm.CLEAN_EXTERNAL_STORAGE”的intent
// com.android.defcontainer.DefaultContainerService会处理它
schedulePackageCleaning(packageName, removeUser, false);
synchronized (mPackages) {
if (clearPackagePreferredActivitiesLPw(packageName, removeUser)) {
//处理UserHandle.USER_ALL这个情况
scheduleWritePackageRestrictionsLocked(removeUser);
}
resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, removeUser);
}
return true;
}
..............................
// 处理 USER_ALL
// 也就是卸载所有用户中的该app
boolean ret = false;
if (isSystemApp(ps)) {
if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package:" + ps.name);
ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled,
flags, outInfo, writeSettings);
} else {
if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package:" + ps.name);
// 除了删除沙箱目录,/data/app/包名等文件外,还要删除其在PMS中的的数据结构,比如注册的组件等
// 这是由其内部的removePackageLI()方法完成的
killApplication(packageName, ps.appId, "uninstall pkg");
ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags,
allUserHandles, perUserInstalled,
outInfo, writeSettings);
}
return ret;
.......
|