installPackagesLI
- private void installPackagesTracedLI(List
requests) { - try {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackages");
- installPackagesLI(requests);
- } finally {
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- }
- }
-
- private void installPackagesLI(List
requests) { - ....
- try {
- for (InstallRequest request : requests) {
- ....
- final PrepareResult prepareResult;
- try {
- //1.成功准备好的安装软件包所需的数据集。这包括将用于扫描和协调包的数据。
- prepareResult = preparePackageLI(request.args, request.installResult);
- }
- ....
- try {
- //2.根据prepare中收集的上下文查询解析后的包
- final List
scanResults = scanPackageTracedLI( - prepareResult.packageToScan, prepareResult.parseFlags,
- prepareResult.scanFlags, System.currentTimeMillis(),
- request.args.user);
- ....
- } catch (PackageManagerException e) {
- request.installResult.setError("Scanning Failed.", e);
- return;
- }
- }
- //3.协调,检查安装包状态确保安装成功
- ReconcileRequest reconcileRequest = new ReconcileRequest(preparedScans, installArgs,
- installResults,
- prepareResults,
- mSharedLibraries,
- Collections.unmodifiableMap(mPackages), versionInfos,
- lastStaticSharedLibSettings);
- CommitRequest commitRequest = null;
- synchronized (mPackages) {
- Map
reconciledPackages; - try {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "reconcilePackages");
- reconciledPackages = reconcilePackagesLocked(
- reconcileRequest, mSettings.mKeySetManagerService);
- }
- ....
- }
- //4.提交
- executePostCommitSteps(commitRequest);
- }
- ....
- }
- private PrepareResult preparePackageLI(InstallArgs args, PackageInstalledInfo res)
- throws PrepareFailure {
- .....
- //解析包AndroidManifest.xml文件,签名信息等。
- PackageParser pp = new PackageParser();
- pp.setSeparateProcesses(mSeparateProcesses);
- pp.setDisplayMetrics(mMetrics);
- pp.setCallback(mPackageParserCallback);
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
- final PackageParser.Package pkg;
- try {
- pkg = pp.parsePackage(tmpPackageFile, parseFlags);
- DexMetadataHelper.validatePackageDexMetadata(pkg);
- } catch (PackageParserException e) {
- throw new PrepareFailure("Failed parse during installPackageLI", e);
- } finally {
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- }
- .....
- //冻结安装包
- final PackageFreezer freezer =
- freezePackageForInstall(pkgName, installFlags, "installPackageLI");
- boolean shouldCloseFreezerBeforeReturn = true;
- try {
- if (replace) {
- //更新包配置
- ...
- //如果是更新包还会判断是不是系统APP
- sysPkg = (isSystemApp(oldPackage));
- if (sysPkg) {
- ...
- }
- } else {
- //新包安装配置
- ...
- }
- ....
- //返回安装包的数据集
- return new PrepareResult(args.installReason, targetVolumeUuid, installerPackageName,
- args.user, replace, targetScanFlags, targetParseFlags, existingPackage, pkg,
- replace /* clearCodeCache */, sysPkg, renamedPackage, freezer,
- ps, disabledPs, childPackages);
- }
preparePackageLI最主要的是
pkg = pp.parsePackage(tmpPackageFile, parseFlags);
\frameworks\base\core\java\android\content\pm\PackageParser.java
- public Package parsePackage(File packageFile, int flags) throws PackageParserException {
- return parsePackage(packageFile, flags, false /* useCaches */);
- }
-
- public Package parsePackage(File packageFile, int flags, boolean useCaches)
- throws PackageParserException {
- ....
- if (packageFile.isDirectory()) {
- parsed = parseClusterPackage(packageFile, flags);
- } else {
- //只有一个包走这里
- parsed = parseMonolithicPackage(packageFile, flags);
- }
- ....
- return parsed;
- }
-
- public Package parseMonolithicPackage(File apkFile, int flags) throws PackageParserException {
- ....
- try {
- final Package pkg = parseBaseApk(apkFile, assetLoader.getBaseAssetManager(), flags);
- pkg.setCodePath(apkFile.getCanonicalPath());
- pkg.setUse32bitAbi(lite.use32bitAbi);
- return pkg;
- }
- ....
- }
-
- private Package parseBaseApk(File apkFile, AssetManager assets, int flags)
- throws PackageParserException {
- try {
- ....
- parser = assets.openXmlResourceParser(cookie, ANDROID_MANIFEST_FILENAME);
- final Resources res = new Resources(assets, mMetrics, null);
- final String[] outError = new String[1];
- final Package pkg = parseBaseApk(apkPath, res, parser, flags, outError);
- if (pkg == null) {
- throw new PackageParserException(mParseError,
- apkPath + " (at " + parser.getPositionDescription() + "): " + outError[0]);
- }
- pkg.setVolumeUuid(volumeUuid);
- pkg.setApplicationVolumeUuid(volumeUuid);
- pkg.setBaseCodePath(apkPath);
- pkg.setSigningDetails(SigningDetails.UNKNOWN);
- return pkg;
- }
- ....
- }
parseBaseApk是具体的解析方法,这里的ANDROID_MANIFEST_FILENAME就是manifest文件了
public static final String ANDROID_MANIFEST_FILENAME = "AndroidManifest.xml";
这里也去解析了资源文件等,最后都赋给了pkg这个Package对象,和Android四大组件相关的信息分别由activites、receivers、providers、services的list保存。
根据prepare中收集的上下文查询已解析的包。
扫描阶段会填充PackageSetting对象,PackageSetting生成之后会被记录到文件中,以后每次系统启动都会重新加载。
验证安装包状态,以确保安装成功。协调新旧包,删除旧的package。
- private void commitPackagesLocked(final CommitRequest request) {
-
- for (ReconciledPackage reconciledPkg : request.reconciledPackages.values()) {
- if (reconciledPkg.prepareResult.replace) {
- PackageParser.Package oldPackage = mPackages.get(packageName);
- // 1.设置安装和更新时间
- PackageSetting deletedPkgSetting = (PackageSetting) oldPackage.mExtras;
- setInstallAndUpdateTime(pkg, deletedPkgSetting.firstInstallTime,
- System.currentTimeMillis());
-
- //系统应用
- if (reconciledPkg.prepareResult.system) {
- // 2.系统应用-移除现有包,后面还会移除子包(已省略)
- removePackageLI(oldPackage, true);
- .....
- }
- } else {
- try {
- //3.非系统应用-删除包
- executeDeletePackageLIF(reconciledPkg.deletePackageAction, packageName,
- true, request.mAllUsers, true, pkg);
- }
- ....
- }
- }
- //4.提交包扫描并修改系统状态
- commitReconciledScanResultLocked(reconciledPkg);
- updateSettingsLI(pkg, reconciledPkg.installArgs.installerPackageName, request.mAllUsers,
- res, reconciledPkg.installArgs.user, reconciledPkg.installArgs.installReason);
-
- final PackageSetting ps = mSettings.mPackages.get(packageName);
- if (ps != null) {
- res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
- ps.setUpdateAvailable(false /*updateAvailable*/);
- }
- ....
- }
- }
提交阶段第4步比较关键。前面3阶段填充了Package对象和PackageSetting对象数据,现在需要将这些数据提交。
4.4 commitReconciledScanResultLocked(reconciledPkg);
- private void commitReconciledScanResultLocked(@NonNull ReconciledPackage reconciledPkg) {
- ....
- commitPackageSettings(pkg, oldPkg, pkgSetting, scanFlags,
- (parseFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/, reconciledPkg);
- ....
- }
-
- //将扫描包添加到系统中。当这个方法完成时,包将会可用于查询,解决等…
- private void commitPackageSettings(PackageParser.Package pkg,
- @Nullable PackageParser.Package oldPkg, PackageSetting pkgSetting,
- final @ScanFlags int scanFlags, boolean chatty, ReconciledPackage reconciledPkg) {
- ....
- synchronized (mPackages) {
- //添加新的设置到mSettings
- mSettings.insertPackageSettingLPw(pkgSetting, pkg);
- //将新设置添加到mPackages中
- mPackages.put(pkg.applicationInfo.packageName, pkg);
- //将包的键集添加到全局KeySetManagerService
- KeySetManagerService ksms = mSettings.mKeySetManagerService;
- ksms.addScannedPackageLPw(pkg);
- mComponentResolver.addAllComponents(pkg, chatty);
- .....
- }
- }
在此之前,四大组件信息等安装包信息都属于Package的私有财产,现在需要把它们登记注册到PKMS内部的财产管理对象中。这样,PKMS就可对外提供统一的组件信息,而不必拘泥于具体的Package。
- private void executePostCommitSteps(CommitRequest commitRequest) {
- for (ReconciledPackage reconciledPkg : commitRequest.reconciledPackages.values()) {
- .....
- //1.安装并准备/data/data下的文件夹
- prepareAppDataAfterInstallLIF(pkg);
- ....
- //2.dex2oat操作,用来将apk中的dex文件转换为oat文件
- final boolean performDexopt =
- (!instantApp || Global.getInt(mContext.getContentResolver(),
- Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0)
- && ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0);
- if (performDexopt) {
- // Compile the layout resources.
- if (SystemProperties.getBoolean(PRECOMPILE_LAYOUTS, false)) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "compileLayouts");
- mViewCompiler.compileLayouts(pkg);
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- }
-
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
- // Do not run PackageDexOptimizer through the local performDexOpt
- // method because `pkg` may not be in `mPackages` yet.
- //
- // Also, don't fail application installs if the dexopt step fails.
- DexoptOptions dexoptOptions = new DexoptOptions(packageName,
- REASON_INSTALL,
- DexoptOptions.DEXOPT_BOOT_COMPLETE
- | DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE);
- mPackageDexOptimizer.performDexOpt(pkg,
- null /* instructionSets */,
- getOrCreateCompilerPackageStats(pkg),
- mDexManager.getPackageUseInfoOrDefault(packageName),
- dexoptOptions);
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- }
- ...
- }
- }
prepareAppDataAfterInstallLIF(pkg);
- private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
- ....
- final UserManagerService um = sUserManager;
- UserManagerInternal umInternal = getUserManagerInternal();
- for (UserInfo user : um.getUsers(false /* excludeDying */)) {
- final int flags;
- if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
- flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
- } else if (umInternal.isUserRunning(user.id)) {
- flags = StorageManager.FLAG_STORAGE_DE;
- } else {
- continue;
- }
-
- if (ps.getInstalled(user.id)) {
- // TODO: when user data is locked, mark that we're still dirty
- prepareAppDataLIF(pkg, user.id, flags);
- }
- }
- }
-
- private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
- if (pkg == null) {
- Slog.wtf(TAG, "Package was null!", new Throwable());
- return;
- }
- prepareAppDataLeafLIF(pkg, userId, flags);
- ....
- }
-
- private void prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags,
- boolean maybeMigrateAppData) {
- prepareAppDataLIF(pkg, userId, flags);
-
- if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
- // We may have just shuffled around app data directories, so
- // prepare them one more time
- prepareAppDataLIF(pkg, userId, flags);
- }
- }
-
- private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
- ...
- try {
- ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
- appId, seInfo, app.targetSdkVersion);
- }
- ...
- }
跟到最后发现是交给mInstaller去做的,这里的mInstaller是个Binder代理对象,具体实现在\frameworks\native\cmds\installd\InstalldNativeService.cpp
- std::string create_data_user_ce_path(const char* volume_uuid, userid_t userid) {
- std::string data(create_data_path(volume_uuid));
- if (volume_uuid == nullptr && userid == 0) {
- std::string legacy = StringPrintf("%s/data", data.c_str());
- struct stat sb;
- if (lstat(legacy.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode)) {
- /* /data/data is dir, return /data/data for legacy system */
- return legacy;
- }
- }
- return StringPrintf("%s/user/%u", data.c_str(), userid);
- }
这里返回data/data
第5步executePostCommitSteps就是去建立用户数据文件夹,data/data;使用 dex2oat 把App编译成 oat 文件,并保存在 dalvik-cache 目录里;发送ACTION_PACKAGE_ADDED、ACTION_PACKAGE_REPLACED广播等等操作。