android 9 adb安装过程学习(四)覆盖安装

六、PackageManagerService.replacePackageLIF - 覆盖安装

一、参数分析

位置:"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;
    }

2.1 replaceSystemPackageLIF - 覆盖安装系统应用

这里我们来回顾下传入的参数: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");
        }
    }

2.1.1 removePackageLI

移除旧的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);
            }
        }
    }
2.1.1.1 cleanPackageDataStructuresLILPw

用于删除 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);
        }
    }

2.1.2 disableSystemPackageLPw

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 方法

2.1.2.1 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 中

2.1.3 createInstallArgsForExisting - 要删除的被更新 apk

这里是针对已存在的应用创建一个 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);
    }

2.1.4 clearAppDataLIF

清除 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));
            }
        }
    }

2.1.5 clearAppProfilesLIF

清除 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));
        }
    }

2.1.6 removeInstalledPackageLI

移除被扫描到的新的 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);
            }
        }
    }

2.1.7 enableSystemPackageLPw

恢复系统应用

    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);
        }
    }

2.1.7.1 Settings.enableSystemPackageLPw

最终会调用 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 的逻辑这里就不在分析了

2.2 replaceNonSystemPackageLIF

这里我们分析下覆盖安装三方应用的流程,对于扫描标志位 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;
                            }
                        }
                    }
                }
            }
        }
    }

2.2.1 deletePackageLIF

删除 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;
    }
2.2.1.1 clearPackageStateForUserLIF

清除指定 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) {
        }
    }
}
2.2.1.2 markPackageUninstalledForUserLPw
    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);
    }
2.2.1.3 deleteSystemPackageLIF

在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;
    }
2.2.1.4 deleteInstalledPackageLIF

如果不是系统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);
            }
        }
    }

你可能感兴趣的:(安卓,android,adb,学习,install,过程)