SystemServer首先启动,创建一个ServerThread线程来启动所有Android核心服务,在创建和启动Installer、ActivityManagerService 、PowerManagerService、RecoverySystemService、LightsService、DisplayManagerService系统服务启动之后,PackageManagerService就会接着被创建和启动。
基于Android 28,为了阅读,本文约定方法表示Java的,而函数表示Native层概念,仅供参考
PackageManagerService(PKMS)作为管理APK包的系统服务,负责APK包的安装、卸载、优化和查询,
Android 系统在启动过程中会通过PKMS(PackageManagerService)服务自动去扫描系统中指定的目录寻找APK文件、JAR包和SO库,并逐一解析封装为对应的对象再保存到内存中,系统运行时就迅速找到对应的信息并自动安装。
PKMS在扫描时遇到需要优化的文件还会额外执行转换工作,将APK的dex格式优化为oat格式(Linux 的ELF格式的一种私有形式)。
在PKMS 在准备安装APK时主要做了两大工作:
当所有App都安装完毕之后,Android Framework 还会启动Home Launcher 应用程序在Launcher 启动。
\frameworks\base\core\java\android\content\pm\IPackageManager.aidl
\out\target\common\obj\JAVA_LIBRARIES\framework_intermediates\src\core\java\android\content\pm\IPackageManager.java
作为Android 系统的核心服务,PackageManagerService自然也是采用Binder 服务的架构,当某个进程需要访问某个系统服务时首先得通过ServiceManager 获取其对应的Binder对象,从而调用对应的方法,至于中间的通信细节全部由Binder 通信去完成,PackageManagerService 只是负责包管理的相关工作,解析完成之后再传到Installer服务里。

在应用进程里通过调用Context#getPackageManager() 得到ApplicationPackageManager 对象后,通过Binder 机制与PackageManagerService 服务通信,再由PackageManagerService 调用Installer服务,最终Installer服务通过socket 与installd 守护进程通信。

在前面文章中介绍System进程(SystemServer.java)启动过程中,在AMS、PowerManagerService、DisplayManagerService核心服务启动后,会通过调用PackageManagerService#main方法将PMS 启动
当然启动PMS 只是System进程启动后干的很小一部分工作,还有其他很多系统服务也会被启动,而且很多启动流程都大同小异。
private void startBootstrapServices() {
//启动Installer服务
Installer installer = mSystemServiceManager.startService(Installer.class);
...
// Activity manager runs the show.
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
//创建 PKMS 对象
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
//PKMS是否首次启动
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();
//...
}
public static PackageManagerService main(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
// Self-check for initial settings.
PackageManagerServiceCompilerMapping.checkProperties();
PackageManagerService m = new PackageManagerService(context, installer,
factoryTest, onlyCore);
m.enableSystemUserPackages();
ServiceManager.addService("package", m);
final PackageManagerNative pmn = m.new PackageManagerNative();
ServiceManager.addService("package_native", pmn);
return m;
}
PackageManagerService 在自己构造方法里主要完成两件事:
public PackageManagerService(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
//true 表示PMKS此次只处理系统应用, SystemProperties.get("vold.decrypt")得到值为trigger_restart_min_framework或者1时SystemServer传过来的参数为true
mOnlyCore = onlyCore;
//创建屏幕显示对象
mMetrics = new DisplayMetrics();
//mInstallLock 用来保护所有安装apk的访问权限,此操作通常涉及繁重的磁盘数据读写等操作,并且是单线程操作,故有时候会处理很慢
synchronized (mInstallLock) {
//mpackages 用来解析内存中所有apk的package信息及相关状态
synchronized (mPackages) {
...
//多用户管理机制,这是google想模拟windows多用户管理系统,为未来的设计
sUserManager = new UserManagerService(context, this,
new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
mPermissionManager = PermissionManagerService.create(context,
new DefaultPermissionGrantedCallback() {
@Override
public void onDefaultRuntimePermissionsGranted(int userId) {
synchronized(mPackages) {
mSettings.onDefaultRuntimePermissionsGrantedLPr(userId);
}
}
}, mPackages /*externalLock*/);
mDefaultPermissionPolicy = mPermissionManager.getDefaultPermissionGrantPolicy();
///创建Settings对象
mSettings = new Settings(mPermissionManager.getPermissionSettings(), mPackages);
}
}
//创建 SharedUserSetting 对象并把system, phone, log, nfc, bluetooth, shell,se,networkstack 这8种shareUserId到mSettings,把这些系统应用的uid 保存起来,添加共享用户组的信息
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);
...
//dex优化工具类
mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
"*dexopt*");
//Dex 管理类
mDexManager = new DexManager(mContext, this, mPackageDexOptimizer, installer, mInstallLock,
dexManagerListener);
// ART虚拟机管理服务
mArtManagerService = new ArtManagerService(mContext, this, installer, mInstallLock);
mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
getDefaultDisplayMetrics(context, mMetrics);//用系统属性设置DisplayMetrics
//获取SystemConfig()的对象,在其构造方法中会调用readPermissions()完成权限的读取
SystemConfig systemConfig = SystemConfig.getInstance();
...
synchronized (mInstallLock) {
// writer
synchronized (mPackages) {
//创建消息处理线程处理APK的安装和卸载请求
mHandlerThread = new ServiceThread(TAG,
Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
mHandlerThread.start();
//用于处理安装、卸载应用请求的Handler
mHandler = new PackageHandler(mHandlerThread.getLooper());
mProcessLoggingHandler = new ProcessLoggingHandler();//创建进程运行信息记录Handler
Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);//绑定到SystemServer 的Watchdog服务
...
//com.android.server.pm.Settings mSettings 读取并解析/data/system下的XML文件
mFirstBoot = !mSettingsreadLPw(sUserManager.getUsers(false));
// 清理代码路径不存在的孤立软件包
final int packageSettingCount = mSettings.mPackages.size();
for (int i = packageSettingCount - 1; i >= 0; i--) {
PackageSetting ps = mSettings.mPackages.valueAt(i);
if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
&& mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
mSettings.mPackages.removeAt(i);
mSettings.enableSystemPackageLPw(ps.name);
}
}
if (mFirstBoot) {
//拷贝预编译的DEX文件
requestCopyPreoptedFiles();
}
...
///获取环境变量 在init.rc里配置的
final String bootClassPath = System.getenv("BOOTCLASSPATH");
final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
File frameworkDir = new File(Environment.getRootDirectory(), "framework"); ...
mCacheDir = preparePackageParserCache(mIsUpgrade);
// Set flag to monitor and not change apk file paths when
// scanning install directories.
int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
if (mIsUpgrade || mFirstBoot) {
scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
}
// Collect vendor/product overlay packages. (Do this before scanning any apps.)
// For security and version matching reason, only consider
// overlay packages if they reside in the right directory.
scanDirTracedLI(new File(VENDOR_OVERLAY_DIR),
mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM_DIR,
scanFlags
| SCAN_AS_SYSTEM
| SCAN_AS_VENDOR,
0);
scanDirTracedLI(new File(PRODUCT_OVERLAY_DIR),
mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM_DIR,
scanFlags
| SCAN_AS_SYSTEM
| SCAN_AS_PRODUCT,
0);
mParallelPackageParserCallback.findStaticOverlayPackages();
// Find base frameworks (resource packages without code).
scanDirTracedLI(frameworkDir,
mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM_DIR,
scanFlags
| SCAN_NO_DEX
| SCAN_AS_SYSTEM
| SCAN_AS_PRIVILEGED,
0);
// Collect privileged system packages.
final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
scanDirTracedLI(privilegedAppDir,
mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM_DIR,
scanFlags
| SCAN_AS_SYSTEM
| SCAN_AS_PRIVILEGED,
0);
// Collect ordinary system packages.
final File systemAppDir = new File(Environment.getRootDirectory(), "app");
scanDirTracedLI(systemAppDir,
mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM_DIR,
scanFlags
| SCAN_AS_SYSTEM,
0);
// Collect privileged vendor packages.
File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");
try {
privilegedVendorAppDir = privilegedVendorAppDir.getCanonicalFile();
} catch (IOException e) {
// failed to look up canonical path, continue with original one
}
scanDirTracedLI(privilegedVendorAppDir,
mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM_DIR,
scanFlags
| SCAN_AS_SYSTEM
| SCAN_AS_VENDOR
| SCAN_AS_PRIVILEGED,
0);
// Collect ordinary vendor packages.
File vendorAppDir = new File(Environment.getVendorDirectory(), "app");
try {
vendorAppDir = vendorAppDir.getCanonicalFile();
} catch (IOException e) {
// failed to look up canonical path, continue with original one
}
scanDirTracedLI(vendorAppDir,
mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM_DIR,
scanFlags
| SCAN_AS_SYSTEM
| SCAN_AS_VENDOR,
0);
// Collect privileged odm packages. /odm is another vendor partition
// other than /vendor.
File privilegedOdmAppDir = new File(Environment.getOdmDirectory(),
"priv-app");
try {
privilegedOdmAppDir = privilegedOdmAppDir.getCanonicalFile();
} catch (IOException e) {
// failed to look up canonical path, continue with original one
}
scanDirTracedLI(privilegedOdmAppDir,
mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM_DIR,
scanFlags
| SCAN_AS_SYSTEM
| SCAN_AS_VENDOR
| SCAN_AS_PRIVILEGED,
0);
// Collect ordinary odm packages. /odm is another vendor partition
// other than /vendor.
File odmAppDir = new File(Environment.getOdmDirectory(), "app");
try {
odmAppDir = odmAppDir.getCanonicalFile();
} catch (IOException e) {
// failed to look up canonical path, continue with original one
}
scanDirTracedLI(odmAppDir,
mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM_DIR,
scanFlags
| SCAN_AS_SYSTEM
| SCAN_AS_VENDOR,
0);
// Collect all OEM packages.
final File oemAppDir = new File(Environment.getOemDirectory(), "app");
scanDirTracedLI(oemAppDir,
mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM_DIR,
scanFlags
| SCAN_AS_SYSTEM
| SCAN_AS_OEM,
0);
// Collected privileged product packages.
File privilegedProductAppDir = new File(Environment.getProductDirectory(), "priv-app");
try {
privilegedProductAppDir = privilegedProductAppDir.getCanonicalFile();
} catch (IOException e) {
// failed to look up canonical path, continue with original one
}
scanDirTracedLI(privilegedProductAppDir,
mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM_DIR,
scanFlags
| SCAN_AS_SYSTEM
| SCAN_AS_PRODUCT
| SCAN_AS_PRIVILEGED,
0);
// Collect ordinary product packages.
File productAppDir = new File(Environment.getProductDirectory(), "app");
try {
productAppDir = productAppDir.getCanonicalFile();
} catch (IOException e) {
// failed to look up canonical path, continue with original one
}
scanDirTracedLI(productAppDir,
mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM_DIR,
scanFlags
| SCAN_AS_SYSTEM
| SCAN_AS_PRODUCT,
0);
// 裁剪不在存在的系统应用的包package
final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
final List<String> stubSystemApps = new ArrayList<>();
if (!mOnlyCore) {
final Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
while (psit.hasNext()) {
PackageSetting ps = psit.next();
/**
*如果得到的ps代表的package信息不是系统应用的则不能禁用
*/
if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
continue;
}
final PackageParser.Package scannedPkg = mPackages.get(ps.name);
if (scannedPkg != null) {
if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
removePackageLI(scannedPkg, true);
mExpectingBetter.put(ps.name, ps.codePath);
}
continue;
}
...
}
}
//删除临时文件
deleteTempPackageFiles();
final int cachedSystemApps = PackageParser.sCachedPackageReadCount.get();
//裁剪多余没有关联应用的uid
mSettings.pruneSharedUsersLPw();
if (!mOnlyCore) {
scanDirTracedLI(sAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
scanDirTracedLI(sDrmAppPrivateInstallDir, mDefParseFlags
| PackageParser.PARSE_FORWARD_LOCK,
scanFlags | SCAN_REQUIRE_KNOWN, 0);
// 删除已更新的系统应用程序的禁用包设置,通过 OTA 删除。 如果更新不再存在,完全删除应用程序。 否则,撤销其系统权限。
for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
mSettings.removeDisabledSystemPackageLPw(deletedAppName);
...
}
//确保所有应该在userdata分区上显示的系统应用程序能正常显示,如果从未出现过,需要回滚以恢复
for (int i = 0; i < mExpectingBetter.size(); i++) {
final String packageName = mExpectingBetter.keyAt(i);
if (!mPackages.containsKey(packageName)) {
final File scanFile = mExpectingBetter.valueAt(i);
...
mSettings.enableSystemPackageLPw(packageName);
try {
//扫描指定目录下的apk
scanPackageTracedLI(scanFile, reparseFlags, rescanFlags, 0, null);
}
}
}
// 解压缩并安装任何存根系统应用程序,以确保所有存根都被替换或禁用。
decompressSystemApplications(stubSystemApps, scanFlags);
// Resolve the storage manager.
mStorageManagerPackage = getStorageManagerPackageName();
// 更新以确保所有客户端持有正确的共享库路径
updateAllSharedLibrariesLPw(null);
mPackageUsage.read(mPackages);
mCompilerStats.read();
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
SystemClock.uptimeMillis());
Slog.i(TAG, "Time to scan packages: "
+ ((SystemClock.uptimeMillis()-startTime)/1000f)
+ " seconds");
// 如果自上次启动以来,SDK版本已改变,则需重新授予应用程序权限以捕获出现的任何新权限
final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
mPermissionManager.updateAllPermissions(
StorageManager.UUID_PRIVATE_INTERNAL, sdkUpdated, mPackages.values(),
mPermissionCallback);
ver.sdkVersion = mSdkVersion;
//第一次正常启动或者 M之前版本更新后正常启动的,需要初始化默认的首选应用程序
if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
for (UserInfo user : sUserManager.getUsers(true)) {
mSettings.applyDefaultPreferredAppsLPw(this, user.id);
applyFactoryDefaultBrowserLPw(user.id);
primeDomainVerificationsLPw(user.id);
}
}
...
//如果是在OTA之后首次启动,并且正常启动,那需要清除代码缓存目录,但不清除应用程序配置文件
if (mIsUpgrade && !onlyCore) {
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)) {
clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE| Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
}
}
ver.fingerprint = Build.FINGERPRINT;
}
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
mSettings.writeLPr();
if (!mOnlyCore) {
mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
mRequiredInstallerPackage = getRequiredInstallerLPr();
mRequiredUninstallerPackage = getRequiredUninstallerLPr();
mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
if (mIntentFilterVerifierComponent != null) {
mIntentFilterVerifier = new IntentVerifierProxy(mContext,
mIntentFilterVerifierComponent);
} else {
mIntentFilterVerifier = null;
}
mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
SharedLibraryInfo.VERSION_UNDEFINED);
mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
SharedLibraryInfo.VERSION_UNDEFINED);
} else {
mRequiredVerifierPackage = null;
mRequiredInstallerPackage = null;
mRequiredUninstallerPackage = null;
mIntentFilterVerifierComponent = null;
mIntentFilterVerifier = null;
mServicesSystemSharedLibraryPackageName = null;
mSharedSystemSharedLibraryPackageName = null;
}
mInstallerService = new PackageInstallerService(context, this);
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);
// Read and update the usage of dex files.
// Do this at the end of PM init so that all the packages have their
// data directory reconciled.
// At this point we know the code paths of the packages, so we can validate
// the disk file and build the internal cache.
// The usage file is expected to be small so loading and verifying it
// should take a fairly small time compare to the other activities (e.g. package
// scanning).
final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
for (int userId : currentUserIds) {
userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
}
mDexManager.load(userPackages);
if (mIsUpgrade) {
MetricsLogger.histogram(null, "ota_package_manager_init_time",
(int) (SystemClock.uptimeMillis() - startTime));
}
} // synchronized (mPackages)
} // synchronized (mInstallLock)
// Now after opening every single application zip, make sure they
// are all flushed. Not really needed, but keeps things nice and
// tidy.
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");
Runtime.getRuntime().gc();
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
// 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(mPackages);
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
private void startOtherServices() {
...
//启动 MountService,后续 PackageManager 会需要使用
mSystemServiceManager.startService(MOUNT_SERVICE_CLASS);
//dex 优化工作,dex 是 Android 针对 Java 字节码的一种优化技术,可提高运行效率
mPackageManagerService.performBootDexOpt();
//调用PKMS的回调函数,其他系统服务启动后也会有类似的操作
mPackageManagerService.systemReady();
//...
}
其他系统服务启动后也会有类似的操作。
篇幅问题见下文。