位置:"frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java"
这里我们来回顾下传入的参数:final int policyFlags 就是我们之前的解析参数 parseFlags
// Retrieve PackageSettings and parse package
@ParseFlags final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
| PackageParser.PARSE_ENFORCE_CODE
| (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
| (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
| (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
同时,对于扫描标志位 scanFlags,会做如下处理:
//【2】设置扫描参数
@ScanFlags int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
if (args.move != null) {
// moving a complete application; perform an initial scan on the new install location
//【2.1】如果 args.move 不为 null,表示正在移动一个 app,我们会对其进行一个初始化的扫描
// 增加 SCAN_INITIAL 位
scanFlags |= SCAN_INITIAL;
}
if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
//【2.2】如果安装参数指定了 INSTALL_DONT_KILL_APP,那么增加 SCAN_DONT_KILL_APP 位
scanFlags |= SCAN_DONT_KILL_APP;
}
if (instantApp) {
scanFlags |= SCAN_AS_INSTANT_APP;
}
//...
//【13】根据安装参数做不同的处理
if (args.move != null) {
// We did an in-place move, so dex is ready to roll
//【13.1】如果是 move package,进入这里
scanFlags |= SCAN_NO_DEX; // 设置以下标签,无需做 odex,我们需要已有的移动过去即可
scanFlags |= SCAN_MOVE;
//...
} else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
//【13.2】如果不是 forward lock 模式安装且没有安装到外置存储上,进入这里
// Enable SCAN_NO_DEX flag to skip dexopt at a later stage
scanFlags |= SCAN_NO_DEX; // 扫描参数设置 SCAN_NO_DEX,意味着后面不做 odex,因为这里会做
//...
}
上面,我们省略掉了不重要的代码段
下面继续分析核心方法:
private void replacePackageLIF(PackageParser.Package pkg, final @ParseFlags int parseFlags,
final @ScanFlags int scanFlags, UserHandle user, String installerPackageName,
PackageInstalledInfo res, int installReason) {
final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
final PackageParser.Package oldPackage;
final PackageSetting ps;
final String pkgName = pkg.packageName;
final int[] allUsers;
final int[] installedUsers;
synchronized(mPackages) {
oldPackage = mPackages.get(pkgName);
if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
// don't allow upgrade to target a release SDK from a pre-release SDK
final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
== android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
== android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
//【2】如果安装设置了 PackageParser.PARSE_FORCE_SDK,那就要校验下 sdk
if (oldTargetsPreRelease
&& !newTargetsPreRelease
&& ((parseFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
Slog.w(TAG, "Can't install package targeting released sdk");
res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
return;
}
ps = mSettings.mPackages.get(pkgName);
// verify signatures are valid
//【4】校验签名,不匹配,不能安装
final KeySetManagerService ksms = mSettings.mKeySetManagerService;
if (ksms.shouldCheckUpgradeKeySetLocked(ps, scanFlags)) {
if (!ksms.checkUpgradeKeySetLocked(ps, pkg)) {
res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
"New package not signed by keys specified by upgrade-keysets: "
+ pkgName);
return;
}
} else {
// default to original signature matching
if (!pkg.mSigningDetails.checkCapability(oldPackage.mSigningDetails,
PackageParser.SigningDetails.CertCapabilities.INSTALLED_DATA)
&& !oldPackage.mSigningDetails.checkCapability(
pkg.mSigningDetails,
PackageParser.SigningDetails.CertCapabilities.ROLLBACK)) {
res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
"New package has a different signature: " + pkgName);
return;
}
}
// don't allow a system upgrade unless the upgrade hash matches
//【5】如果旧的应用是 sys app,并且需要强制 hash 校验,那就会在这里校验 hash
if (oldPackage.restrictUpdateHash != null && oldPackage.isSystem()) {
byte[] digestBytes = null;
try {
final MessageDigest digest = MessageDigest.getInstance("SHA-512");
updateDigest(digest, new File(pkg.baseCodePath));
if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
for (String path : pkg.splitCodePaths) {
updateDigest(digest, new File(path));
}
}
digestBytes = digest.digest();
} catch (NoSuchAlgorithmException | IOException e) {
res.setError(INSTALL_FAILED_INVALID_APK,
"Could not compute hash: " + pkgName);
return;
}
if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
res.setError(INSTALL_FAILED_INVALID_APK,
"New package fails restrict-update check: " + pkgName);
return;
}
// retain upgrade restriction
pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
}
// Check for shared user id changes
//【6】检查 shareUserId 是否变化
String invalidPackageName =
getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
if (invalidPackageName != null) {
res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
"Package " + invalidPackageName + " tried to change user "
+ oldPackage.mSharedUserId);
return;
}
// check if the new package supports all of the abis which the old package supports
boolean oldPkgSupportMultiArch = oldPackage.applicationInfo.secondaryCpuAbi != null;
boolean newPkgSupportMultiArch = pkg.applicationInfo.secondaryCpuAbi != null;
if (isSystemApp(oldPackage) && oldPkgSupportMultiArch && !newPkgSupportMultiArch) {
res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
"Update to package " + pkgName + " doesn't support multi arch");
return;
}
// In case of rollback, remember per-user/profile install state
//【7】获得系统中所有的 user,和上一次安装的目标 user
allUsers = sUserManager.getUserIds();
installedUsers = ps.queryInstalledUsers(allUsers, true);
// don't allow an upgrade from full to ephemeral
//【3】如果之前安装是 no ephemeral,现在是 ephemeral,那么不能安装
if (isInstantApp) {
if (user == null || user.getIdentifier() == UserHandle.USER_ALL) {
for (int currentUser : allUsers) {
if (!ps.getInstantApp(currentUser)) {
// can't downgrade from full to instant
Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
+ " for user: " + currentUser);
res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
return;
}
}
} else if (!ps.getInstantApp(user.getIdentifier())) {
// can't downgrade from full to instant
Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
+ " for user: " + user.getIdentifier());
res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
return;
}
}
}
// Update what is removed
//【×7.1.1】针对与 replace 的情况,会创建一个 PackageRemovedInfo,封装被 replace 的 app 的信息!
// 如果有子包的话,也会做相同的事情
res.removedInfo = new PackageRemovedInfo(this);
res.removedInfo.uid = oldPackage.applicationInfo.uid;
res.removedInfo.removedPackage = oldPackage.packageName;
res.removedInfo.installerPackageName = ps.installerPackageName;
res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
res.removedInfo.isUpdate = true; // 表示要更新 package
res.removedInfo.origUsers = installedUsers;
res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
for (int i = 0; i < installedUsers.length; i++) {
final int userId = installedUsers[i];
res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
}
final int childCount = (oldPackage.childPackages != null)
? oldPackage.childPackages.size() : 0;
for (int i = 0; i < childCount; i++) {
boolean childPackageUpdated = false;
PackageParser.Package childPkg = oldPackage.childPackages.get(i);
final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
if (res.addedChildPackages != null) {
PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
if (childRes != null) {
childRes.removedInfo.uid = childPkg.applicationInfo.uid;
childRes.removedInfo.removedPackage = childPkg.packageName;
if (childPs != null) {
childRes.removedInfo.installerPackageName = childPs.installerPackageName;
}
childRes.removedInfo.isUpdate = true;
childRes.removedInfo.installReasons = res.removedInfo.installReasons;
childPackageUpdated = true;
}
}
if (!childPackageUpdated) {
PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(this);
childRemovedRes.removedPackage = childPkg.packageName;
if (childPs != null) {
childRemovedRes.installerPackageName = childPs.installerPackageName;
}
childRemovedRes.isUpdate = false;
childRemovedRes.dataRemoved = true;
synchronized (mPackages) {
if (childPs != null) {
childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
}
}
if (res.removedInfo.removedChildPackages == null) {
res.removedInfo.removedChildPackages = new ArrayMap<>();
}
res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
}
}
//【9】判断下旧应用是系统应用,还是非系统应用,然后做不同的处理
boolean sysPkg = (isSystemApp(oldPackage));
if (sysPkg) {
// Set the system/privileged/oem/vendor/product flags as needed
//【9.1】如果是系统应用,再判断是是否是系统特权应用
final boolean privileged =
(oldPackage.applicationInfo.privateFlags
& ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
final boolean oem =
(oldPackage.applicationInfo.privateFlags
& ApplicationInfo.PRIVATE_FLAG_OEM) != 0;
final boolean vendor =
(oldPackage.applicationInfo.privateFlags
& ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0;
final boolean product =
(oldPackage.applicationInfo.privateFlags
& ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0
//【9.2】对于系统应用会增加如下的解析 flags;
final @ParseFlags int systemParseFlags = parseFlags;
final @ScanFlags int systemScanFlags = scanFlags
| SCAN_AS_SYSTEM
| (privileged ? SCAN_AS_PRIVILEGED : 0)
| (oem ? SCAN_AS_OEM : 0)
| (vendor ? SCAN_AS_VENDOR : 0)
| (product ? SCAN_AS_PRODUCT : 0);
//【×2.1】处理系统应用的 replace
replaceSystemPackageLIF(oldPackage, pkg, systemParseFlags, systemScanFlags,
user, allUsers, installerPackageName, res, installReason);
} else {
//【×2.2】处理下非系统应用的 replace
replaceNonSystemPackageLIF(oldPackage, pkg, parseFlags, scanFlags,
user, allUsers, installerPackageName, res, installReason);
}
}
对于判断是否是系统应用,调用了如下的接口:
private static boolean isSystemApp(PackageParser.Package pkg) {
return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
}
这里我们来回顾下传入的参数:final int policyFlags 就是我们之前的解析参数 parseFlags
//【1】默认情况下: mDefParseFlags = 0
@ParseFlags final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
| PackageParser.PARSE_ENFORCE_CODE
| (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
| (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
| (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
//【2】针对系统应用额外增加如下的标志
final int systemPolicyFlags = policyFlags
| PackageParser.PARSE_IS_SYSTEM
| (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0);
同时,对于扫描标志位 scanFlags,和上面保持一致,下面我们来分析下更新 sys app 的流程
private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
PackageParser.Package pkg, final @ParseFlags int parseFlags,
final @ScanFlags int scanFlags, UserHandle user,
int[] allUsers, String installerPackageName, PackageInstalledInfo res,
int installReason) {
if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
+ ", old=" + deletedPackage);
final boolean disabledSystem;
// Remove existing system package
//【*2.1.1】移除掉已安装的 sys app 的数据,包括解析到的四大组件
removePackageLI(deletedPackage, true);
synchronized (mPackages) {
//【*2.1.2】disable 掉系统应用
disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
}
//【1】根据 disabledSystem 的值做不同处理
if (!disabledSystem) {
// We didn't need to disable the .apk as a current system package,
// which means we are replacing another update that is already
// installed. We need to make sure to delete the older one's .apk.
//【1.1】如果 disabledSystem 为 false,说明我们之前已经更新过 sys app 了,其已经被 disable 过了
// 我们现在更新的是位于 data 分区的那个 app,所以要删除掉那个旧的 data app
//【*2.1.3】这里会根据要删除 data 分区的 apk 的数据,创建一个 InstallArgs,用于执行删除操作
res.removedInfo.args = createInstallArgsForExisting(0,
deletedPackage.applicationInfo.getCodePath(),
deletedPackage.applicationInfo.getResourcePath(),
getAppDexInstructionSets(deletedPackage.applicationInfo));
} else {
//【1.2】此时无需删除 app,所以设置为 null
res.removedInfo.args = null;
}
// Successfully disabled the old package. Now proceed with re-installation
//【*2.1.4】清除掉新安装的应用 code_cache 目录下的文件数据
clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
| StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
//【2】给本次扫描的新 app 设置 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP 标志位
pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
PackageParser.Package newPackage = null;
try {
// Add the package to the internal data structures
//【3】再次扫描 apk 文件
newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags, 0, user);
// Set the update and install times
//【4】更新新 apk 的安装时间和最新更新时间(包括子包的)
PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
System.currentTimeMillis());
// Update the package dynamic state if succeeded
//【5】处理安装成功的情况
if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
// Now that the install succeeded make sure we remove data
// directories for any child package the update removed.
final int deletedChildCount = (deletedPackage.childPackages != null)
? deletedPackage.childPackages.size() : 0;
final int newChildCount = (newPackage.childPackages != null)
? newPackage.childPackages.size() : 0;
//【5.1】比较旧的应用和新安装的应用的子包
for (int i = 0; i < deletedChildCount; i++) {
PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
boolean childPackageDeleted = true;
for (int j = 0; j < newChildCount; j++) {
PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
childPackageDeleted = false;
break;
}
}
//【5.1.1】如果旧的应用的子包被删除了,那会移除旧的应用子包遗留下的数据
if (childPackageDeleted) {
PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
deletedChildPkg.packageName);
if (ps != null && res.removedInfo.removedChildPackages != null) {
PackageRemovedInfo removedChildRes = res.removedInfo
.removedChildPackages.get(deletedChildPkg.packageName);
// 移除数据
removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
}
}
}
//【*7.2.1】更新数据
updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
installReason);
//【*7.2.2】准备数据目录,即 data/data/packageName 的目录
prepareAppDataAfterInstallLIF(newPackage);
mDexManager.notifyPackageUpdated(newPackage.packageName,
newPackage.baseCodePath, newPackage.splitCodePaths);
}
} catch (PackageManagerException e) {
res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
res.setError("Package couldn't be installed in " + pkg.codePath, e);
}
//【3】处理安装失败的情况
if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
// Re installation failed. Restore old information
// Remove new pkg information
if (newPackage != null) {
//【*2.1.6】移除新解析的 apk 的数据
removeInstalledPackageLI(newPackage, true);
}
// Add back the old system package
try {
//【3.1】重新扫描旧的 apk(注意如果之前 system apk 已经被更新过了,那么这里
// 恢复的是处于 data 的那个新的 apk)
scanPackageTracedLI(deletedPackage, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user);
} catch (PackageManagerException e) {
Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
}
synchronized (mPackages) {
if (disabledSystem) {
//【*2.1.7】如果本次是第一次更新(即 disable 了 sys app),那么我们要 enable sys app
enableSystemPackageLPw(deletedPackage);
}
// Ensure the installer package name up to date
//【3.2】更新升级包的安装信息,就是 PackageInstaller
setInstallerPackageNameLPw(deletedPackage, installerPackageName);
// Update permissions for restored package
//【3.3】更新权限信息,关于权限的相关逻辑,这里不再分析,但是能推测到更新权限的原因
mPermissionManager.updatePermissions(
deletedPackage.packageName, deletedPackage, false, mPackages.values(),
mPermissionCallback);
//【3.4】持久化数据
mSettings.writeLPr();
}
Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
+ " after failed upgrade");
}
}
移除旧的apk的数据信息:
private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
// Remove the parent package setting 处理父包
PackageSetting ps = (PackageSetting) pkg.mExtras;
if (ps != null) {
removePackageLI(ps, chatty); //【1.1】移除父包的 Settings 对象的 Settings 数据
}
// Remove the child package setting 处理子包
final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
for (int i = 0; i < childCount; i++) {
PackageParser.Package childPkg = pkg.childPackages.get(i);
ps = (PackageSetting) childPkg.mExtras;
if (ps != null) {
removePackageLI(ps, chatty); //【2.1】移除子包的 Settings 对象的 Settings 数据
}
}
}
调用了另外一个 removePackageLI 方法
void removepackageli(packagesetting ps, boolean chatty) {
if (debug_install) {
if (chatty)
log.d(tag, "removing package " + ps.name);
}
// writer
synchronized (mpackages) {
//【1】将应用对应的 PackageSettings 对象删除掉
mpackages.remove(ps.name);
final packageparser.package pkg = ps.pkg;
if (pkg != null) {
//【×2.1.1.1】移除四大组件数据
cleanpackagedatastructureslilpw(pkg, chatty);
}
}
}
用于删除 apk 的四大组件和共享库数据:
void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
//【1】移除 provider
int N = pkg.providers.size();
StringBuilder r = null;
int i;
for (i=0; i<N; i++) {
PackageParser.Provider p = pkg.providers.get(i);
mProviders.removeProvider(p);
if (p.info.authority == null) {
/* There was another ContentProvider with this authority when
* this app was installed so this authority is null,
* Ignore it as we don't have to unregister the provider.
* 【1.1】表示系统之前已经有相同 authority 的 provider,那么这个应用的 provider 是不会注册的.
* 对于没有注册的 provider 不处理
*/
continue;
}
String names[] = p.info.authority.split(";");
for (int j = 0; j < names.length; j++) {
if (mProvidersByAuthority.get(names[j]) == p) {
mProvidersByAuthority.remove(names[j]);
if (DEBUG_REMOVE) {
if (chatty)
Log.d(TAG, "Unregistered content provider: " + names[j]
+ ", className = " + p.info.name + ", isSyncable = "
+ p.info.isSyncable);
}
}
}
if (DEBUG_REMOVE && chatty) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ');
}
r.append(p.info.name);
}
}
if (r != null) {
if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r);
}
//【2】移除 service
N = pkg.services.size();
r = null;
for (i=0; i<N; i++) {
PackageParser.Service s = pkg.services.get(i);
mServices.removeService(s);
if (chatty) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ');
}
r.append(s.info.name);
}
}
if (r != null) {
if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r);
}
//【3】移除 receiver
N = pkg.receivers.size();
r = null;
for (i=0; i<N; i++) {
PackageParser.Activity a = pkg.receivers.get(i);
mReceivers.removeActivity(a, "receiver");
if (DEBUG_REMOVE && chatty) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ');
}
r.append(a.info.name);
}
}
if (r != null) {
if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r);
}
//【4】移除 activity
N = pkg.activities.size();
r = null;
for (i=0; i<N; i++) {
PackageParser.Activity a = pkg.activities.get(i);
mActivities.removeActivity(a, "activity");
if (DEBUG_REMOVE && chatty) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ');
}
r.append(a.info.name);
}
}
if (r != null) {
if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r);
}
//【5】移除定义的 permission,设置了 appop 标志为的权限,从 mAppOpPermissionPackages 也要移除
mPermissionManager.removeAllPermissions(pkg, chatty);
//【7】移除请求的 instrumentation
N = pkg.instrumentation.size();
r = null;
for (i=0; i<N; i++) {
PackageParser.Instrumentation a = pkg.instrumentation.get(i);
mInstrumentation.remove(a.getComponentName());
if (DEBUG_REMOVE && chatty) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ');
}
r.append(a.info.name);
}
}
if (r != null) {
if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r);
}
//【8】移除 SharedLibraries
r = null;
if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
// Only system apps can hold shared libraries.
if (pkg.libraryNames != null) {
for (i = 0; i < pkg.libraryNames.size(); i++) {
String name = pkg.libraryNames.get(i);
if (removeSharedLibraryLPw(name, 0)) {
if (DEBUG_REMOVE && chatty) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ');
}
r.append(name);
}
}
}
}
}
r = null;
// Any package can hold static shared libraries.
if (pkg.staticSharedLibName != null) {
if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) {
if (DEBUG_REMOVE && chatty) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ');
}
r.append(pkg.staticSharedLibName);
}
}
}
if (r != null) {
if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r);
}
}
disable 掉系统应用
private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
PackageParser.Package newPkg) {
// Disable the parent package (parent always replaced) //【2.1.2.1】disable 掉父包,父包是要通过 replace 方式
boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
// Disable the child packages
final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
for (int i = 0; i < childCount; i++) {
PackageParser.Package childPkg = oldPkg.childPackages.get(i);
final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
//【2.1.2.1】disable 掉子包,如果新包也有子包,那就通过 replace 方式
disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
}
return disabled;
}
这里调用了 Settings 的 disableSystemPackageLPw 方法
位置:./frameworks/base/services/core/java/com/android/server/pm/Settings.java
boolean disableSystemPackageLPw(String name, boolean replaced) {
final PackageSetting p = mPackages.get(name);
if(p == null) { //【1】异常判断,如果没安装,直接返回
Log.w(PackageManagerService.TAG, "Package " + name + " is not an installed package");
return false;
}
//【2】尝试从 mDisabledSysPackages 列表中获得 PackageSetting
final PackageSetting dp = mDisabledSysPackages.get(name);
//【3】判断 disable 的条件是否满足:
// 1、之前没有 disable;2、是系统应用;3、没有更新过
// always make sure the system package code and resource paths dont change
if (dp == null && p.pkg != null && p.pkg.isSystem() && !p.pkg.isUpdatedSystemApp()) {
//【3.1】设置 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP 标志位,表示更新过的 sys app
if((p.pkg != null) && (p.pkg.applicationInfo != null)) {
p.pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
}
//【3.2】将其旧应用的 PackageSetting 添加到 mDisabledSysPackages 中
mDisabledSysPackages.put(name, p);
//【3.4】判断是否是 replace,显然,对于 base apk 是需要 replace 的,对于 child apk,
// 需要看新安装的应用是否有相应的子包
if (replaced) {
// a little trick... when we install the new package, we don't
// want to modify the existing PackageSetting for the built-in
// version. so at this point we need a new PackageSetting that
// is okay to muck with.
PackageSetting newp = new PackageSetting(p); // copy 一份旧数据
replacePackageLPw(name, newp); //【3.5】用 copy 后的数据替换之前的数据
}
return true;
}
return false;
}
可以看到,对于系统应用来说,只有第一次覆盖更新时,会 disable 掉 sys 下的那个 app;如果多次覆盖安装,后续的不会再 disable
下面是替换的具体操作
private void replacePackageLPw(String name, PackageSetting newp) {
//【1】获得之前数据,然后根据 uid 的不同做不同的处理
final PackageSetting p = mPackages.get(name);
if (p != null) {
if (p.sharedUser != null) {
p.sharedUser.removePackage(p);
p.sharedUser.addPackage(newp);
} else {
replaceUserIdLPw(p.appId, newp);
}
}
//【2】更新 mPackages 中的数据
mPackages.put(name, newp);
}
旧的数据,此时是在 mDisabledSysPackages 中
这里是针对已存在的应用创建一个 InstallArgs
/**
* Create args that describe an existing installed package. Typically used
* when cleaning up old installs, or used as a move source.
*/
private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
String resourcePath, String[] instructionSets) {
// 创建了实例,描述一个已经存在的 app
return new FileInstallArgs(codePath, resourcePath, instructionSets);
}
清除 app 的数据:
private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
if (pkg == null) {
Slog.wtf(TAG, "Package was null!", new Throwable());
return;
}
//【1】处理父包
clearAppDataLeafLIF(pkg, userId, flags);
final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
for (int i = 0; i < childCount; i++) {
//【2】调用另外一个方法处理子包
clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
}
clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
}
继续看:
private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
final PackageSetting ps;
synchronized (mPackages) {
ps = mSettings.mPackages.get(pkg.packageName);
}
for (int realUserId : resolveUserIds(userId)) {
final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
try {
mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
ceDataInode);
} catch (InstallerException e) {
Slog.w(TAG, String.valueOf(e));
}
}
}
清除 app 的 profiles 数据:
private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
if (pkg == null) {
Slog.wtf(TAG, "Package was null!", new Throwable());
return;
}
mArtManagerService.clearAppProfiles(pkg);
final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
for (int i = 0; i < childCount; i++) {
mArtManagerService.clearAppProfiles(pkg.childPackages.get(i));
}
}
移除被扫描到的新的 apk 的数据:
void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
if (DEBUG_INSTALL) {
if (chatty)
Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
}
// writer
synchronized (mPackages) {
// Remove the parent package //【1】移除父包
mPackages.remove(pkg.applicationInfo.packageName);
//【*2.1.1.1】移除父包的数据结构
cleanPackageDataStructuresLILPw(pkg, chatty);
// Remove the child packages
final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
for (int i = 0; i < childCount; i++) {
//【2】移除子包
PackageParser.Package childPkg = pkg.childPackages.get(i);
mPackages.remove(childPkg.applicationInfo.packageName);
//【*2.1.1.1】移除子包的数据结构
cleanPackageDataStructuresLILPw(childPkg, chatty);
}
}
}
恢复系统应用
private void enableSystemPackageLPw(PackageParser.Package pkg) {
// Enable the parent package //【1】恢复父包
mSettings.enableSystemPackageLPw(pkg.packageName);
// Enable the child packages
final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
for (int i = 0; i < childCount; i++) {
PackageParser.Package childPkg = pkg.childPackages.get(i);
//【*2.1.7.1】恢复子包
mSettings.enableSystemPackageLPw(childPkg.packageName);
}
}
最终会调用 Settings 的 enableSystemPackageLPw 方法 enable package:
PackageSetting enableSystemPackageLPw(String name) {
//【1】判断该 sys package 是否被 disable 了
PackageSetting p = mDisabledSysPackages.get(name);
if(p == null) {
Log.w(PackageManagerService.TAG, "Package " + name + " is not disabled");
return null;
}
// Reset flag in ApplicationInfo object
//【2】取消 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP 标志位
if((p.pkg != null) && (p.pkg.applicationInfo != null)) {
p.pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
}
//【3】重新为该 system 创建一个 PackageSetting 对象,并添加到相应的集合中
PackageSetting ret = addPackageLPw(name, p.realName, p.codePath, p.resourcePath,
p.legacyNativeLibraryPathString, p.primaryCpuAbiString,
p.secondaryCpuAbiString, p.cpuAbiOverrideString,
p.appId, p.versionCode, p.pkgFlags, p.pkgPrivateFlags,
p.parentPackageName, p.childPackageNames, p.usesStaticLibraries,
p.usesStaticLibrariesVersions);
//【4】从 mDisabledSysPackages 中删除
mDisabledSysPackages.remove(name);
return ret;
}
关于 addPackageLPw 的逻辑这里就不在分析了
这里我们分析下覆盖安装三方应用的流程,对于扫描标志位 scanFlags,和上面保持一致:
private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
PackageParser.Package pkg, final @ParseFlags int parseFlags,
final @ScanFlags int scanFlags, UserHandle user, int[] allUsers,
String installerPackageName, PackageInstalledInfo res, int installReason) {
if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
+ deletedPackage);
String pkgName = deletedPackage.packageName; // 获得包名
boolean deletedPkg = true;
boolean addedPkg = false;
boolean updatedSettings = false;
final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
//【1】设置删除 flags,会保留用户数据
final int deleteFlags = PackageManager.DELETE_KEEP_DATA
| (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
final long origUpdateTime = (pkg.mExtras != null)
? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
// First delete the existing package while retaining the data directory
//【*2.2.1】删除在 data 分区的旧 apk 数据,res.removedInfo 用于表示要移除的 apk!!
// 删除失败会进入 if 分支
if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
res.removedInfo, true, pkg)) {
// If the existing package wasn't successfully deleted
res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
deletedPkg = false;
} else {
// Successfully deleted the old package; proceed with replace.
// If deleted package lived in a container, give users a chance to
// relinquish resources before killing.
//【2】删除成功后,要判断下被删除的 apk 是否安装在 External 位置或者其是否是 forward lock 的
// 如果是,那么我们要发送资源变化的广播通知其他进程
if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
if (DEBUG_INSTALL) {
Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
}
final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
final ArrayList<String> pkgList = new ArrayList<String>(1);
pkgList.add(deletedPackage.applicationInfo.packageName);
sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
}
//【*2.1.4】清楚 code cache 数据
//【*2.1.5】清楚要被删除的应用的 profile 数据,这个和 odex 优化相关
clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
| StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
try {
//【3】扫描新的 apk 应用
final PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags,
scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
//【4】更新系统中的数据结构
updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
installReason);
// Update the in-memory copy of the previous code paths.
//【5】记录保存被删除的旧 apk 的 code path,包括父包和子包
PackageSetting ps = mSettings.mPackages.get(pkgName);
if (!killApp) {
if (ps.oldCodePaths == null) {
ps.oldCodePaths = new ArraySet<>();
}
Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
if (deletedPackage.splitCodePaths != null) {
Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
}
} else {
ps.oldCodePaths = null;
}
if (ps.childPackageNames != null) {
for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
final String childPkgName = ps.childPackageNames.get(i);
final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
childPs.oldCodePaths = ps.oldCodePaths;
}
}
//【*7.2.2】准备 app 数据目录
prepareAppDataAfterInstallLIF(newPackage);
addedPkg = true; // 表示安装应用成功
mDexManager.notifyPackageUpdated(newPackage.packageName,
newPackage.baseCodePath, newPackage.splitCodePaths);
} catch (PackageManagerException e) {
res.setError("Package couldn't be installed in " + pkg.codePath, e);
}
}
//【6】如果前面的处理没有问题,进入 if 分支
if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
// Revert all internal state mutations and added folders for the failed install
//【*2.2.1】如果安装不成功,但是我们已经扫描了新的 apk 那么这里会删除其遗留的数据
if (addedPkg) {
deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
res.removedInfo, true, null);
}
// Restore the old package
//【2.1】如果新 apk 安装失败了,并且执行了清理旧的 apk 的数据,那么这里会 reinstall 旧 apk
if (deletedPkg) {
if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
File restoreFile = new File(deletedPackage.codePath);
// Parse old package //【2.1.1】设置解析参数 flags
boolean oldExternal = isExternal(deletedPackage);
int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY |
(deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
(oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
try {
//【2.1.2】重新解析和扫描旧的 apk
scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
null);
} catch (PackageManagerException e) {
Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
+ e.getMessage());
return;
}
synchronized (mPackages) {
// Ensure the installer package name up to date //【2.1.3】设置 installer name
setInstallerPackageNameLPw(deletedPackage, installerPackageName);
// Update permissions for restored package //【2.1.4】更新被恢复的旧 apk 的权限信息
mPermissionManager.updatePermissions(
deletedPackage.packageName, deletedPackage, false, mPackages.values(),
mPermissionCallback);
//【2.1.5】持久化内存中的应用数据
mSettings.writeLPr();
}
Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
}
} else {
//【7】新 apk 覆盖安装成功了,进入 else
synchronized (mPackages) {
PackageSetting ps = mSettings.getPackageLPr(pkg.packageName);
if (ps != null) {
//【7.1】更新要从那些 user 下移除
res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
if (res.removedInfo.removedChildPackages != null) {
final int childCount = res.removedInfo.removedChildPackages.size();
// Iterate in reverse as we may modify the collection
for (int i = childCount - 1; i >= 0; i--) {
String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
if (res.addedChildPackages.containsKey(childPackageName)) {
res.removedInfo.removedChildPackages.removeAt(i);
} else {
PackageRemovedInfo childInfo = res.removedInfo
.removedChildPackages.valueAt(i);
childInfo.removedForAllUsers = mPackages.get(
childInfo.removedPackage) == null;
}
}
}
}
}
}
}
删除 apk,参数 PackageParser.Package replacingPackage 表示用于 replace 的 package:
deletePackageLIF 中的逻辑很多涉及到了 delete package 的逻辑,和 install package 并没有太大关系,我们在后面的 delete package 中会继续分析
private boolean deletePackageLIF(String packageName, UserHandle user,
boolean deleteCodeAndResources, int[] allUserHandles, int flags,
PackageRemovedInfo outInfo, boolean writeSettings,
PackageParser.Package replacingPackage) {
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;
synchronized (mPackages) { //【1】获得要删除的 apk 的 PackageSetting 数据
ps = mSettings.mPackages.get(packageName);
if (ps == null) {
Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
return false;
}
//【2】处理子包的数据:
// 如果是子包,并且(其不是系统应用,或者 deleteFlags 设置了 DELETE_SYSTEM_APP 标志)
// 那么我们会清除该子包的使用状态,同时设置在设备用户下处于未安装状态
if (ps.parentPackageName != null && (!isSystemApp(ps)
|| (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
if (DEBUG_REMOVE) {
Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
+ ((user == null) ? UserHandle.USER_ALL : user));
}
//【2.1】判断下要在那些 user 下删除该子包 apk 的状态信息
final int removedUserId = (user != null) ? user.getIdentifier()
: UserHandle.USER_ALL;
//【*2.2.1.1】清除掉 userId 下的子包 apk 的使用信息
if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
return false;
}
//【*2.2.1.2】更新子包 apk 在该 user 下为未安装状态
markPackageUninstalledForUserLPw(ps, user);
//【2.2】更新应用偏好设置
scheduleWritePackageRestrictionsLocked(user);
return true;
}
}
final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
if (ps.getPermissionsState().hasPermission(Manifest.permission.SUSPEND_APPS, userId)) {
unsuspendForSuspendingPackage(packageName, userId);
}
//【3】如果只是删除在指定 user 下的安装信息,那么我们会设置其在该 user 下为未安装的状态,同时删除其数据
// 如果 deleteFlags 设置了 DELETE_SYSTEM_APP 标志位,表示删除的是系统应用
if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
&& user.getIdentifier() != UserHandle.USER_ALL)) {
// The caller is asking that the package only be deleted for a single
// user. To do this, we just mark its uninstalled state and delete
// its data. If this is a system app, we only allow this to happen if
// they have set the special DELETE_SYSTEM_APP which requests different
// semantics than normal for uninstalling system apps.
//【*2.2.1.2】更新子包 apk 在该 user 下为未安装状态
markPackageUninstalledForUserLPw(ps, user);
if (!isSystemApp(ps)) {
// Do not uninstall the APK if an app should be cached
//【3.1】对于非系统应用的情况,先判断下是否需要保留不卸载
boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
//【3.2】如果该 package 在其他用户下有安装;或者其需要保留不卸载
// 那么我们只需要清楚在当前指定的用户 user 下的数据并设置其为未安装状态
if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
// Other user still have this package installed, so all
// we need to do is clear this user's data and save that
// it is uninstalled.
if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
//【*2.2.1.1】清除掉当前指定的用户 user 下的 apk 的使用信息
if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
return false;
}
//【3.3】更新应用偏好设置,然后返回
scheduleWritePackageRestrictionsLocked(user);
return true;
} else {
// We need to set it back to 'installed' so the uninstall
// broadcasts will be sent correctly.
//【3.4】这里说明其没有在其他 user 下安装,同时也不需要保留,那么后面会执行删除操作
// 这里会将在当前指定的用户 user 下的安装状态设置为 installed,这样卸载广播能正确发出
if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
ps.setInstalled(true, user.getIdentifier());
mSettings.writeKernelMappingLPr(ps);
}
} else {
// This is a system app, so we assume that the
// other users still have this package installed, so all
// we need to do is clear this user's data and save that
// it is uninstalled.
//【3.5】对于系统应用的情况,这里只会清楚当前指定用户下的数据,然后返回
if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
//【*2.2.1.1】清除掉当前指定的用户 user 下的 apk 的使用信息
if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
return false;
}
//【3.6】更新应用偏好设置,然后返回
scheduleWritePackageRestrictionsLocked(user);
return true;
}
}
// If we are deleting a composite package for all users, keep track
// of result for each child.
//【4】这里按照逻辑,只有系统 apk 才能进入,因为只有系统 apk 才有子包!
// 这里是处理每个子包的移除信息,包括子包名,子包所在 user
if (ps.childPackageNames != null && outInfo != null) {
synchronized (mPackages) {
final int childCount = ps.childPackageNames.size();
outInfo.removedChildPackages = new ArrayMap<>(childCount);
for (int i = 0; i < childCount; i++) {
String childPackageName = ps.childPackageNames.get(i);
PackageRemovedInfo childInfo = new PackageRemovedInfo(this);
childInfo.removedPackage = childPackageName;
childInfo.installerPackageName = ps.installerPackageName;
//【4.1】添加到父包的 removedChildPackages 集合中
outInfo.removedChildPackages.put(childPackageName, childInfo);
PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
if (childPs != null) {
childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
}
}
}
}
boolean ret = false;
if (isSystemApp(ps)) {
if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
// When an updated system application is deleted we delete the existing resources
// as well and fall back to existing code in system partition
//【×2.2.1.3】删除系统 apk,如果系统 apk 之前被覆盖更新了,那么我们会删除新的 apk
// 回滚到 system 分区的旧 apk
ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
} else {
if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
//【×8.1.4】删除非系统的 apk
ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
outInfo, writeSettings, replacingPackage);
}
// Take a note whether we deleted the package for all users
//【5】记录下,我们是否从所有的用户 user 下删除了该 package
if (outInfo != null) {
//【5.1】更新父包和子包的 removedForAllUsers 属性
outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
if (outInfo.removedChildPackages != null) {
synchronized (mPackages) {
final int childCount = outInfo.removedChildPackages.size();
for (int i = 0; i < childCount; i++) {
PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
if (childInfo != null) {
childInfo.removedForAllUsers = mPackages.get(
childInfo.removedPackage) == null;
}
}
}
}
// If we uninstalled an update to a system app there may be some
// child packages that appeared as they are declared in the system
// app but were not declared in the update.
//【5.2】我们卸载的是一个系统 apk 的更新包,那么可能有些子包在 system 分区的旧 apk 中声明了
// 但是在新的 data 更新 apk 中没有申明,这里会处理这种情况
if (isSystemApp(ps)) {
synchronized (mPackages) {
PackageSetting updatedPs = mSettings.getPackageLPr(ps.name);
final int childCount = (updatedPs.childPackageNames != null)
? updatedPs.childPackageNames.size() : 0;
for (int i = 0; i < childCount; i++) {
String childPackageName = updatedPs.childPackageNames.get(i);
if (outInfo.removedChildPackages == null
|| outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
if (childPs == null) {
continue;
}
PackageInstalledInfo installRes = new PackageInstalledInfo();
installRes.name = childPackageName;
installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
installRes.pkg = mPackages.get(childPackageName);
installRes.uid = childPs.pkg.applicationInfo.uid;
if (outInfo.appearedChildPackages == null) {
outInfo.appearedChildPackages = new ArrayMap<>();
}
//【5.3】将这些子包保存到 outInfo.appearedChildPackages 中
outInfo.appearedChildPackages.put(childPackageName, installRes);
}
}
}
}
}
return ret;
}
清除指定 user 下的应用数据,这里涉及到的清理操作很多,由于篇幅,这里先不细讲,等到卸载应用时在深入分析
private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
PackageRemovedInfo outInfo) {
final PackageParser.Package pkg;
synchronized (mPackages) {
pkg = mPackages.get(ps.name); //【1】获得旧 apk 的扫描信息
}
//【2】判断要删除那些 user 下的状态数据
final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
: new int[] {userId};
for (int nextUserId : userIds) {
if (DEBUG_REMOVE) {
Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
+ nextUserId);
}
//【×2.2.1.1.1】删除掉旧 apk 的使用状态本地记录文件
destroyAppDataLIF(pkg, userId,
StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
//【×2.2.1.1.2】删除 profile 相关信息
destroyAppProfilesLIF(pkg, userId);
clearDefaultBrowserIfNeededForUser(ps.name, userId);
//【4】移除 key store
removeKeystoreDataIfNeeded(nextUserId, ps.appId);
//【×2.2.1.1.3】执行 package clean 操作
schedulePackageCleaning(ps.name, nextUserId, false);
synchronized (mPackages) {
//【5】清楚默认应用设置
if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
//【5.1】更新偏好设置
scheduleWritePackageRestrictionsLocked(nextUserId);
}
//【6】更新运行时权限信息
resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
}
}
if (outInfo != null) {
outInfo.removedPackage = ps.name;
outInfo.installerPackageName = ps.installerPackageName;
outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null;
outInfo.removedAppId = ps.appId;
outInfo.removedUsers = userIds;
outInfo.broadcastUsers = userIds;
}
return true;
}
关于以下的内容,会在卸载 app 和权限相关文章中分析,这里由于篇幅原因(markdown 只支持 6 级标题),就先不深入分析了
//【3】删除 profile 相关信息!!
destroyAppProfilesLIF(pkg, userId);
//【4】移除 key store!!
removeKeystoreDataIfNeeded(nextUserId, ps.appId);
//【5】清楚默认应用设置
clearPackagePreferredActivitiesLPw();
//【6】更新运行时权限信息!
resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
clearPackageStateForUserLIF >> destroyAppDataLIF
private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
if (pkg == null) {
Slog.wtf(TAG, "Package was null!", new Throwable());
return;
}
//【1】删除父包的数据
destroyAppDataLeafLIF(pkg, userId, flags);
final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
for (int i = 0; i < childCount; i++) {
//【2】删除子包的数据
destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
}
}
继续看:
destroyAppDataLIF >> destroyAppDataLeafLIF
private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
final PackageSetting ps;
synchronized (mPackages) {
//【1】获得该应用的安装信息 PackageSetting
ps = mSettings.mPackages.get(pkg.packageName);
}
for (int realUserId : resolveUserIds(userId)) {
//【2】获得要删除的状态信息目录:
final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
try {
//【3】调用了 Installd 删除指定目录
mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
ceDataInode);
} catch (InstallerException e) {
Slog.w(TAG, String.valueOf(e));
}
mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
}
}
这里使用了 PackageSetting.getCeDataInode 方法:
long getCeDataInode(int userId) {
return readUserState(userId).ceDataInode;
}
该方法返回的是 PackageUserState.ceDataInode 的值。
clearPackageStateForUserLIF >> schedulePackageCleaning
void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
//这里会发送一个 START_CLEANING_PACKAGE 的消息给 PackageHandler
final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
userId, andCode ? 1 : 0, packageName);
if (mSystemReady) {
msg.sendToTarget();
} else {
if (mPostSystemReadyMessages == null) {
mPostSystemReadyMessages = new ArrayList<>();
}
mPostSystemReadyMessages.add(msg);
}
}
schedulePackageCleaning >> START_CLEANING_PACKAGE处理
case START_CLEANING_PACKAGE: {
Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
final String packageName = (String)msg.obj;
final int userId = msg.arg1;
final boolean andCode = msg.arg2 != 0;
synchronized (mPackages) {
if (userId == UserHandle.USER_ALL) {
int[] users = sUserManager.getUserIds();
for (int user : users) {
//【1】将 package 加入到 Settings 内部的 mPackagesToBeCleaned 集合中
mSettings.addPackageToCleanLPw(
new PackageCleanItem(user, packageName, andCode));
}
} else {
mSettings.addPackageToCleanLPw(
new PackageCleanItem(userId, packageName, andCode));
}
}
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
startCleaningPackages();
} break;
START_CLEANING_PACKAGE处理 >> startCleaningPackages
void startCleaningPackages() {
// reader
if (!isExternalMediaAvailable()) {
return;
}
synchronized (mPackages) {
if (mSettings.mPackagesToBeCleaned.isEmpty()) {
return;
}
}
//【1】发送 action PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE
Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
//【2】目标组件服务:DefaultContainerService
intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
IActivityManager am = ActivityManager.getService();
if (am != null) {
int dcsUid = -1;
synchronized (mPackages) {
if (!mDefaultContainerWhitelisted) {
mDefaultContainerWhitelisted = true;
PackageSetting ps = mSettings.mPackages.get(DEFAULT_CONTAINER_PACKAGE);
dcsUid = UserHandle.getUid(UserHandle.USER_SYSTEM, ps.appId);
}
}
try {
if (dcsUid > 0) {
am.backgroundWhitelistUid(dcsUid);
}
//【2.1】启动服务
am.startService(null, intent, null, false, mContext.getOpPackageName(),
UserHandle.USER_SYSTEM);
} catch (RemoteException e) {
}
}
}
进入 DefaultContainerService.onHandleIntent 方法:
@Override
protected void onHandleIntent(Intent intent) {
if (PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE.equals(intent.getAction())) {
final IPackageManager pm = IPackageManager.Stub.asInterface(
ServiceManager.getService("package"));
PackageCleanItem item = null;
try {
while ((item = pm.nextPackageToClean(item)) != null) {
final UserEnvironment userEnv = new UserEnvironment(item.userId);
eraseFiles(userEnv.buildExternalStorageAppDataDirs(item.packageName));
eraseFiles(userEnv.buildExternalStorageAppMediaDirs(item.packageName));
if (item.andCode) {
eraseFiles(userEnv.buildExternalStorageAppObbDirs(item.packageName));
}
}
} catch (RemoteException e) {
}
}
}
private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
for (int nextUserId : userIds) {
if (DEBUG_REMOVE) {
Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
}
//【1】调用了 PackageSettings 的 setUserState 接口
ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
false /*installed*/,
true /*stopped*/,
true /*notLaunched*/,
false /*hidden*/,
false /*suspended*/,
null /*suspendingPackage*/,
null /*dialogMessage*/,
null /*suspendedAppExtras*/,
null /*suspendedLauncherExtras*/,
false /*instantApp*/,
false /*virtualPreload*/,
null /*lastDisableAppCaller*/,
null /*enabledComponents*/,
null /*disabledComponents*/,
ps.readUserState(nextUserId).domainVerificationStatus,
0, PackageManager.INSTALL_REASON_UNKNOWN,
null /*harmfulAppWarning*/);
}
mSettings.writeKernelMappingLPr(ps);
}
在replaceNonSystemPackageLIF设置了关于 flags 的设置:
//【1】设置删除 flags,会保留用户数据
final int deleteFlags = PackageManager.DELETE_KEEP_DATA
| (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
删除 system 更新 apk,PackageRemovedInfo outInfo 用于封装移除的相关信息
private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
boolean writeSettings) {
if (deletedPs.parentPackageName != null) {
Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
return false;
}
final boolean applyUserRestrictions
= (allUserHandles != null) && (outInfo.origUsers != null);
final PackageSetting disabledPs;
// Confirm if the system package has been updated
// An updated system app can be deleted. This will also have to restore
// the system pkg from system partition
// reader
synchronized (mPackages) {
//【1】尝试获得被更新的 system apk 数据
disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
}
if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
+ " disabledPs=" + disabledPs);
//【2】如果没有更新,那就不能删除,对于系统 apk,我们只能删除覆盖更新在 data 分区的
if (disabledPs == null) {
Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
return false;
} else if (DEBUG_REMOVE) {
Slog.d(TAG, "Deleting system pkg from data partition");
}
if (DEBUG_REMOVE) {
if (applyUserRestrictions) {
Slog.d(TAG, "Remembering install states:");
for (int userId : allUserHandles) {
final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
Slog.d(TAG, " u=" + userId + " inst=" + finstalled);
}
}
}
// Delete the updated package
//【3】设置父包和子包的 isRemovedPackageSystemUpdate 为 true
outInfo.isRemovedPackageSystemUpdate = true;
if (outInfo.removedChildPackages != null) {
final int childCount = (deletedPs.childPackageNames != null)
? deletedPs.childPackageNames.size() : 0;
for (int i = 0; i < childCount; i++) {
String childPackageName = deletedPs.childPackageNames.get(i);
if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
.contains(childPackageName)) {
PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
childPackageName);
if (childInfo != null) {
childInfo.isRemovedPackageSystemUpdate = true;
}
}
}
}
//【4】判读 version code,如果出现降级,那么就不能保留数据
if (disabledPs.versionCode < deletedPs.versionCode) {
// Delete data for downgrades
flags &= ~PackageManager.DELETE_KEEP_DATA;
} else {
// Preserve data by setting flag
flags |= PackageManager.DELETE_KEEP_DATA;
}
//【×2.2.1.4】执行删除 data 分区新 apk,删除失败就结束操作
boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
outInfo, writeSettings, disabledPs.pkg);
if (!ret) {
return false;
}
// writer //【5】恢复 system 分区的旧 apk 的数据,同时删除更新的 apk 的 native libs
synchronized (mPackages) {
// NOTE: The system package always needs to be enabled; even if it's for
// a compressed stub. If we don't, installing the system package fails
// during scan [scanning checks the disabled packages]. We will reverse
// this later, after we've "installed" the stub.
// Reinstate the old system package
enableSystemPackageLPw(disabledPs.pkg);
// Remove any native libraries from the upgraded package.
removeNativeBinariesLI(deletedPs);
}
// Install the system package //【6】设置扫描 flags
if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
try {
installPackageFromSystemLIF(disabledPs.codePathString, false, allUserHandles,
outInfo.origUsers, deletedPs.getPermissionsState(), writeSettings);
} catch (PackageManagerException e) {
Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
+ e.getMessage());
return false;
} finally {
if (disabledPs.pkg.isStub) {
mSettings.disableSystemPackageLPw(disabledPs.name, true /*replaced*/);
}
}
return true;
}
deleteSystemPackageLIF >> installPackageFromSystemLIF
/**
* Installs a package that's already on the system partition.
*/
private PackageParser.Package installPackageFromSystemLIF(@NonNull String codePathString,
boolean isPrivileged, @Nullable int[] allUserHandles, @Nullable int[] origUserHandles,
@Nullable PermissionsState origPermissionState, boolean writeSettings)
throws PackageManagerException {
@ParseFlags int parseFlags =
mDefParseFlags
| PackageParser.PARSE_MUST_BE_APK
| PackageParser.PARSE_IS_SYSTEM_DIR;
@ScanFlags int scanFlags = SCAN_AS_SYSTEM;
if (isPrivileged || locationIsPrivileged(codePathString)) {
scanFlags |= SCAN_AS_PRIVILEGED;
}
if (locationIsOem(codePathString)) {
scanFlags |= SCAN_AS_OEM;
}
if (locationIsVendor(codePathString)) {
scanFlags |= SCAN_AS_VENDOR;
}
if (locationIsProduct(codePathString)) {
scanFlags |= SCAN_AS_PRODUCT;
}
//【7】扫描旧的 system apk
final File codePath = new File(codePathString);
final PackageParser.Package pkg =
scanPackageTracedLI(codePath, parseFlags, scanFlags, 0 /*currentTime*/, null);
try {
// update shared libraries for the newly re-installed system package
//【8】更新 shared libs 给重新安装的 system apk
updateSharedLibrariesLPr(pkg, null);
} catch (PackageManagerException e) {
Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
}
//【*7.2.2】准备 app 数据目录
prepareAppDataAfterInstallLIF(pkg);
// writer //【9】更新 pms 数据
synchronized (mPackages) {
PackageSetting ps = mSettings.mPackages.get(pkg.packageName);
// Propagate the permissions state as we do not want to drop on the floor
// runtime permissions. The update permissions method below will take
// care of removing obsolete permissions and grant install permissions.
if (origPermissionState != null) {
//【9.1】从被删除的 data 分区 apk 那里继承最新的权限信息
ps.getPermissionsState().copyFrom(origPermissionState);
}
//【9.2】更新系统中所有应用的权限信息
mPermissionManager.updatePermissions(pkg.packageName, pkg, true, mPackages.values(),
mPermissionCallback);
final boolean applyUserRestrictions
= (allUserHandles != null) && (origUserHandles != null);
if (applyUserRestrictions) {
boolean installedStateChanged = false;
if (DEBUG_REMOVE) {
Slog.d(TAG, "Propagating install state across reinstall");
}
for (int userId : allUserHandles) {
final boolean installed = ArrayUtils.contains(origUserHandles, userId);
if (DEBUG_REMOVE) {
Slog.d(TAG, " user " + userId + " => " + installed);
}
if (installed != ps.getInstalled(userId)) {
installedStateChanged = true;
}
ps.setInstalled(installed, userId);
//【9.3】持久化运行时权限
mSettings.writeRuntimePermissionsForUserLPr(userId, false);
}
// Regardless of writeSettings we need to ensure that this restriction
// state propagation is persisted //【9.4】持久化应用偏好设置
mSettings.writeAllUsersPackageRestrictionsLPr();
if (installedStateChanged) {
mSettings.writeKernelMappingLPr(ps);
}
}
// can downgrade to reader here //【9.5】持久化最新的所有应用数据
if (writeSettings) {
mSettings.writeLPr();
}
}
return pkg;
}
如果不是系统app就用这个删除函数,他的falgs和2.2.1.3里的一样的
private boolean deleteInstalledPackageLIF(PackageSetting ps,
boolean deleteCodeAndResources, int flags, int[] allUserHandles,
PackageRemovedInfo outInfo, boolean writeSettings,
PackageParser.Package replacingPackage) {
synchronized (mPackages) {
if (outInfo != null) {
outInfo.uid = ps.appId;
}
if (outInfo != null && outInfo.removedChildPackages != null) {
final int childCount = (ps.childPackageNames != null)
? ps.childPackageNames.size() : 0;
for (int i = 0; i < childCount; i++) {
String childPackageName = ps.childPackageNames.get(i);
PackageSetting childPs = mSettings.mPackages.get(childPackageName);
if (childPs == null) {
return false;
}
PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
childPackageName);
if (childInfo != null) {
childInfo.uid = childPs.appId;
}
}
}
}
// Delete package data from internal structures and also remove data if flag is set
//【×2.2.1.4.1】移除 package 的数据
removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
// Delete the child packages data //【1】如果有子包,也会移除子包的数据
final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
for (int i = 0; i < childCount; i++) {
PackageSetting childPs;
synchronized (mPackages) {
childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
}
if (childPs != null) {
PackageRemovedInfo childOutInfo = (outInfo != null
&& outInfo.removedChildPackages != null)
? outInfo.removedChildPackages.get(childPs.name) : null;
final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
&& (replacingPackage != null
&& !replacingPackage.hasChildPackage(childPs.name))
? flags & ~DELETE_KEEP_DATA : flags;
//【×2.2.1.4.1】移除 package 的数据
removePackageDataLIF(childPs, allUserHandles, childOutInfo,
deleteFlags, writeSettings);
}
}
// Delete application code and resources only for parent packages
//【2】对于被删除的父包,会创建一个 InstallArgs,用于删除 apk 和资源
if (ps.parentPackageName == null) {
if (deleteCodeAndResources && (outInfo != null)) {
//【×6.2.1.3】根据一个存在的 package 创建一个 InstallArgs 中
outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
}
}
return true;
}
deleteInstalledPackageLIF >> removePackageDataLIF
private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
String packageName = ps.name;
if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
// Retrieve object to delete permissions for shared user later on
final PackageParser.Package deletedPkg;
final PackageSetting deletedPs;
// reader
synchronized (mPackages) {
//【1】获得要被删除的 apk 的 PackageSetting 和 PackageParser.Package 对象
deletedPkg = mPackages.get(packageName);
deletedPs = mSettings.mPackages.get(packageName);
if (outInfo != null) {
outInfo.removedPackage = packageName;
outInfo.installerPackageName = ps.installerPackageName;
outInfo.isStaticSharedLib = deletedPkg != null
&& deletedPkg.staticSharedLibName != null;
outInfo.populateUsers(deletedPs == null ? null
: deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true), deletedPs);
}
}
//【×2.2.1.4.1】第一部移除,扫描和四大组件信息
removePackageLI(ps, (flags & PackageManager.DELETE_CHATTY) != 0);
//【2】如果 flags 没有设置 DELETE_KEEP_DATA,那么会清楚 apk 的数据,显然这里由于设置了,那么就不会清楚
if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
final PackageParser.Package resolvedPkg;
if (deletedPkg != null) {
resolvedPkg = deletedPkg;
} else {
// We don't have a parsed package when it lives on an ejected
// adopted storage device, so fake something together
resolvedPkg = new PackageParser.Package(ps.name);
resolvedPkg.setVolumeUuid(ps.volumeUuid);
}
//【×2.2.1.1.1】删除 apk 的 data 数据
destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
//【×2.2.1.1.2】删除 apk 的 profiles 数据
destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
if (outInfo != null) {
outInfo.dataRemoved = true;
}
//【×2.2.1.1.3】执行 package 清除
schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
}
int removedAppId = -1;
// writer //【3】进一步处理
synchronized (mPackages) {
boolean installedStateChanged = false;
if (deletedPs != null) {
//【3.1】如果 flags 没有设置 DELETE_KEEP_DATA 标志位,那么执行其他的清楚操作
if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
//【3.1.1】清楚 intentfilter verify 和 默认浏览器的设置数据
clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
clearDefaultBrowserIfNeeded(packageName);
mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
removedAppId = mSettings.removePackageLPw(packageName);
if (outInfo != null) {
outInfo.removedAppId = removedAppId;
}
//【3.1.2】更新权限信息
mPermissionManager.updatePermissions(
deletedPs.name, null, false, mPackages.values(), mPermissionCallback);
if (deletedPs.sharedUser != null) { //【3.1.3】如果该应用是共享 shared user 的,进入这里
// Remove permissions associated with package. Since runtime
// permissions are per user we have to kill the removed package
// or packages running under the shared user of the removed
// package if revoking the permissions requested only by the removed
// package is successful and this causes a change in gids.
for (int userId : UserManagerService.getInstance().getUserIds()) {
//【3.1.3.1】更新该共享 shared uid 的权限,该 package 被移除掉,会导致和该
// 应用相关连的权限的变化,从而导致共享 shared uid 的 gids 发生变化
final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
userId);
if (userIdToKill == UserHandle.USER_ALL
|| userIdToKill >= UserHandle.USER_SYSTEM) {
// If gids changed for this user, kill all affected packages.
//【3.1.3.1】如果共享 shared uid 的 gids 发生变化,杀掉该 uid 下的
// 所有的 app 进程
mHandler.post(new Runnable() {
@Override
public void run() {
// This has to happen with no lock held.
killApplication(deletedPs.name, deletedPs.appId,
KILL_APP_REASON_GIDS_CHANGED);
}
});
break;
}
}
}
//【3.1.4】清除默认应用的数据
clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
}
// make sure to preserve per-user disabled state if this removal was just
// a downgrade of a system app to the factory package
//【3.4】更新下在每个 user 下的安装状态
if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
if (DEBUG_REMOVE) {
Slog.d(TAG, "Propagating install state across downgrade");
}
for (int userId : allUserHandles) {
final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
if (DEBUG_REMOVE) {
Slog.d(TAG, " user " + userId + " => " + installed);
}
if (installed != ps.getInstalled(userId)) {
installedStateChanged = true;
}
ps.setInstalled(installed, userId);
}
}
}
// can downgrade to reader //【3.5】持久化 Settings
if (writeSettings) {
// Save settings now
mSettings.writeLPr();
}
if (installedStateChanged) {
mSettings.writeKernelMappingLPr(ps);
}
}
if (removedAppId != -1) {
// A user ID was deleted here. Go through all users and remove it
// from KeyStore. //【4】移除 key-store
removeKeystoreDataIfNeeded(UserHandle.USER_ALL, removedAppId);
}
}
removePackageDataLIF >> removePackageLI
void removePackageLI(PackageSetting ps, boolean chatty) {
if (DEBUG_INSTALL) {
if (chatty)
Log.d(TAG, "Removing package " + ps.name);
}
// writer
synchronized (mPackages) {
mPackages.remove(ps.name); //【1】移除扫描信息
final PackageParser.Package pkg = ps.pkg;
if (pkg != null) {
//【×6.2.1.6.1】移除四大组件,共享库解析对象
cleanPackageDataStructuresLILPw(pkg, chatty);
}
}
}