• 前言
    • 背负着过去的痛苦,夹杂着现实的烦恼,对人的心灵而言是无任何益处的

参考博客

  本文中的所有内容大部分来源于网络资料,如有侵权请联系本人修改或删除,请大家多多支持原创!非常感谢!

PackageManagerService

  PackageManagerService(PMS)主要是管理应用的安装,卸载,更新,解析以及权限。同ActivityManagerService,PMS也是由SystemService孵化而来。

PMS启动流程.png

启动与初始化

  • frameworks/base/services/java/com/android/server/SystemServer.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//line 1234
// Start the package manager.
if (!mRuntimeRestart) {
FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
FrameworkStatsLog
.BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__PACKAGE_MANAGER_INIT_START,
SystemClock.elapsedRealtime());
}

t.traceBegin("StartDomainVerificationService");
DomainVerificationService domainVerificationService = new DomainVerificationService(
mSystemContext, SystemConfig.getInstance(), platformCompat);
mSystemServiceManager.startService(domainVerificationService);
t.traceEnd();

t.traceBegin("StartPackageManagerService");
try {
Watchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain");
mPackageManagerService = PackageManagerService.main(
mSystemContext, installer, domainVerificationService,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF);
} finally {
Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain");
}

mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();
t.traceEnd();

  DomainVerificationService 是用来验证域名是否已经被注册过的服务。它是一个后台服务,可以在系统启动时或者应用请求时触发。它的主要功能是检查域名是否已经被其他应用或者系统使用过,以及是否已经被用户注册过。如果域名没有被使用或者注册过,那么 DomainVerificationService 会返回一个成功的结果;如果域名已经被使用或者注册过,那么 DomainVerificationService 会返回一个失败的结果,并且给出相应的错误信息。如果只启动 DomainVerificationService 不启动 PackageManagerService ,那么可能会导致一些功能缺失或者异常。这里重点查看PackageManagerService。

  • frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// Line 1520
/** Starts PackageManagerService. */
public static PackageManagerService main(Context context,
Installer installer, @NonNull DomainVerificationService domainVerificationService,
boolean factoryTest) {
// Self-check for initial settings.
// 初始化配置检查
PackageManagerServiceCompilerMapping.checkProperties();
final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",
Trace.TRACE_TAG_PACKAGE_MANAGER);
t.traceBegin("create package manager");
final PackageManagerTracedLock lock = new PackageManagerTracedLock();
final Object installLock = new Object();

HandlerThread backgroundThread = new ServiceThread("PackageManagerBg",
Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
backgroundThread.start();
Handler backgroundHandler = new Handler(backgroundThread.getLooper(),
BACKGROUND_HANDLER_CALLBACK);

PackageManagerServiceInjector injector = new PackageManagerServiceInjector(
context, lock, installer, installLock, new PackageAbiHelperImpl(),
backgroundHandler,
SYSTEM_PARTITIONS,
(i, pm) -> new ComponentResolver(i.getUserManagerService(), pm.mUserNeedsBadging),
(i, pm) -> PermissionManagerService.create(context,
i.getSystemConfig().getAvailableFeatures()),
// 创建多用户管理对象
(i, pm) -> new UserManagerService(context, pm,
new UserDataPreparer(installer, installLock, context), lock),
// 初始化Settings,调试中可以在shell使用setting get/put命令
(i, pm) -> new Settings(Environment.getDataDirectory(),
RuntimePermissionsPersistence.createInstance(),
i.getPermissionManagerServiceInternal(),
domainVerificationService, backgroundHandler,
lock),
(i, pm) -> AppsFilterImpl.create(i,
i.getLocalService(PackageManagerInternal.class)),
(i, pm) -> (PlatformCompat) ServiceManager.getService("platform_compat"),
(i, pm) -> SystemConfig.getInstance(),
(i, pm) -> new PackageDexOptimizer(i.getInstaller(), i.getInstallLock(),
i.getContext(), "*dexopt*"),
(i, pm) -> new DexManager(i.getContext(), i.getPackageDexOptimizer(),
i.getInstaller(), i.getInstallLock(), i.getDynamicCodeLogger()),
(i, pm) -> new DynamicCodeLogger(i.getInstaller()),
(i, pm) -> new ArtManagerService(i.getContext(), i.getInstaller(),
i.getInstallLock()),
(i, pm) -> ApexManager.getInstance(),
(i, pm) -> new ViewCompiler(i.getInstallLock(), i.getInstaller()),
(i, pm) -> (IncrementalManager)
i.getContext().getSystemService(Context.INCREMENTAL_SERVICE),
(i, pm) -> new DefaultAppProvider(() -> context.getSystemService(RoleManager.class),
() -> LocalServices.getService(UserManagerInternal.class)),
(i, pm) -> new DisplayMetrics(),
(i, pm) -> new PackageParser2(pm.mSeparateProcesses, i.getDisplayMetrics(),
pm.mCacheDir,
pm.mPackageParserCallback) /* scanningCachingPackageParserProducer */,
(i, pm) -> new PackageParser2(pm.mSeparateProcesses, i.getDisplayMetrics(), null,
pm.mPackageParserCallback) /* scanningPackageParserProducer */,
(i, pm) -> new PackageParser2(pm.mSeparateProcesses, i.getDisplayMetrics(), null,
pm.mPackageParserCallback) /* preparingPackageParserProducer */,
// Prepare a supplier of package parser for the staging manager to parse apex file
// during the staging installation.
(i, pm) -> new PackageInstallerService(
i.getContext(), pm, i::getScanningPackageParser),
(i, pm, cn) -> new InstantAppResolverConnection(
i.getContext(), cn, Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE),
(i, pm) -> new ModuleInfoProvider(i.getContext()),
(i, pm) -> LegacyPermissionManagerService.create(i.getContext()),
(i, pm) -> domainVerificationService,
(i, pm) -> {
HandlerThread thread = new ServiceThread(TAG,
Process.THREAD_PRIORITY_DEFAULT, true /*allowIo*/);
thread.start();
return new PackageHandler(thread.getLooper(), pm);
},
new DefaultSystemWrapper(),
LocalServices::getService,
context::getSystemService,
(i, pm) -> {
if (useArtService()) {
return null;
}
try {
return new BackgroundDexOptService(i.getContext(), i.getDexManager(), pm);
} catch (LegacyDexoptDisabledException e) {
throw new RuntimeException(e);
}
},
(i, pm) -> IBackupManager.Stub.asInterface(ServiceManager.getService(
Context.BACKUP_SERVICE)),
(i, pm) -> new SharedLibrariesImpl(pm, i),
(i, pm) -> new CrossProfileIntentFilterHelper(i.getSettings(),
i.getUserManagerService(), i.getLock(), i.getUserManagerInternal(),
context),
(i, pm) -> new UpdateOwnershipHelper());

if (Build.VERSION.SDK_INT <= 0) {
Slog.w(TAG, "**** ro.build.version.sdk not set!");
}
// 创建PMS对象
PackageManagerService m = new PackageManagerService(injector, factoryTest,
PackagePartitions.FINGERPRINT, Build.IS_ENG, Build.IS_USERDEBUG,
Build.VERSION.SDK_INT, Build.VERSION.INCREMENTAL);
t.traceEnd(); // "create package manager"

final CompatChange.ChangeListener selinuxChangeListener = packageName -> {
synchronized (m.mInstallLock) {
final Computer snapshot = m.snapshotComputer();
final PackageStateInternal packageState =
snapshot.getPackageStateInternal(packageName);
if (packageState == null) {
Slog.e(TAG, "Failed to find package setting " + packageName);
return;
}
AndroidPackage pkg = packageState.getPkg();
SharedUserApi sharedUser = snapshot.getSharedUser(
packageState.getSharedUserAppId());
String oldSeInfo = packageState.getSeInfo();

if (pkg == null) {
Slog.e(TAG, "Failed to find package " + packageName);
return;
}
final String newSeInfo = SELinuxMMAC.getSeInfo(packageState, pkg, sharedUser,
m.mInjector.getCompatibility());

if (!newSeInfo.equals(oldSeInfo)) {
Slog.i(TAG, "Updating seInfo for package " + packageName + " from: "
+ oldSeInfo + " to: " + newSeInfo);
m.commitPackageStateMutation(null, packageName,
state -> state.setOverrideSeInfo(newSeInfo));
m.mAppDataHelper.prepareAppDataAfterInstallLIF(pkg);
}
}
};

injector.getCompatibility().registerListener(SELinuxMMAC.SELINUX_LATEST_CHANGES,
selinuxChangeListener);
injector.getCompatibility().registerListener(SELinuxMMAC.SELINUX_R_CHANGES,
selinuxChangeListener);

// 为用户安装系统应用
m.installAllowlistedSystemPackages();
IPackageManagerImpl iPackageManager = m.new IPackageManagerImpl();
// 向ServiceManager注册PMS服务
ServiceManager.addService("package", iPackageManager);
final PackageManagerNative pmn = new PackageManagerNative(m);
ServiceManager.addService("package_native", pmn);
return m;
}

  PMS的构造方法代码较多,可以分为5个阶段。这里直接引用wise丰大佬的分析过程。

1. PMS_START阶段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
public PackageManagerService(Injector injector, boolean onlyCore, boolean factoryTest,
final String buildFingerprint, final boolean isEngBuild,
final boolean isUserDebugBuild, final int sdkVersion, final String incrementalVersion) {
...

// 打印启动日志
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, SystemClock.uptimeMillis());
...

// 创建Settings对象
mSettings = injector.getSettings();
...

// 调用addSharedUserLPw函数添加共享ID
t.traceBegin("addSharedUsers");
mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
mSettings.addSharedUserLPw("android.uid.se", SE_UID,
ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
mSettings.addSharedUserLPw("android.uid.networkstack", NETWORKSTACK_UID,
ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
mSettings.addSharedUserLPw("android.uid.uwb", UWB_UID,
ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
t.traceEnd();
...

// 获取dex优化对象
mPackageDexOptimizer = injector.getPackageDexOptimizer();
// 获取dex管理对象
mDexManager = injector.getDexManager();
...

// 获取系统配置信息
t.traceBegin("get system config");
SystemConfig systemConfig = injector.getSystemConfig();
mAvailableFeatures = systemConfig.getAvailableFeatures();
t.traceEnd();
...

// 在Data分区创建app目录
mAppInstallDir = new File(Environment.getDataDirectory(), "app");

// 在Data分区创建framework目录
File frameworkDir = new File(Environment.getRootDirectory(), "framework");

...
}
  • 获取Settings类,这个类在Android中是在PMS的Main函数下初始化的
  • 向Settings中添加信息
  • 获取系统配置信息,包括全局属性、groupid以及系统权限。将一些类进行绑定,包括:PackageDexOptimizer (dex优化工具类) 、 DexManager(dex管理类)、PackageHandler(建立package相关操作的消息循环)等
  • 创建data下的各种目录

2. PMS_SYSTEM_SCAN_START阶段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
public PackageManagerService(Injector injector, boolean onlyCore, boolean factoryTest,
final String buildFingerprint, final boolean isEngBuild,
final boolean isUserDebugBuild, final int sdkVersion, final String incrementalVersion) {
...

// 打印启动日志
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, startTime);

// 读取环境变量BOOTCLASSPATH,用于之后的类加载和优化
final String bootClassPath = System.getenv("BOOTCLASSPATH");

final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
...

// 在system/下创建framework目录
File frameworkDir = new File(Environment.getRootDirectory(), "framework");
...


// 在扫描APK之前准备APEX包信息
mApexManager.scanApexPackagesTraced(packageParser, executorService);

// 在vendor/product/system_ext分区的收集包名
for (int i = mDirsToScanAsSystem.size() - 1; i >= 0; i--) {
final ScanPartition partition = mDirsToScanAsSystem.get(i);
if (partition.getOverlayFolder() == null) {
continue;
}
scanDirTracedLI(partition.getOverlayFolder(), systemParseFlags,
systemScanFlags | partition.scanFlag, 0,
packageParser, executorService);
}

// 在system/framework目录下收集包名
scanDirTracedLI(frameworkDir, systemParseFlags,
systemScanFlags | SCAN_NO_DEX | SCAN_AS_PRIVILEGED, 0,
packageParser, executorService);
if (!mPackages.containsKey("android")) {
throw new IllegalStateException(
"Failed to load frameworks package; check log for warnings");
}
for (int i = 0, size = mDirsToScanAsSystem.size(); i < size; i++) {
final ScanPartition partition = mDirsToScanAsSystem.get(i);
if (partition.getPrivAppFolder() != null) {
scanDirTracedLI(partition.getPrivAppFolder(), systemParseFlags,
systemScanFlags | SCAN_AS_PRIVILEGED | partition.scanFlag, 0,
packageParser, executorService);
}
scanDirTracedLI(partition.getAppFolder(), systemParseFlags,
systemScanFlags | partition.scanFlag, 0,
packageParser, executorService);
}

// 收集可能不再存在的系统App
final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
final List<String> stubSystemApps = new ArrayList<>();
if (!mOnlyCore) {
// do this first before mucking with mPackages for the "expecting better" case
final Iterator<AndroidPackage> pkgIterator = mPackages.values().iterator();
while (pkgIterator.hasNext()) {
final AndroidPackage pkg = pkgIterator.next();
if (pkg.isStub()) {
stubSystemApps.add(pkg.getPackageName());
}
}

final Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
// 将packages.xml文件中读取的记录和实时扫描得到的记录做比较,看看有哪些变化
// OTA升级往往会带来一些变化
while (psit.hasNext()) {
PackageSetting ps = psit.next();

// 非系统App跳过
if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
continue;
}
final AndroidPackage scannedPkg = mPackages.get(ps.name);
if (scannedPkg != null) {
if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
logCriticalInfo(Log.WARN,
"Expecting better updated system app for " + ps.name
+ "; removing system app. Last known"
+ " codePath=" + ps.codePathString
+ ", versionCode=" + ps.versionCode
+ "; scanned versionCode=" + scannedPkg.getLongVersionCode());
removePackageLI(scannedPkg, true);
mExpectingBetter.put(ps.name, ps.codePath);
}
continue;
}

if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
psit.remove();
logCriticalInfo(Log.WARN, "System package " + ps.name
+ " no longer exists; it's data will be wiped");
mPermissionManager.updatePermissions(ps.name, null);
} else {
final PackageSetting disabledPs =
mSettings.getDisabledSystemPkgLPr(ps.name);
if (disabledPs.codePath == null || !disabledPs.codePath.exists()
|| disabledPs.pkg == null) {
possiblyDeletedUpdatedSystemApps.add(ps.name);
} else {
mExpectingBetter.put(disabledPs.name, disabledPs.codePath);
}
}
}
}
...

}

  • 扫描各个系统分区的的App
  • 解析系统App信息
  • 把解析结果存储起来,存储在PMS的相关属性和mSettings里

3. PMS_DATA_SCAN_START阶段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
if (!mOnlyCore) {
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
SystemClock.uptimeMillis());

// 在/data/app目录扫描用户安装文件
scanDirTracedLI(sAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0,
packageParser, executorService);

}

// 关闭packageParser
packageParser.close();

List<Runnable> unfinishedTasks = executorService.shutdownNow();
if (!unfinishedTasks.isEmpty()) {
throw new IllegalStateException("Not all tasks finished before calling close: "
+ unfinishedTasks);
}

if (!mOnlyCore) {
// 删除OTA升级中移除的系统App,如果OTA对这个App的操作是“删除”,则完全删除App相关的东西,否则剥夺它的“系统App”权限
for (int i = possiblyDeletedUpdatedSystemApps.size() - 1; i >= 0; --i) {
final String packageName = possiblyDeletedUpdatedSystemApps.get(i);
final AndroidPackage pkg = mPackages.get(packageName);
final String msg;

// 从disabled清单删除
mSettings.removeDisabledSystemPackageLPw(packageName);

if (pkg == null) {
// should have found an update, but, we didn't; remove everything
// pkg
msg = "Updated system package " + packageName
+ " no longer exists; removing its data";
// Actual deletion of code and data will be handled by later
// reconciliation step
} else {
// found an update; revoke system privileges
msg = "Updated system package " + packageName
+ " no longer exists; rescanning package on data";

// 从系统中删除该包并重新扫描权限
removePackageLI(pkg, true);
try {
final File codePath = new File(pkg.getCodePath());
scanPackageTracedLI(codePath, 0, scanFlags, 0, null);
} catch (PackageManagerException e) {
Slog.e(TAG, "Failed to parse updated, ex-system package: "
+ e.getMessage());
}
}

final PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps != null && mPackages.get(packageName) == null) {
removePackageDataLIF(ps, null, null, 0, false);

}
logCriticalInfo(Log.WARN, msg);
}

//遍历mExpectingBetter列表
for (int i = 0; i < mExpectingBetter.size(); i++) {
final String packageName = mExpectingBetter.keyAt(i);
if (!mPackages.containsKey(packageName)) {
//得到系统App的升级包路径
final File scanFile = mExpectingBetter.valueAt(i);

logCriticalInfo(Log.WARN, "Expected better " + packageName
+ " but never showed up; reverting to system");

@ParseFlags int reparseFlags = 0;
@ScanFlags int rescanFlags = 0;
for (int i1 = mDirsToScanAsSystem.size() - 1; i1 >= 0; i1--) {
final ScanPartition partition = mDirsToScanAsSystem.get(i1);
if (partition.containsPrivApp(scanFile)) {
reparseFlags = systemParseFlags;
rescanFlags = systemScanFlags | SCAN_AS_PRIVILEGED
| partition.scanFlag;
break;
}
if (partition.containsApp(scanFile)) {
reparseFlags = systemParseFlags;
rescanFlags = systemScanFlags | partition.scanFlag;
break;
}
}
if (rescanFlags == 0) {
Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
continue;
}
// 将packageName对应的包设置数据(PackageSetting)添加到mSettings的mPackages中
mSettings.enableSystemPackageLPw(packageName);

try {
// 扫描系统App的升级包
scanPackageTracedLI(scanFile, reparseFlags, rescanFlags, 0, null);
} catch (PackageManagerException e) {
Slog.e(TAG, "Failed to parse original system package: "
+ e.getMessage());
}
}
}

installSystemStubPackages(stubSystemApps, scanFlags);

final int cachedNonSystemApps = PackageCacher.sCachedPackageReadCount.get()
- cachedSystemApps;

final long dataScanTime = SystemClock.uptimeMillis() - systemScanTime - startTime;
final int dataPackagesCount = mPackages.size() - systemPackagesCount;
Slog.i(TAG, "Finished scanning non-system apps. Time: " + dataScanTime
+ " ms, packageCount: " + dataPackagesCount
+ " , timePerPackage: "
+ (dataPackagesCount == 0 ? 0 : dataScanTime / dataPackagesCount)
+ " , cached: " + cachedNonSystemApps);
if (mIsUpgrade && dataPackagesCount > 0) {
//CHECKSTYLE:OFF IndentationCheck
FrameworkStatsLog.write(
FrameworkStatsLog.BOOT_TIME_EVENT_DURATION_REPORTED,
BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_DATA_APP_AVG_SCAN_TIME,
dataScanTime / dataPackagesCount);
//CHECKSTYLE:OFF IndentationCheck
}
}
mExpectingBetter.clear();

mStorageManagerPackage = getStorageManagerPackageName();
...

4. PMS_SCAN_END阶段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// 打印相关日志
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
SystemClock.uptimeMillis());
Slog.i(TAG, "Time to scan packages: "
+ ((SystemClock.uptimeMillis()-startTime)/1000f)
+ " seconds");

// If the platform SDK has changed since the last time we booted,
// we need to re-grant app permission to catch any new ones that
// appear. This is really a hack, and means that apps can in some
// cases get permissions that the user didn't initially explicitly
// allow... it would be nice to have some better way to handle
// this situation.
// 如果SDK版本发生了变化(升级系统),重新对App进行授权
final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
if (sdkUpdated) {
Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
+ mSdkVersion + "; regranting permissions for internal storage");
}
mPermissionManager.updateAllPermissions(
StorageManager.UUID_PRIVATE_INTERNAL, sdkUpdated);
ver.sdkVersion = mSdkVersion;

// If this is the first boot or an update from pre-M, and it is a normal
// boot, then we need to initialize the default preferred apps across
// all defined users.
// 如果是首次启动或者从6.0以前的系统升级,初始化用户首选App
if (!mOnlyCore && (mPromoteSystemApps || mFirstBoot)) {
for (UserInfo user : mInjector.getUserManagerInternal().getUsers(true)) {
mSettings.applyDefaultPreferredAppsLPw(user.id);
primeDomainVerificationsLPw(user.id);
}
}

// Prepare storage for system user really early during boot,
// since core system apps like SettingsProvider and SystemUI
// can't wait for user to start
// 为系统用户准备存储空间,因为SettingsProvider和SystemUI等核心系统App不可能等用户去启动
final int storageFlags;
if (StorageManager.isFileEncryptedNativeOrEmulated()) {
storageFlags = StorageManager.FLAG_STORAGE_DE;
} else {
storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
}
List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
true /* onlyCoreApps */);
mPrepareAppDataFuture = SystemServerInitThreadPool.submit(() -> {
TimingsTraceLog traceLog = new TimingsTraceLog("SystemServerTimingAsync",
Trace.TRACE_TAG_PACKAGE_MANAGER);
traceLog.traceBegin("AppDataFixup");
try {
mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
} catch (InstallerException e) {
Slog.w(TAG, "Trouble fixing GIDs", e);
}
traceLog.traceEnd();

traceLog.traceBegin("AppDataPrepare");
if (deferPackages == null || deferPackages.isEmpty()) {
return;
}
int count = 0;
for (String pkgName : deferPackages) {
AndroidPackage pkg = null;
synchronized (mLock) {
PackageSetting ps = mSettings.getPackageLPr(pkgName);
if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
pkg = ps.pkg;
}
}
if (pkg != null) {
synchronized (mInstallLock) {
prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
true /* maybeMigrateAppData */);
}
count++;
}
}
traceLog.traceEnd();
Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
}, "prepareAppData");

// 如果是升级后第一次正常启动,需要清除代码缓存,但不是会清除应用的配置文件
if (mIsUpgrade && !mOnlyCore) {
Slog.i(TAG, "Build fingerprint changed; clearing code caches");
for (int i = 0; i < mSettings.mPackages.size(); i++) {
final PackageSetting ps = mSettings.mPackages.valueAt(i);
if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
// No apps are running this early, so no need to freeze
clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL
| Installer.FLAG_CLEAR_CODE_CACHE_ONLY
| Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES);
}
}
ver.fingerprint = Build.FINGERPRINT;
}

// Grandfather existing (installed before Q) non-system apps to hide
// their icons in launcher.
if (!mOnlyCore && mIsPreQUpgrade) {
Slog.i(TAG, "Whitelisting all existing apps to hide their icons");
int size = mSettings.mPackages.size();
for (int i = 0; i < size; i++) {
final PackageSetting ps = mSettings.mPackages.valueAt(i);
if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
continue;
}
ps.disableComponentLPw(PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME,
UserHandle.USER_SYSTEM);
}
}

// clear only after permissions and other defaults have been updated
mPromoteSystemApps = false;

// All the changes are done during package scanning.
ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;

// can downgrade to reader
t.traceBegin("write settings");
// 把更新后的mSettings中更新后的相关信息写入packages.xml等对应文件中
mSettings.writeLPr();
t.traceEnd();


  • 如果SDK版本发生了变化(升级系统),重新对App进行授权
  • 为系统核心服务准备存储空间
  • 如果是升级后第一次正常启动,需要清除代码缓存,但不是会清除应用的配置文件
  • 把更新后的信息写回对应的xml文件中

5. PMS_READY阶段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
public PackageManagerService(Injector injector, boolean onlyCore, boolean factoryTest) {
...
synchronized (mInstallLock) {
// writer
synchronized (mLock) {
...

EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
SystemClock.uptimeMillis());

if (!mOnlyCore) {
mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
mRequiredInstallerPackage = getRequiredInstallerLPr();
mRequiredUninstallerPackage = getRequiredUninstallerLPr();
mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
if (mIntentFilterVerifierComponent != null) {
mIntentFilterVerifier = new IntentVerifierProxy(mContext,
mIntentFilterVerifierComponent);
} else {
mIntentFilterVerifier = null;
}
mServicesExtensionPackageName = getRequiredServicesExtensionPackageLPr();
mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
SharedLibraryInfo.VERSION_UNDEFINED);
} else {
mRequiredVerifierPackage = null;
mRequiredInstallerPackage = null;
mRequiredUninstallerPackage = null;
mIntentFilterVerifierComponent = null;
mIntentFilterVerifier = null;
mServicesExtensionPackageName = null;
mSharedSystemSharedLibraryPackageName = null;
}

// PermissionController hosts default permission granting and role management, so it's a
// critical part of the core system.
mRequiredPermissionControllerPackage = getRequiredPermissionControllerLPr();

mSettings.setPermissionControllerVersion(
getPackageInfo(mRequiredPermissionControllerPackage, 0,
UserHandle.USER_SYSTEM).getLongVersionCode());

// Initialize InstantAppRegistry's Instant App list for all users.
final int[] userIds = UserManagerService.getInstance().getUserIds();
for (AndroidPackage pkg : mPackages.values()) {
if (pkg.isSystem()) {
continue;
}
for (int userId : userIds) {
final PackageSetting ps = getPackageSetting(pkg.getPackageName());
if (ps == null || !ps.getInstantApp(userId) || !ps.getInstalled(userId)) {
continue;
}
mInstantAppRegistry.addInstantAppLPw(userId, ps.appId);
}
}

// Prepare a supplier of package parser for the staging manager to parse apex file
// during the staging installation.
final Supplier<PackageParser2> apexParserSupplier = () -> new PackageParser2(
mSeparateProcesses, mOnlyCore, mMetrics, null /* cacheDir */,
mPackageParserCallback);
// 初始化PackageInstallerService
mInstallerService = new PackageInstallerService(mContext, this, apexParserSupplier);
final Pair<ComponentName, String> instantAppResolverComponent =
getInstantAppResolverLPr();
if (instantAppResolverComponent != null) {
if (DEBUG_INSTANT) {
Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
}
mInstantAppResolverConnection = new InstantAppResolverConnection(
mContext, instantAppResolverComponent.first,
instantAppResolverComponent.second);
mInstantAppResolverSettingsComponent =
getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
} else {
mInstantAppResolverConnection = null;
mInstantAppResolverSettingsComponent = null;
}
updateInstantAppInstallerLocked(null);

// 读取并更新dex文件的使用情况
final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
for (int userId : userIds) {
userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
}
mDexManager.load(userPackages);
if (mIsUpgrade) {
FrameworkStatsLog.write(
FrameworkStatsLog.BOOT_TIME_EVENT_DURATION_REPORTED,
BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_INIT_TIME,
SystemClock.uptimeMillis() - startTime);
}
} // synchronized (mLock)
} // synchronized (mInstallLock)
// CHECKSTYLE:ON IndentationCheck

mModuleInfoProvider = new ModuleInfoProvider(mContext, this);

// Uncork cache invalidations and allow clients to cache package information.
PackageManager.uncorkPackageInfoCache();

// Now after opening every single application zip, make sure they
// are all flushed. Not really needed, but keeps things nice and
// tidy.
t.traceBegin("GC");
Runtime.getRuntime().gc();
t.traceEnd();

// The initial scanning above does many calls into installd while
// holding the mPackages lock, but we're mostly interested in yelling
// once we have a booted system.
mInstaller.setWarnIfHeld(mLock);

PackageParser.readConfigUseRoundIcon(mContext.getResources());

mServiceStartWithDelay = SystemClock.uptimeMillis() + (60 * 1000L);
}


安装应用

apk 文件构成

目录 or 文件描述
assert存放的原生资源文件,通过AssetManager类访问
libnative库文件
META-INF存放签名信息,用来保证APK包的完整性和系统的安全。系统安装APK时,应用管理器会按照对应算法对包里文件做校验,如果校验结果与META-INF中内容不一致,则不会安装这个APK。
res种资源文件系统会在R.java里面自动生成该资源文件的ID,所以访问这种资源文件比较简单,通过R.XXX.ID即可
AndroidManifest.xml每个应用都必须定义和包含,描述应用的名字、版本权限、引用的库文件等信息。apk中的AndroidManifest.xml经过压缩,可以通过AXMLPrinter2工具解开。
classes.dex是JAVA源码编译后生成的JAVA字节码文件。但Android使用的dalvik虚拟机与标准的JAVA虚拟机不兼容,dex文件与class文件相比,不论是文件结构还是opcode都不一样。
resources.arsc编译后的二进制资源文件。

安装方式

  • adb install

  当执行adb install时,会调用packages/modules/adb/client/commandline.cpp中的adb_commandline函数,这个过程会把apk文件copy到data/local/tmp/目录下,然后向shell服务发送pm命令安装apk,最后调用Pm.runInstall()方法来安装apk

  • frameworks/base/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78

// Line 1522
private int runInstall() throws RemoteException {
return doRunInstall(makeInstallParams(UNSUPPORTED_INSTALL_CMD_OPTS));
}

private int doRunInstall(final InstallParams params) throws RemoteException {
final PrintWriter pw = getOutPrintWriter();

final boolean isStreaming = params.sessionParams.dataLoaderParams != null;
final boolean isApex =
(params.sessionParams.installFlags & PackageManager.INSTALL_APEX) != 0;

ArrayList<String> args = getRemainingArgs();

final boolean fromStdIn = args.isEmpty() || STDIN_PATH.equals(args.get(0));
final boolean hasSplits = args.size() > 1;

if (fromStdIn && params.sessionParams.sizeBytes == -1) {
pw.println("Error: must either specify a package size or an APK file");
return 1;
}

if (isApex && hasSplits) {
pw.println("Error: can't specify SPLIT(s) for APEX");
return 1;
}

if (!isStreaming) {
if (fromStdIn && hasSplits) {
pw.println("Error: can't specify SPLIT(s) along with STDIN");
return 1;
}

if (args.isEmpty()) {
args.add(STDIN_PATH);
} else {
setParamsSize(params, args);
}
}

final int sessionId = doCreateSession(params.sessionParams,
params.installerPackageName, params.userId);
boolean abandonSession = true;
try {
if (isStreaming) {
if (doAddFiles(sessionId, args, params.sessionParams.sizeBytes, isApex)
!= PackageInstaller.STATUS_SUCCESS) {
return 1;
}
} else {
if (doWriteSplits(sessionId, args, params.sessionParams.sizeBytes, isApex)
!= PackageInstaller.STATUS_SUCCESS) {
return 1;
}
}
if (doCommitSession(sessionId, false /*logSuccess*/)
!= PackageInstaller.STATUS_SUCCESS) {
return 1;
}
abandonSession = false;

if (params.sessionParams.isStaged && params.stagedReadyTimeoutMs > 0) {
return doWaitForStagedSessionReady(sessionId, params.stagedReadyTimeoutMs, pw);
}

pw.println("Success");
return 0;
} finally {
if (abandonSession) {
try {
doAbandonSession(sessionId, false /*logSuccess*/);
} catch (Exception ignore) {
}
}
}
}

  这里关键事件是doCreateSession、doWriteSplits、doCommitSession读写提交session

  • doCreateSession

    • 调用的是PackageInstallerService的createSession,这个过程主要是为APK安装做好准备工作,例如权限检查、目的临时文件的创建等, 最终创建出PackageInstallerSession对象。 PackageInstallerSession可以看做是”安装APK”这个请求的封装,其中包含了处理这个请求需要的一些信息。 实际上PackageInstallerSession不仅是封装请求的对象,其自身还是个服务端
  • doWriteSplits

    • 通过PackageInstallerSession将/data/local/tmp的apk拷贝到终端目录内
  • doCommitSession

    • doWriteSplits结束后,如果没有出现任何错误,那么APK源文件已经copy到目的地址了,doCommitSession最终会调用到PMS.installStage来安装apk
  • frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    // 进入安装阶段
    void installStage(ActiveInstallSession activeInstallSession) {
    if (DEBUG_INSTANT) {
    if ((activeInstallSession.getSessionParams().installFlags
    & PackageManager.INSTALL_INSTANT_APP) != 0) {
    Slog.d(TAG, "Ephemeral install of " + activeInstallSession.getPackageName());
    }
    }
    final Message msg = mHandler.obtainMessage(INIT_COPY);
    final InstallParams params = new InstallParams(activeInstallSession);
    params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
    msg.obj = params;

    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
    System.identityHashCode(msg.obj));
    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
    System.identityHashCode(msg.obj));

    mHandler.sendMessage(msg);
    }

安装过程细分

首先检查安装包的完整性并解析安装包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//[PackageManagerService.java] preparePackageLI()
// 完整性校验
if (instantApp && onExternal) {
Slog.i(TAG, "Incompatible ephemeral install; external=" + onExternal);
throw new PrepareFailure(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
}
// 检索包设置,并解析应用
@ParseFlags final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
| PackageParser.PARSE_ENFORCE_CODE
| (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
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);
}

检查SDK版本和沙箱版本,同时检查是否有静态共享库,如有则需要放在内部存储中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//[PackageManagerService.java] preparePackageLI()
//检查SDK版本和沙箱版本
if (instantApp) {
if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
Slog.w(TAG,
"Instant app package " + pkg.packageName + " does not target at least O");
throw new PrepareFailure(INSTALL_FAILED_INSTANT_APP_INVALID,
"Instant app package must target at least O");
}
if (pkg.mSharedUserId != null) {
Slog.w(TAG, "Instant app package " + pkg.packageName
+ " may not declare sharedUserId.");
throw new PrepareFailure(INSTALL_FAILED_INSTANT_APP_INVALID,
"Instant app package may not declare a sharedUserId");
}
}
//检查是否有静态共享库
if (pkg.applicationInfo.isStaticSharedLibrary()) {
// Static shared libraries have synthetic package names
renameStaticSharedLibraryPackage(pkg);
// No static shared libs on external storage
if (onExternal) {
Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
throw new PrepareFailure(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
"Packages declaring static-shared libs cannot be updated");
}
}

检查是否有子安装包,如有则子安装包也需要检测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
[PackageManagerService.java]preparePackageLI()

if(pkg.childPackages!=null){
synchronized (mPackages){
final int childCount=pkg.childPackages.size();
for(int i=0;i<childCount; i++){
PackageParser.Package childPkg=pkg.childPackages.get(i);
PackageInstalledInfo childRes=new PackageInstalledInfo();
childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
childRes.pkg=childPkg;
childRes.name=childPkg.packageName;
PackageSetting childPs=mSettings.getPackageLPr(childPkg.packageName);
if(childPs!=null){
childRes.origUsers=childPs.queryInstalledUsers(
sUserManager.getUserIds(),true);
}
if((mPackages.containsKey(childPkg.packageName))){
childRes.removedInfo=new PackageRemovedInfo(this);
childRes.removedInfo.removedPackage=childPkg.packageName;
childRes.removedInfo.installerPackageName=childPs.installerPackageName;
}
if(res.addedChildPackages==null){
res.addedChildPackages=new ArrayMap<>();
}

res.addedChildPackages.put(childPkg.packageName,childRes);
}
}
}

校验安装包签名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[PackageManagerService.java] preparePackageLI()
PackageSetting signatureCheckPs = ps;
if (pkg.applicationInfo.isStaticSharedLibrary()) {
SharedLibraryInfo libraryInfo = getLatestSharedLibraVersionLPr(pkg);
if (libraryInfo != null) {
signatureCheckPs = mSettings.getPackageLPr(libraryInfo.getPackageName());
}
}
final KeySetManagerService ksms = mSettings.mKeySetManagerService;
if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
if (!ksms.checkUpgradeKeySetLocked(signatureCheckPs, pkg)) {
throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
+ pkg.packageName + " upgrade keys do not match the "
+ "previously installed version");
}
}

设置相关的权限,包括生成权限、移植权限等

如果这是一个系统应用,则检查是否在外部存储上或是是否被其他应用替换等

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[PackageManagerService.java]preparePackageLI()
if(systemApp){

if(onExternal){
// Abort update; system app can't be replaced with app on sdcard
throw new PrepareFailure(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
"Cannot install updates to system apps on sdcard");

}else if(instantApp){
// Abort update; system app can't be replaced with an instant app
throw new PrepareFailure(INSTALL_FAILED_INSTANT_APP_INVALID,
"Cannot update a system app with an instant app");
}
}

生成安装包Abi(Application binary interface,应用二进制接口,描述应用程序和操作系统之间或其他应用程序的低级接口)

1
2
3
4
5
6
7
8
9
10
11
12
[PackageManagerService.java] preparePackageLI()
try {
String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
args.abiOverride : pkg.cpuAbiOverride);
final boolean extractNativeLibs = !pkg.isLibrary();
derivePackageAbi(pkg, abiOverride, extractNativeLibs);

} catch (PackageManagerException pme) {
Slog.e(TAG, "Error deriving application ABI", pme);
throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
}

如有必要,优化dex文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[PackageManagerService.java] executePostCommitSteps()
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");
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);
}

冻结APK,并决定是替换安装,还是新安装,组装参数

1
2
3
4
5
6
7
8
9
10
11
[PackageManagerService.java] preparePackageLI()
final PackageFreezer freezer =freezePackageForInstall(pkgName, installFlags, "installPackageLI");
if (replace) {
//替换安装
} else {// new package install
//安装新的APK
//1)已安装具有相同名称的包,但已将其重命名为旧名称
//2)不要允许在同一名称的现有包上安装。
renamedPackage = mSettings.getRenamedPackageLPr(pkgName1);
}

扫描APK,将APK的信息存储在PackageParser.Package类型的newPackage中,一个Package的信息包含了1个base APK以及0个或者多个split APK

  调用顺序: scanPackageTracedLI() => scanPackageLI() => parsePackage()

更新共享库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[PackageManagerService.java] commitPackageSettings()
synchronized (mPackages) {
if (!ArrayUtils.isEmpty(reconciledPkg.allowedSharedLibraryInfos)) {
for (SharedLibraryInfo info : reconciledPkg.allowedSharedLibraryInfos) {
commitSharedLibraryInfoLocked(info);
final Map<String, PackageParser.Package> combinedPackages =reconciledPkg.getCombinedPackages();
try {
// Shared libraries for the package need to be updated.
updateSharedLibrariesLocked(pkg, null, combinedPackages);
} catch (PackageManagerException e) {
Slog.e(TAG, "updateSharedLibrariesLPr failed: ", e);
}
// Update all applications that use this library. Skip when booting
// since this will be done after all packages are scaned.
if ((scanFlags & SCAN_BOOTING) == 0) {
clientLibPkgs = updateAllSharedLibrariesLocked(pkg, combinedPackages);
}
}
}
}

更新该APK对应的Settings信息,Settings用于保存所有包的动态设置

1
2
3
4
5
6
7
8
9
[PackageManagerService.java] commitPackageSettings()
synchronized (mPackages) {
// Add the new setting to mSettings
mSettings.insertPackageSettingLPw(pkgSetting, pkg);
// Add the new setting to mPackages
mPackages.put(pkg.applicationInfo.packageName, pkg);

}

安装APK,并为新的代码路径准备应用程序配置文件,并再次检查是否需要dex优化

  如果是直接安装新包,会为新的代码路径准备应用程序配置文件。 如果是替换安装:其主要过程为更新设置,清除原有的某些APP数据,重新生成相关的app数据目录等步骤,同时要区分系统应用替换和非系统应用替换。而安装新包:则直接更新设置,生成APP数据即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[PackageManagerService.java] executePostCommitSteps()

private void executePostCommitSteps(CommitRequest commitRequest) {
for (ReconciledPackage reconciledPkg : commitRequest.reconciledPackages.values()) {
...
//1)进行安装
prepareAppDataAfterInstallLIF(pkg);
//2)如果需要替换安装,则需要清楚原有的APP数据
if (reconciledPkg.prepareResult.clearCodeCache) {
clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE
| FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
}
//3)为新的代码路径准备应用程序配置文件。这需要在调用dexopt之前完成,以便任何安装时配置文件都可以用于优化。
mArtManagerService.prepareAppProfiles(pkg,resolveUserIds(reconciledPkg.installArgs.user.getIdentifier()),
/* updateReferenceProfileContent= */ true);
final boolean performDexopt =(!instantApp || Global.getInt(mContext.getContentResolver(),
Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0)&& ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0);
if (performDexopt) {
...
//4)执行dex优化
mPackageDexOptimizer.performDexOpt(pkg,null /* instructionSets */,getOrCreateCompilerPackageStats(pkg),
mDexManager.getPackageUseInfoOrDefault(packageName),
dexoptOptions);
}
}
}

APK的安装

  调用顺序如下: prepareAppDataAfterInstallLIF() => prepareAppDataLIF() => prepareAppDataLeafLIF() => Installer.java#createAppData()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78

private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
...
for (UserInfo user : um.getUsers()) {
...
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);
final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
for (int i = 0; i < childCount; i++) {
prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
}
}

private void prepareAppDataLeafLIF(AndroidPackage pkg, int userId, int flags) {
if (DEBUG_APP_DATA) {
Slog.v(TAG, "prepareAppData for " + pkg.getPackageName() + " u" + userId + " 0x"
+ Integer.toHexString(flags));
}

final PackageSetting ps;
synchronized (mLock) {
ps = mSettings.mPackages.get(pkg.getPackageName());
}
final String volumeUuid = pkg.getVolumeUuid();
final String packageName = pkg.getPackageName();
final int appId = UserHandle.getAppId(pkg.getUid());

String pkgSeInfo = AndroidPackageUtils.getSeInfo(pkg, ps);

Preconditions.checkNotNull(pkgSeInfo);

final String seInfo = pkgSeInfo + (pkg.getSeInfoUser() != null ? pkg.getSeInfoUser() : "");
long ceDataInode = -1;
try {
ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
appId, seInfo, pkg.getTargetSdkVersion());
} catch (InstallerException e) {
if (pkg.isSystem()) {
logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
+ ", but trying to recover: " + e);
destroyAppDataLeafLIF(pkg, userId, flags);
try {
ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
appId, seInfo, pkg.getTargetSdkVersion());
logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
} catch (InstallerException e2) {
logCriticalInfo(Log.DEBUG, "Recovery failed!");
}
} else {
Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
}
}
if (mIsUpgrade || mFirstBoot || (userId != UserHandle.USER_SYSTEM)) {
mArtManagerService.prepareAppProfiles(pkg, userId,
/* updateReferenceProfileContent= */ false);
}

if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
synchronized (mLock) {
if (ps != null) {
ps.setCeDataInode(ceDataInode, userId);
}
}
}
prepareAppDataContentsLeafLIF(pkg, ps, userId, flags);
}

安装完成后,更新设置,更新安装锁等

总结

  PMS是一个及其复杂的服务,其系统源码涵盖广泛。阅读源码可以更好的帮助你理解这个服务,比如说实现静默安装,从上面的源码中得知,可以使用pm install调用command指令去安装,但是限制和条件是有很多的,需要系统签名,系统组等等。更好的实现方式是仿照pm 的安装流程,构建session。