概述
PackageManagerService,是Android系统中核心服务之一,管理着所有跟package相关的工作,常见的比如安装、卸载应用。 PKMS服务也是通过binder进行通信,IPackageManager.aidl由工具转换后自动生成binder的服务端IPackageManager.Stub和客户端IPackageManager.Stub.Proxy,具体关系如下:
Binder服务端:PackageManagerService继承于IPackageManager.Stub; Binder客户端:ApplicationPackageManager(简称APM)的成员变量mPM继承于IPackageManager.Stub.Proxy; 本身APM是继承于PackageManager对象。
Android系统启动过程中,一路启动到SystemServer后,便可以启动framework的各大服务,本篇博客将介绍PKMS的启动过程(基于安卓7.0源码)。
PackageManagerService的启动
SystemServer启动过程中涉及到的PKMS代码如下:
private void startBootstrapServices() {
//启动installer服务
Installer installer = mSystemServiceManager.startService(Installer.class);
...
//处于加密状态则仅仅解析核心应用
String cryptState = SystemProperties.get(
"vold.decrypt");
if (ENCRYPTING_STATE.equals(cryptState)) {
mOnlyCore = true; // ENCRYPTING_STATE =
"trigger_restart_min_framework"
}
else if (ENCRYPTED_STATE.equals(cryptState)) {
mOnlyCore = true; // ENCRYPTED_STATE =
"1"
}
//创建PKMS对象
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
//PKMS是否首次启动
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();
...
}
PackageManagerService与其他所有的服务一样,也是由SystemServer启动,它也是java层服务之一,PKMS.main()过程主要是创建PKMS服务,并注册到ServiceManager。
整个system_server进程启动过程,涉及PKMS服务的主要几个动作如下,接下来分别讲解每个过程 PKMS.main() PKMS.performBootDexOpt PKMS.systemReady
PKMS.main()
public static PackageManagerService
main(Context context, Installer installer,
boolean factoryTest,
boolean onlyCore) {
PackageManagerServiceCompilerMapping.checkProperties();
PackageManagerService m =
new PackageManagerService(context, installer,
factoryTest, onlyCore);
m.enableSystemUserPackages();
CarrierAppUtils.disableCarrierAppsUntilPrivileged(context.getOpPackageName(), m,
UserHandle.USER_SYSTEM);
ServiceManager.addService(
"package", m);
return m;
}
该方法的主要功能创建PKMS对象,并将其注册到ServiceManager。 关于PKMS对象的构造方法很长,分为以下几个阶段,每个阶段会输出相应的EventLog: 除了阶段1的开头部分代码,后续代码都是同时持有同步锁mPackages和mInstallLock的过程中执行的。
阶段1:BOOT_PROGRESS_PMS_START 阶段2:BOOT_PROGRESS_PMS_SYSTEM_SCAN_START 阶段3:BOOT_PROGRESS_PMS_DATA_SCAN_START 阶段4:BOOT_PROGRESS_PMS_SCAN_END 阶段5:BOOT_PROGRESS_PMS_READY
阶段1:BOOT_PROGRESS_PMS_START
阶段1 PMS_START有两部分组成,由无需加锁的前部分和同时持有两个锁的后半部分,先来说说前半部分: 前半部分
//向事件日志写入事件,标识PackageManagerService启动
EventLog
.writeEvent(EventLogTags
.BOOT_PROGRESS_PMS_START,
SystemClock
.uptimeMillis())
//SDK版本检查
if (mSdkVersion <=
0) {
Slog
.w(TAG,
"**** ro.build.version.sdk not set!")
}
mContext = context
//开机模式是否为工厂模式
mFactoryTest = factoryTest
//是否仅启动内核
mOnlyCore = onlyCore
//构造DisplayMetrics对象以便获取尺寸数据
mMetrics = new DisplayMetrics()
//构造Settings对象存储运行时的设置信息
mSettings = new Settings(mPackages)
//添加一些用户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)
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)
//判断是否在不同的进程
String separateProcesses = SystemProperties
.get(
"debug.separate_processes")
if (separateProcesses != null && separateProcesses
.length() >
0) {
if (
"*".equals(separateProcesses)) {
mDefParseFlags = PackageParser
.PARSE_IGNORE_PROCESSES
mSeparateProcesses = null
Slog
.w(TAG,
"Running with debug.separate_processes: * (ALL)")
} else {
mDefParseFlags =
0
mSeparateProcesses = separateProcesses
.split(
",")
Slog
.w(TAG,
"Running with debug.separate_processes: "
+ separateProcesses)
}
} else {
mDefParseFlags =
0
mSeparateProcesses = null
}
//installer由SystemServer构造,这里通过该对象与底层进行通信,进行具体安装与卸载的操作
mInstaller = installer
//创建PackageDexOptimizer,该类用于辅助进行dex优化
mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
"*dexopt*")
mMoveCallbacks = new MoveCallbacks(FgThread
.get()
.getLooper())
mOnPermissionChangeListeners = new OnPermissionChangeListeners(
FgThread
.get()
.getLooper())
getDefaultDisplayMetrics(context, mMetrics)
//获取系统配置信息
SystemConfig systemConfig = SystemConfig
.getInstance()
mGlobalGids = systemConfig
.getGlobalGids()
mSystemPermissions = systemConfig
.getSystemPermissions()
mAvailableFeatures = systemConfig
.getAvailableFeatures()
接下来,再来看看后半部分:
synchronized (mInstallLock) {
synchronized (mPackages) {
mHandlerThread
= new ServiceThread(
TAG,
Process
.THREAD_PRIORITY_BACKGROUND,
true );
mHandlerThread
.start();
mHandler
= new PackageHandler(mHandlerThread
.getLooper());
mProcessLoggingHandler
= new ProcessLoggingHandler();
Watchdog
.getInstance()
.addThread(mHandler, WATCHDOG_TIMEOUT);
File dataDir
= Environment
.getDataDirectory();
mAppInstallDir
= new File(dataDir,
"app");
mAppLib32InstallDir
= new File(dataDir,
"app-lib");
mEphemeralInstallDir
= new File(dataDir,
"app-ephemeral");
mAsecInternalPath
= new File(dataDir,
"app-asec")
.getPath();
mDrmAppPrivateInstallDir
= new File(dataDir,
"app-private");
sUserManager
= new UserManagerService(context, this, mPackages);
ArrayMap
<String, SystemConfig
.PermissionEntry
> permConfig
= systemConfig
.getPermissions();
for (int i
=0; i
<permConfig
.size(); i
++) {
SystemConfig
.PermissionEntry perm
= permConfig
.valueAt(i);
BasePermission bp
= mSettings
.mPermissions
.get(perm
.name);
if (bp
== null) {
bp
= new BasePermission(perm
.name,
"android", BasePermission
.TYPE_BUILTIN);
mSettings
.mPermissions
.put(perm
.name, bp);
}
if (perm
.gids
!= null) {
bp
.setGids(perm
.gids, perm
.perUser);
}
}
ArrayMap
<String,
String> libConfig
= systemConfig
.getSharedLibraries();
for (int i
=0; i
<libConfig
.size(); i
++) {
mSharedLibraries
.put(libConfig
.keyAt(i),
new SharedLibraryEntry(libConfig
.valueAt(i),
null));
}
mFoundPolicyFile
= SELinuxMMAC
.readInstallPolicy();
mRestoredSettings
= mSettings
.readLPw(sUserManager
.getUsers(
false));
String customResolverActivity
= Resources
.getSystem()
.getString(
R
.string.config_customResolverActivity);
if (TextUtils
.isEmpty(customResolverActivity)) {
customResolverActivity
= null;
}
else {
mCustomResolverComponentName
= ComponentName
.unflattenFromString(
customResolverActivity);
}
................
}
这个过程涉及的几个重要变量:
创建Settings
在阶段1中创建了Settings对象,我们看看里面做了什么
Settings(File dataDir, Object
lock) {
mLock =
lock;
mRuntimePermissionsPersistence =
new RuntimePermissionPersistence(mLock);
mSystemDir =
new File(dataDir,
"system");
mSystemDir.mkdirs();
FileUtils.setPermissions(mSystemDir.toString(),
FileUtils.S_IRWXU|FileUtils.S_IRWXG
|FileUtils.S_IROTH|FileUtils.S_IXOTH,
-
1, -
1);
mSettingsFilename =
new File(mSystemDir,
"packages.xml");
mBackupSettingsFilename =
new File(mSystemDir,
"packages-backup.xml");
mPackageListFilename =
new File(mSystemDir,
"packages.list");
FileUtils.setPermissions(mPackageListFilename,
0640, SYSTEM_UID, PACKAGE_INFO_GID);
final File kernelDir =
new File(
"/config/sdcardfs");
mKernelMappingFilename = kernelDir.exists() ? kernelDir :
null;
mStoppedPackagesFilename =
new File(mSystemDir,
"packages-stopped.xml");
mBackupStoppedPackagesFilename =
new File(mSystemDir,
"packages-stopped-backup.xml");
}
此处mSystemDir是指目录/data/system,在该目录有以下5个文件:
SystemConfig 阶段1中还调用SystemConfig.getInstance()方法来获取SystemConfig
public static SystemConfig
getInstance() {
synchronized (SystemConfig.class) {
if (sInstance ==
null) {
sInstance =
new SystemConfig();
}
return sInstance;
}
}
SystemConfig() {
// Read configuration from system
readPermissions(Environment
.buildPath(
Environment
.getRootDirectory(),
"etc",
"sysconfig"), ALLOW_ALL)
// Read configuration from the old permissions dir
readPermissions(Environment
.buildPath(
Environment
.getRootDirectory(),
"etc",
"permissions"), ALLOW_ALL)
// Allow ODM to customize system configs around libs, features
and apps
int odmPermissionFlag = ALLOW_LIBS | ALLOW_FEATURES | ALLOW_APP_CONFIGS
readPermissions(Environment
.buildPath(
Environment
.getOdmDirectory(),
"etc",
"sysconfig"), odmPermissionFlag)
readPermissions(Environment
.buildPath(
Environment
.getOdmDirectory(),
"etc",
"permissions"), odmPermissionFlag)
// Only allow OEM to customize features
readPermissions(Environment
.buildPath(
Environment
.getOemDirectory(),
"etc",
"sysconfig"), ALLOW_FEATURES)
readPermissions(Environment
.buildPath(
Environment
.getOemDirectory(),
"etc",
"permissions"), ALLOW_FEATURES)
}
readPermissions()解析指定目录下的所有xml文件,比如将标签所指的动态库保存到 PKMS的成员变量mSharedLibraries。可见,SystemConfig创建过程是对以下这六个目录中的所有xml进行解析: /system/etc/sysconfig /system/etc/permissions /odm/etc/sysconfig /odm/etc/permissions /oem/etc/sysconfig /oem/etc/permissions
SystemConfig.readPermissions
void readPermissions(File libraryDir,
int permissionFlag) {
if (!libraryDir.exists() || !libraryDir.isDirectory()) {
if (permissionFlag == ALLOW_ALL) {
Slog.w(TAG,
"No directory " + libraryDir +
", skipping");
}
return;
}
if (!libraryDir.canRead()) {
Slog.w(TAG,
"Directory " + libraryDir +
" cannot be read");
return;
}
File platformFile =
null;
for (File f : libraryDir.listFiles()) {
if (f.getPath().endsWith(
"etc/permissions/platform.xml")) {
platformFile = f;
continue;
}
if (!f.getPath().endsWith(
".xml")) {
Slog.i(TAG,
"Non-xml file " + f +
" in " + libraryDir +
" directory, ignoring");
continue;
}
if (!f.canRead()) {
Slog.w(TAG,
"Permissions library file " + f +
" cannot be read");
continue;
}
readPermissionsFromXml(f, permissionFlag);
}
if (platformFile !=
null) {
readPermissionsFromXml(platformFile, permissionFlag);
}
}
该方法是解析指定目录下所有的具有可读权限的,且以xml后缀文件。
阶段2:BOOT_PROGRESS_PMS_SYSTEM_SCAN_START
long startTime = SystemClock.uptimeMillis();
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
startTime);
final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING | SCAN_INITIAL;
final String bootClassPath = System.getenv(
"BOOTCLASSPATH");
final String systemServerClassPath = System.getenv(
"SYSTEMSERVERCLASSPATH");
if (bootClassPath ==
null) {
Slog.w(TAG,
"No BOOTCLASSPATH found!");
}
if (systemServerClassPath ==
null) {
Slog.w(TAG,
"No SYSTEMSERVERCLASSPATH found!");
}
final List<String> allInstructionSets = InstructionSets.getAllInstructionSets();
final String[] dexCodeInstructionSets =
getDexCodeInstructionSets(
allInstructionSets.toArray(
new String[allInstructionSets.size()]));
/**
* Ensure all external libraries have had dexopt run on them.
*/
if (mSharedLibraries.size() >
0) {
for (String dexCodeInstructionSet : dexCodeInstructionSets) {
for (SharedLibraryEntry libEntry : mSharedLibraries.values()) {
final String lib = libEntry.path;
if (lib ==
null) {
continue;
}
try {
int dexoptNeeded = DexFile.getDexOptNeeded(
lib, dexCodeInstructionSet,
getCompilerFilterForReason(REASON_SHARED_APK),
false );
if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
mInstaller.dexopt(lib, Process.SYSTEM_UID, dexCodeInstructionSet,
dexoptNeeded, DEXOPT_PUBLIC ,
getCompilerFilterForReason(REASON_SHARED_APK),
StorageManager.UUID_PRIVATE_INTERNAL,
SKIP_SHARED_LIBRARY_CHECK);
}
}
catch (FileNotFoundException e) {
Slog.w(TAG,
"Library not found: " + lib);
}
catch (IOException | InstallerException e) {
Slog.w(TAG,
"Cannot dexopt " + lib +
"; is it an APK or JAR? "
+ e.getMessage());
}
}
}
}
File frameworkDir =
new File(Environment.getRootDirectory(),
"framework");
final VersionInfo ver = mSettings.getInternalVersion();
mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
mPromoteSystemApps =
mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
if (mPromoteSystemApps) {
Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
while (pkgSettingIter.hasNext()) {
PackageSetting ps = pkgSettingIter.next();
if (isSystemApp(ps)) {
mExistingSystemPackages.add(ps.name);
}
}
}
File vendorOverlayDir =
new File(VENDOR_OVERLAY_DIR);
scanDirTracedLI(vendorOverlayDir, mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR
| PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY,
0);
scanDirTracedLI(frameworkDir, mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR
| PackageParser.PARSE_IS_PRIVILEGED,
scanFlags | SCAN_NO_DEX,
0);
final File privilegedAppDir =
new File(Environment.getRootDirectory(),
"priv-app");
scanDirTracedLI(privilegedAppDir, mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR
| PackageParser.PARSE_IS_PRIVILEGED, scanFlags,
0);
final File systemAppDir =
new File(Environment.getRootDirectory(),
"app");
scanDirTracedLI(systemAppDir, mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags,
0);
File vendorAppDir =
new File(
"/vendor/app");
try {
vendorAppDir = vendorAppDir.getCanonicalFile();
}
catch (IOException e) {
}
scanDirTracedLI(vendorAppDir, mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags,
0);
final File oemAppDir =
new File(Environment.getOemDirectory(),
"app");
scanDirTracedLI(oemAppDir, mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags,
0);
final List<String> possiblyDeletedUpdatedSystemApps =
new ArrayList<String>();
if (!mOnlyCore) {
Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
while (psit.hasNext()) {
PackageSetting ps = psit.next();
if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) ==
0) {
continue;
}
final PackageParser.Package 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 +
", installStatus=" + ps.installStatus
+
", versionCode=" + ps.versionCode +
"; scanned versionCode="
+ scannedPkg.mVersionCode);
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");
}
else {
final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
if (disabledPs.codePath ==
null || !disabledPs.codePath.exists()) {
possiblyDeletedUpdatedSystemApps.add(ps.name);
}
}
}
}
ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
for (
int i =
0; i < deletePkgsList.size(); i++) {
final String packageName = deletePkgsList.get(i).name;
logCriticalInfo(Log.WARN,
"Cleaning up incompletely installed app: " + packageName);
synchronized (mPackages) {
mSettings.removePackageLPw(packageName);
}
}
deleteTempPackageFiles();
mSettings.pruneSharedUsersLPw();
环境变量: 那可通过adb shell env来查看系统所有的环境变量及相应值。也可通过命令adb shell echo $SYSTEMSERVERCLASSPATH。 SYSTEMSERVERCLASSPATH:主要包括/system/framework目录下services.jar,ethernet-service.jar,wifi-service.jar这3个文件。 BOOTCLASSPATH:该环境变量内容较多,不同ROM可能有所不同,常见内容包含/system/framework目录下的framework.jar,ext.jar,core-libart.jar,telephony-common.jar,ims-common.jar,core-junit.jar等文件。
scanDirLI(): 扫描指定目录下的apk文件,最终调用PackageParser.parseBaseApk来完成AndroidManifest.xml文件的解析,生成Application, activity,service,broadcast, provider等信息。 /vendor/overlay /system/framework /system/priv-app /system/app /vendor/priv-app /vendor/app /oem/app
阶段3:BOOT_PROGRESS_PMS_DATA_SCAN_START
mSettings.pruneSharedUsersLPw();
if (!mOnlyCore) {
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
SystemClock.uptimeMillis());
scanDirTracedLI(mAppInstallDir,
0, scanFlags | SCAN_REQUIRE_KNOWN,
0);
scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
| PackageParser.PARSE_FORWARD_LOCK,
scanFlags | SCAN_REQUIRE_KNOWN,
0);
scanDirLI(mEphemeralInstallDir, mDefParseFlags
| PackageParser.PARSE_IS_EPHEMERAL,
scanFlags | SCAN_REQUIRE_KNOWN,
0);
/**
* Remove disable package settings for any updated system
* apps that were removed via an OTA. If they're not a
* previously-updated app, remove them completely.
* Otherwise, just revoke their system-level permissions.
*/
for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
mSettings.removeDisabledSystemPackageLPw(deletedAppName);
String msg;
if (deletedPkg ==
null) {
msg =
"Updated system package " + deletedAppName
+
" no longer exists; it's data will be wiped";
}
else {
msg =
"Updated system app + " + deletedAppName
+
" no longer present; removing system privileges for "
+ deletedAppName;
deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
}
logCriticalInfo(Log.WARN, msg);
}
/**
* Make sure all system apps that we expected to appear on
* the userdata partition actually showed up. If they never
* appeared, crawl back and revive the system version.
*/
for (
int i =
0; i < mExpectingBetter.size(); i++) {
final String packageName = mExpectingBetter.keyAt(i);
if (!mPackages.containsKey(packageName)) {
final File scanFile = mExpectingBetter.valueAt(i);
logCriticalInfo(Log.WARN,
"Expected better " + packageName
+
" but never showed up; reverting to system");
int reparseFlags = mDefParseFlags;
if (FileUtils.contains(privilegedAppDir, scanFile)) {
reparseFlags = PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR
| PackageParser.PARSE_IS_PRIVILEGED;
}
else if (FileUtils.contains(systemAppDir, scanFile)) {
reparseFlags = PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR;
}
else if (FileUtils.contains(vendorAppDir, scanFile)) {
reparseFlags = PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR;
}
else if (FileUtils.contains(oemAppDir, scanFile)) {
reparseFlags = PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR;
}
else {
Slog.e(TAG,
"Ignoring unexpected fallback path " + scanFile);
continue;
}
mSettings.enableSystemPackageLPw(packageName);
try {
scanPackageTracedLI(scanFile, reparseFlags, scanFlags,
0,
null);
}
catch (PackageManagerException e) {
Slog.e(TAG,
"Failed to parse original system package: "
+ e.getMessage());
}
}
}
}
mExpectingBetter.clear();
mSetupWizardPackage = getSetupWizardPackageName();
if (mProtectedFilters.size() >
0) {
if (DEBUG_FILTERS && mSetupWizardPackage ==
null) {
Slog.i(TAG,
"No setup wizard;"
+
" All protected intents capped to priority 0");
}
for (ActivityIntentInfo filter : mProtectedFilters) {
if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
if (DEBUG_FILTERS) {
Slog.i(TAG,
"Found setup wizard;"
+
" allow priority " + filter.getPriority() +
";"
+
" package: " + filter.activity.info.packageName
+
" activity: " + filter.activity.className
+
" priority: " + filter.getPriority());
}
continue;
}
Slog.w(TAG,
"Protected action; cap priority to 0;"
+
" package: " + filter.activity.info.packageName
+
" activity: " + filter.activity.className
+
" origPrio: " + filter.getPriority());
filter.setPriority(
0);
}
}
mDeferProtectedFilters =
false;
mProtectedFilters.clear();
updateAllSharedLibrariesLPw();
for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
adjustCpuAbisForSharedUserLPw(setting.packages,
null ,
false );
}
mPackageUsage.readLP();
当mOnlyCore = false时,则scanDirLI()还会收集如下目录中的apk /data/app /data/app-private
阶段4:BOOT_PROGRESS_PMS_SCAN_END
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
SystemClock.uptimeMillis());
Slog.i(TAG,
"Time to scan packages: "
+ ((SystemClock.uptimeMillis()-startTime)/
1000f)
+
" seconds");
int updateFlags = UPDATE_PERMISSIONS_ALL;
if (ver.sdkVersion != mSdkVersion) {
Slog.i(TAG,
"Platform changed from " + ver.sdkVersion +
" to "
+ mSdkVersion +
"; regranting permissions for internal storage");
updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
}
updatePermissionsLPw(
null,
null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
ver.sdkVersion = mSdkVersion;
if (!onlyCore && (mPromoteSystemApps || !mRestoredSettings)) {
for (UserInfo user : sUserManager.getUsers(
true)) {
mSettings.applyDefaultPreferredAppsLPw(
this, user.id);
applyFactoryDefaultBrowserLPw(user.id);
primeDomainVerificationsLPw(user.id);
}
}
final int storageFlags;
if (StorageManager.isFileEncryptedNativeOrEmulated()) {
storageFlags = StorageManager.FLAG_STORAGE_DE;
}
else {
storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
}
reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL, UserHandle.USER_SYSTEM,
storageFlags);
if (mIsUpgrade && !onlyCore) {
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)) {
clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
| Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
}
}
ver.fingerprint = Build.FINGERPRINT;
}
checkDefaultBrowser();
mExistingSystemPackages.clear();
mPromoteSystemApps =
false;
ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
mSettings.writeLPr();
if ((isFirstBoot() || isUpgrade() || VMRuntime.didPruneDalvikCache()) && !onlyCore) {
long start = System.nanoTime();
List<PackageParser.Package> coreApps =
new ArrayList<>();
for (PackageParser.Package pkg : mPackages.values()) {
if (pkg.coreApp) {
coreApps.add(pkg);
}
}
int[] stats = performDexOpt(coreApps,
false,
getCompilerFilterForReason(REASON_CORE_APP));
final int elapsedTimeSeconds =
(
int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start);
MetricsLogger.histogram(mContext,
"opt_coreapps_time_s", elapsedTimeSeconds);
if (DEBUG_DEXOPT) {
Slog.i(TAG,
"Dex-opt core apps took : " + elapsedTimeSeconds +
" seconds (" +
stats[
0] +
", " + stats[
1] +
", " + stats[
2] +
")");
}
}
阶段5:BOOT_PROGRESS_PMS_READY
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
SystemClock.uptimeMillis());
if (!mOnlyCore) {
mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
mRequiredInstallerPackage = getRequiredInstallerLPr();
mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
mIntentFilterVerifier =
new IntentVerifierProxy(mContext,
mIntentFilterVerifierComponent);
mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES);
mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
PackageManager.SYSTEM_SHARED_LIBRARY_SHARED);
}
else {
mRequiredVerifierPackage =
null;
mRequiredInstallerPackage =
null;
mIntentFilterVerifierComponent =
null;
mIntentFilterVerifier =
null;
mServicesSystemSharedLibraryPackageName =
null;
mSharedSystemSharedLibraryPackageName =
null;
}
mInstallerService =
new PackageInstallerService(context,
this);
final ComponentName ephemeralResolverComponent = getEphemeralResolverLPr();
final ComponentName ephemeralInstallerComponent = getEphemeralInstallerLPr();
if (ephemeralInstallerComponent !=
null && ephemeralResolverComponent !=
null) {
if (DEBUG_EPHEMERAL) {
Slog.i(TAG,
"Ephemeral activated; resolver: " + ephemeralResolverComponent
+
" installer:" + ephemeralInstallerComponent);
}
mEphemeralResolverComponent = ephemeralResolverComponent;
mEphemeralInstallerComponent = ephemeralInstallerComponent;
setUpEphemeralInstallerActivityLP(mEphemeralInstallerComponent);
mEphemeralResolverConnection =
new EphemeralResolverConnection(mContext, mEphemeralResolverComponent);
}
else {
if (DEBUG_EPHEMERAL) {
final String missingComponent =
(ephemeralResolverComponent ==
null)
? (ephemeralInstallerComponent ==
null)
?
"resolver and installer"
:
"resolver"
:
"installer";
Slog.i(TAG,
"Ephemeral deactivated; missing " + missingComponent);
}
mEphemeralResolverComponent =
null;
mEphemeralInstallerComponent =
null;
mEphemeralResolverConnection =
null;
}
mEphemeralApplicationRegistry =
new EphemeralApplicationRegistry(
this);
}
}
Runtime.getRuntime().gc();
mInstaller.setWarnIfHeld(mPackages);
LocalServices.addService(PackageManagerInternal.
class,
new PackageManagerInternalImpl());
PKMS初始化完成阶段,还会创建一个PackageInstaller服务。
public PackageInstallerService(Context context, PackageManagerService pm) {
mContext = context;
mPm = pm;
mInstallThread =
new HandlerThread(TAG);
mInstallThread.start();
mInstallHandler =
new Handler(mInstallThread.getLooper());
mCallbacks =
new Callbacks(mInstallThread.getLooper());
mSessionsFile =
new AtomicFile(
new File(Environment.getSystemSecureDirectory(),
"install_sessions.xml"));
mSessionsDir =
new File(Environment.getSystemSecureDirectory(),
"install_sessions");
mSessionsDir.mkdirs();
synchronized (mSessions) {
readSessionsLocked();
reconcileStagesLocked(StorageManager.UUID_PRIVATE_INTERNAL);
final ArraySet<File> unclaimedIcons = newArraySet(
mSessionsDir.listFiles());
for (
int i =
0; i < mSessions.size(); i++) {
final PackageInstallerSession session = mSessions.valueAt(i);
unclaimedIcons.remove(buildAppIconFile(session.sessionId));
}
for (File icon : unclaimedIcons) {
icon.delete();
}
}
}
PKMS初始化过程,分为5个阶段: PMS_START阶段: 创建Settings对象; 将6类shareUserId到mSettings; 初始化SystemConfig; 创建名为“PackageManager”的handler线程mHandlerThread; 创建UserManagerService多用户管理服务; 通过解析4大目录中的xmL文件构造共享mSharedLibraries; PMS_SYSTEM_SCAN_START阶段: 扫描系统apk; PMS_DATA_SCAN_START阶段: 扫描/data/app目录下的apk; 扫描/data/app-private目录下的apk; PMS_SCAN_END阶段: 将上述信息写回/data/system/packages.xml; PMS_READY阶段: 创建服务PackageInstallerService;
PKMS.systemReady
@Override
public void systemReady() {
mSystemReady =
true;
boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
mContext.getContentResolver(),
android.provider.Settings.Global.COMPATIBILITY_MODE,
1) ==
1;
PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
if (DEBUG_SETTINGS) {
Log.d(TAG,
"compatibility mode:" + compatibilityModeEnabled);
}
int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
synchronized (mPackages) {
ArrayList<PreferredActivity> removed =
new ArrayList<PreferredActivity>();
for (
int i=
0; i<mSettings.mPreferredActivities.size(); i++) {
PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
removed.clear();
for (PreferredActivity pa : pir.filterSet()) {
if (mActivities.mActivities.get(pa.mPref.mComponent) ==
null) {
removed.add(pa);
}
}
if (removed.size() >
0) {
for (
int r=
0; r<removed.size(); r++) {
PreferredActivity pa = removed.get(r);
Slog.w(TAG,
"Removing dangling preferred activity: "
+ pa.mPref.mComponent);
pir.removeFilter(pa);
}
mSettings.writePackageRestrictionsLPr(
mSettings.mPreferredActivities.keyAt(i));
}
}
for (
int userId : UserManagerService.getInstance().getUserIds()) {
if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
grantPermissionsUserIds = ArrayUtils.appendInt(
grantPermissionsUserIds, userId);
}
}
}
sUserManager.systemReady();
for (
int userId : grantPermissionsUserIds) {
mDefaultPermissionPolicy.grantDefaultPermissions(userId);
}
if (mPostSystemReadyMessages !=
null) {
for (Message msg : mPostSystemReadyMessages) {
msg.sendToTarget();
}
mPostSystemReadyMessages =
null;
}
final StorageManager storage = mContext.getSystemService(StorageManager.class);
storage.registerListener(mStorageListener);
mInstallerService.systemReady();
mPackageDexOptimizer.systemReady();
MountServiceInternal mountServiceInternal = LocalServices.getService(
MountServiceInternal.class);
mountServiceInternal.addExternalStoragePolicy(
new MountServiceInternal.ExternalStorageMountPolicy() {
@Override
public int getMountMode(
int uid, String packageName) {
if (Process.isIsolated(uid)) {
return Zygote.MOUNT_EXTERNAL_NONE;
}
if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
return Zygote.MOUNT_EXTERNAL_DEFAULT;
}
if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
return Zygote.MOUNT_EXTERNAL_DEFAULT;
}
if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
return Zygote.MOUNT_EXTERNAL_READ;
}
return Zygote.MOUNT_EXTERNAL_WRITE;
}
@Override
public boolean hasExternalStorage(
int uid, String packageName) {
return true;
}
});
reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
}
至此,PackageManagerService启动流程分析完毕,如有错误之处,欢迎留言指正。