接上文:PackageManagerService Android 8.1 源码解读 01
d、第三步细节:PKMS.main(),main函数主要工作:
- 【检查】Package编译相关系统属性
- 【调用】PackageManagerService【构造方法】
- 【启用】部分【应用服务】于多用户场景
- 【注册】服务【”package”】和【”package_native”】到ServiceManager中。
public static PackageManagerService main(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
// (1)检查Package编译相关系统属性
PackageManagerServiceCompilerMapping.checkProperties();
//(2)调用PackageManagerService构造方法, 可以参考【PKMS构造方法】
PackageManagerService m = new PackageManagerService(context, installer,
factoryTest, onlyCore);
//(3)启用部分应用服务于多用户场景
m.enableSystemUserPackages();
//(4)往ServiceManager中注册”package”和”package_native”
ServiceManager.addService("package", m);
final PackageManagerNative pmn = m.new PackageManagerNative();
ServiceManager.addService("package_native", pmn);
return m;
}
d.1、函数checkProperties(),主要是检测编译属性的有效性,如果不合法,直接报错;
// Check that the properties are set and valid.
// Note: this is done in a separate method so this class can be statically initialized.
static void checkProperties() {
// We're gonna check all properties and collect the exceptions, so we can give a general
// overview. Store the exceptions here.
RuntimeException toThrow = null;
// REASON_LAST = 6
for (int reason = 0; reason <= PackageManagerService.REASON_LAST; reason++) {
try {
// 循环检测系统属性名称的合法性
String sysPropName = getSystemPropertyName(reason);
if (sysPropName == null || sysPropName.isEmpty()) {
throw new IllegalStateException("Reason system property name \"" +
sysPropName +"\" for reason " + REASON_STRINGS[reason]);
}
// 检测属性的有效性,忽略结果
getAndCheckValidity(reason);
} catch (Exception exc) {
if (toThrow == null) {
toThrow = new IllegalStateException("PMS compiler filter settings are bad.");
}
toThrow.addSuppressed(exc);
}
}
if (toThrow != null) {
throw toThrow;
}
}
//获取系统属性名称
private static String getSystemPropertyName(int reason) {
if (reason < 0 || reason >= REASON_STRINGS.length) {
throw new IllegalArgumentException("reason " + reason + " invalid");
}
return "pm.dexopt." + REASON_STRINGS[reason];
}
//编译原因的名称。
static final String REASON_STRINGS[] = {
"first-boot", "boot", "install", "bg-dexopt", "ab-ota", "inactive", "shared"
};
// 根据给定的原因加载属性并检查其有效性。如果原因或值无效,这将引发异常。
private static String getAndCheckValidity(int reason) {
String sysPropValue = SystemProperties.get(getSystemPropertyName(reason));
if (sysPropValue == null || sysPropValue.isEmpty() ||
!DexFile.isValidCompilerFilter(sysPropValue)) {
throw new IllegalStateException("Value \"" + sysPropValue +"\" not valid "
+ "(reason " + REASON_STRINGS[reason] + ")");
} else if (!isFilterAllowedForReason(reason, sysPropValue)) {
throw new IllegalStateException("Value \"" + sysPropValue +"\" not allowed "
+ "(reason " + REASON_STRINGS[reason] + ")");
}
return sysPropValue;
}
检测到我的设备的属性名称如下:
k37mv1_bsp:/ $ getprop |grep pm.dexopt
[pm.dexopt.ab-ota]: [speed-profile]
[pm.dexopt.bg-dexopt]: [speed-profile]
[pm.dexopt.boot]: [verify]
[pm.dexopt.downgrade_after_inactive_days]: [10]
[pm.dexopt.first-boot]: [quicken]
[pm.dexopt.inactive]: [verify]
[pm.dexopt.install]: [quicken]
[pm.dexopt.shared]: [quicken]
k37mv1_bsp:/ $
d.2、【PKMS构造方法】:重点分析,内容比较多
d.2.1、KMS初始化时的核心部分为PKMS()构造函数的内容,我们下面就来分析该流程:
PKMS的构造函数中由两个重要的锁(mInstallLock、mPackages):
- 【mInstallLock】 :用来保护所有安装apk的访问权限,此操作通常涉及【繁重的磁盘数据读写】等操作,并且是【单线程操作】,故有时候会【处理很慢】,此锁不会在已经持有mPackages锁的情况下持有,反之,在已经持有mInstallLock锁的情况下,立即获取mPackages是安全的
- 【mPackages】:用来解析【内存中所有apk的package信息】及相关状态
和五个阶段组成:
- 阶段1:BOOT_PROGRESS_PMS_START:PKMS开始阶段
- 阶段2:BOOT_PROGRESS_PMS_SYSTEM_SCAN_START:扫描系统app阶段
- 阶段3:BOOT_PROGRESS_PMS_DATA_SCAN_START:扫描data目录阶段
- 阶段4:BOOT_PROGRESS_PMS_SCAN_END:扫描结束
- 阶段5:BOOT_PROGRESS_PMS_READY:pms做准备
阶段1:BOOT_PROGRESS_PMS_START:PKMS开始阶段
- (1) 构造 【DisplayMetrics】 ,保存分辨率等相关信息;
- (2) 构造【Settings】类,保存安装包信息,清除路径不存在的孤立应用,主要涉及/data/system/目录的packages.xml,packages-backup.xml,packages.list,packages-stopped.xml,packages-stoppedbackup.xml等文件。
- (3) 创建【Installer】对象,与installd交互;
- (4) 构造【PackageDexOptimizer及DexManager】类,处理dex优化;
- (5) 创建【SystemConfig】实例,获取系统配置信息,配置共享lib库;
- (6) 创建【mSystemPermissions】对象,进行权限管理;
- (7) 创建【PackageManager的handler】线程,循环处理外部安装相关消息。
public PackageManagerService(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
// 安装锁
LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
SystemClock.uptimeMillis());
// 保存上下文的引用
mContext = context;
// 一般为false,即非工厂生产模式
mFactoryTest = factoryTest;
// 标记是否只加载核心服务,一般都是false
mOnlyCore = onlyCore;
// (1) 构造 DisplayMetrics ,保存分辨率等相关信息;
mMetrics = new DisplayMetrics();
// (2)构造Settings类,保存安装包信息,清除路径不存在的孤立应用,主要涉
// 及/data/system/目录的packages.xml,packages-backup.xml, packages.list,
// packages-stopped.xml,packages-stopped-backup.xml等文件。
// 添加system, phone, log, nfc, bluetooth, shell 这6种shareUserId到mSettings;
mSettings = new Settings(mPackages);
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);
......省略
// (3)创建Installer对象,与installd交互;
mInstaller = installer;
// (4)构造【PackageDexOptimizer及DexManager】类,处理dex优化
mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
"*dexopt*");
mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock);
// 创建移动回调
mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
// 创建权限改变监听器
mOnPermissionChangeListeners = new OnPermissionChangeListeners(
FgThread.get().getLooper());
// 获取默认分辨率
getDefaultDisplayMetrics(context, mMetrics);
// (5)创建【SystemConfig】实例,获取系统配置信息,配置共享lib库;
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
// 这是一个单例模式,保存着系统的权限
SystemConfig systemConfig = SystemConfig.getInstance();
mGlobalGids = systemConfig.getGlobalGids();
// (6)获取系统权限
mSystemPermissions = systemConfig.getSystemPermissions();
mAvailableFeatures = systemConfig.getAvailableFeatures();
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
// 受保护的包名对象
mProtectedPackages = new ProtectedPackages(mContext);
// 创建提供服务、数据的子组件。
// 这里的顺序很重要,使用到了两个重要的同步锁:mInstallLock、mPackages
synchronized (mInstallLock) {
// writer
synchronized (mPackages) {
// (7)创建PackageManager的handler线程,循环处理外部安装相关消息。
// 启动"PackageManager"线程,负责apk的安装、卸载
mHandlerThread = new ServiceThread(TAG,
Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
mHandlerThread.start();
// 应用handler
mHandler = new PackageHandler(mHandlerThread.getLooper());
// 进程记录handler
mProcessLoggingHandler = new ProcessLoggingHandler();
// Watchdog监听ServiceThread是否超时:10分钟
Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
// 创建默认的权限策略对象
mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this);
// Instant应用注册
mInstantAppRegistry = new InstantAppRegistry(this);
// 创建/data/app目录和/data/app-lib目录,/data/app-asec,已经/data/app-private目录
File dataDir = Environment.getDataDirectory();
// 创建/data/app目录
mAppInstallDir = new File(dataDir, "app");
// 创建/data/app-lib目录
mAppLib32InstallDir = new File(dataDir, "app-lib");
// 创建/data/app-asec目录
mAsecInternalPath = new File(dataDir, "app-asec").getPath();
// /data/app-private目录
mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
// 窗机用户管理服务
sUserManager = new UserManagerService(context, this,
new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), 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);
}
}
// 共享lib库配置
ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
final int builtInLibCount = libConfig.size();
for (int i = 0; i < builtInLibCount; i++) {
String name = libConfig.keyAt(i);
String path = libConfig.valueAt(i);
addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
}
// 读取安装相关SELinux策略
mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
// 读取并解析/data/system下的XML文件
mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
// Clean up orphaned packages for which the code path doesn't exist
// and they are an update to a system app - caused by bug/32321269
// 清理代码路径不存在的孤立软件包
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);
}
}
// 如果不是首次启动,也不是CORE应用,则拷贝预编译的DEX文件
if (!mOnlyCore && mFirstBoot) {
requestCopyPreoptedFiles();
}
// 获取客制化的Activity,
String customResolverActivity = Resources.getSystem().getString(
R.string.config_customResolverActivity);
if (TextUtils.isEmpty(customResolverActivity)) {
customResolverActivity = null;
} else {
mCustomResolverComponentName = ComponentName.unflattenFromString(
customResolverActivity);
}
long startTime = SystemClock.uptimeMillis();
...............
}
}
......
}
重点分析一下readLPw,mSettings.readLPw,readLPw()会扫描下面5个文件
- 1) "/data/system/packages.xml" :所有安装app信息
- 2) "/data/system/packages-backup.xml" :所有安装app信息之备份的信息记录
- 3) "/data/system/packages.list" :所有安装app信息
- 4) "/data/system/packages-stopped.xml" :所有强制停止app信息
- 5) "/data/system/packages-stopped-backup.xml" :所有强制停止app信息之备份的信息记录
五个文件共分为三组,简单的作用描述如下:
- 【packages.xml】:PKMS 扫描完目标文件夹后会创建该文件。当系统进行程序安装、卸载和更新等操作时,均会更新该文件。该文件保存了系统中与 package 相关的一些信息。
- 【packages.list】:描述系统中存在的所有非系统自带的 APK 的信息。当这些程序有变动时,PKMS 就会更新该文件。
- 【packages-stopped.xml】:从系统自带的设置程序中进入应用程序页面,然后在选择强制停止(ForceStop)某个应用时,系统会将该应用的相关信息记录到此文件中。也就是该文件保存系统中被用户强制停止的 Package 的信息。
这些目录的指向,都在Settings中的构造函数完成, 如下所示,得到目录后调用readLPw()进行扫描
Settings(File dataDir, Object lock) {
mLock = lock;
mRuntimePermissionsPersistence = new RuntimePermissionPersistence(mLock);
// mSystemDir指向目录"/data/system"
mSystemDir = new File(dataDir, "system");
// 创建 "/data/system"
mSystemDir.mkdirs();
// 设置权限
FileUtils.setPermissions(mSystemDir.toString(),
FileUtils.S_IRWXU|FileUtils.S_IRWXG
|FileUtils.S_IROTH|FileUtils.S_IXOTH,
-1, -1);
// (1)指向目录"/data/system/packages.xml"
mSettingsFilename = new File(mSystemDir, "packages.xml");
// (2)指向目录"/data/system/packages-backup.xml"
mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml");
// (3)指向目录"/data/system/packages.list"
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;
// Deprecated: Needed for migration
// (4)指向目录"/data/system/packages-stopped.xml"
mStoppedPackagesFilename = new File(mSystemDir, "packages-stopped.xml");
// (5)指向目录"/data/system/packages-stopped-backup.xml"
mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml");
}
继续看:readLPw()函数
boolean readLPw(@NonNull List<UserInfo> users) {
FileInputStream str = null;
......省略
if (str == null) {
......省略
str = new FileInputStream(mSettingsFilename);
}
XmlPullParser parser = Xml.newPullParser();
parser.setInput(str, StandardCharsets.UTF_8.name());
int type;//遍历文件,查找xml文件的第一个起始字符
while ((type = parser.next()) != XmlPullParser.START_TAG
&& type != XmlPullParser.END_DOCUMENT) {
;
}
......省略
int outerDepth = parser.getDepth();
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
continue;
}
// 根据XML的各个节点进行各种操作,例如读取权限、shared-user等
String tagName = parser.getName();
if (tagName.equals("package")) {
readPackageLPw(parser);
} else if (tagName.equals("permissions")) {
readPermissionsLPw(mPermissions, parser);
} else if (tagName.equals("permission-trees")) {
readPermissionsLPw(mPermissionTrees, parser);
} else if (tagName.equals("shared-user")) {
readSharedUserLPw(parser);
} else if (tagName.equals("preferred-packages")) {
// no longer used.
} else if (tagName.equals("preferred-activities")) {
// Upgrading from old single-user implementation;
// these are the preferred activities for user 0.
readPreferredActivitiesLPw(parser, 0);
} else if (tagName.equals(TAG_PERSISTENT_PREFERRED_ACTIVITIES)) {
// TODO: check whether this is okay! as it is very
// similar to how preferred-activities are treated
readPersistentPreferredActivitiesLPw(parser, 0);
} else if (tagName.equals(TAG_CROSS_PROFILE_INTENT_FILTERS)) {
// TODO: check whether this is okay! as it is very
// similar to how preferred-activities are treated
readCrossProfileIntentFiltersLPw(parser, 0);
} else if (tagName.equals(TAG_DEFAULT_BROWSER)) {
readDefaultAppsLPw(parser, 0);
} else if (tagName.equals("updated-package")) {
readDisabledSysPackageLPw(parser);
} ......省略
str.close();
......
return true;
}
阶段2:BOOT_PROGRESS_PMS_SYSTEM_SCAN_START:扫描系统app阶段
- (1) 从【init.rc】中获取环境变量BOOTCLASSPATH和SYSTEMSERVERCLASSPATH;
- (2) 对于【旧版本升级】的情况,将【安装时】获取权限变更为【运行时】申请权限;
- (3) 【扫描】system/vendor/product/odm/oem等目录的priv-app、app、overlay包;
- (4) 【清除】安装时临时文件以及其他不必要的信息。
public PackageManagerService(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
synchronized (mInstallLock) {
synchronized (mPackages) {
// 记录扫描开始时间
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
startTime);
// (1)从init.rc中获取环境变量BOOTCLASSPATH和SYSTEMSERVERCLASSPATH;
final String bootClassPath = System.getenv("BOOTCLASSPATH");
final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
......省略
// 获取system/framework目录
File frameworkDir = new File(Environment.getRootDirectory(), "framework");
// 获取内部版本
final VersionInfo ver = mSettings.getInternalVersion();
// 判断fingerprint是否有更新
mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
if (mIsUpgrade) {
logCriticalInfo(Log.INFO,
"Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
}
// (2)对于旧版本升级的情况,将安装时获取权限变更为运行时申请权限
// 对于Android M之前版本升级上来的情况,需将系统应用程序权限从安装升级到运行时
mPromoteSystemApps =
mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
// 对于Android N之前版本升级上来的情况,需像首次启动一样处理package
mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
// 在扫描之前保存预先存在的系统package的名称,不希望自动为新系统应用授予运行时权限
if (mPromoteSystemApps) {
Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
while (pkgSettingIter.hasNext()) {
PackageSetting ps = pkgSettingIter.next();
if (isSystemApp(ps)) {
mExistingSystemPackages.add(ps.name);
}
}
}
// 准备解析package的缓存
mCacheDir = preparePackageParserCache(mIsUpgrade);
// 设置flag,而不在扫描安装时更改文件路径
int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
if (mIsUpgrade || mFirstBoot) {
scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
}
// (3)扫描"/vendor/overlay"等目录的priv-app、app文件;
scanDirTracedLI(new File(VENDOR_OVERLAY_DIR), mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR
| PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
mParallelPackageParserCallback.findStaticOverlayPackages();
// 扫描"/system/framework"目录;
// Find base frameworks (resource packages without code).
scanDirTracedLI(frameworkDir, mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR
| PackageParser.PARSE_IS_PRIVILEGED,
scanFlags | SCAN_NO_DEX, 0);
// Collected privileged system packages.
// 扫描"/system/priv-app"目录;
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);
// Collect ordinary system packages.
// 扫描"/system/app"目录
final File systemAppDir = new File(Environment.getRootDirectory(), "app");
scanDirTracedLI(systemAppDir, mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
// Collect all vendor packages.
// 扫描"/vendor/app"目录
File vendorAppDir = new File("/vendor/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
| PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
// Collect all OEM packages.
// 扫描"/oem/app"目录
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<>();
// Stub packages must either be replaced with full versions in the /data
// partition or be disabled.
final List<String> stubSystemApps = new ArrayList<>();
// 删掉不存在的package
if (!mOnlyCore) {
// do this first before mucking with mPackages for the "expecting better" case
final Iterator<PackageParser.Package> pkgIterator = mPackages.values().iterator();
while (pkgIterator.hasNext()) {
final PackageParser.Package pkg = pkgIterator.next();
if (pkg.isStub) {
stubSystemApps.add(pkg.packageName);
}
}
final Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
while (psit.hasNext()) {
PackageSetting ps = psit.next();
// 如果不是系统应用,则不被允许disable
if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
/// M: Operator apps are belong to system domain, therefore, need prune.
/// We should also consider OTA from old version without mtkFlag
if (sPmsExt.isNotOperatorApp(ps))
continue;
}
// 如果应用被扫描,则不允许被擦除
final PackageParser.Package scannedPkg = mPackages.get(ps.name);
if (scannedPkg != null) {
// 如果系统应用被扫描且存在disable应用列表中,则只能通过OTA升级添加
if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
......
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");
// Actual deletion of code and data will be handled by later
// reconciliation step
} else {
// we still have a disabled system package, but, it still might have
// been removed. check the code path still exists and check there's
// still a package. the latter can happen if an OTA keeps the same
// code path, but, changes the package name.
final PackageSetting disabledPs =
mSettings.getDisabledSystemPkgLPr(ps.name);
if (disabledPs.codePath == null || !disabledPs.codePath.exists()
|| disabledPs.pkg == null) {
possiblyDeletedUpdatedSystemApps.add(ps.name);
}
}
}
}
//look for any incomplete package installations
ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
for (int i = 0; i < deletePkgsList.size(); i++) {
// Actual deletion of code and data will be handled by later
// reconciliation step
final String packageName = deletePkgsList.get(i).name;
logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName);
synchronized (mPackages) {
mSettings.removePackageLPw(packageName);
}
}
// (4)清除安装时临时文件以及其他不必要的信息。
// 删除临时文件
deleteTempPackageFiles();
final int cachedSystemApps = PackageParser.sCachedPackageReadCount.get();
// 删除没有关联应用的共享UID标识
mSettings.pruneSharedUsersLPw();
final long systemScanTime = SystemClock.uptimeMillis() - startTime;
final int systemPackagesCount = mPackages.size();
......
}
}
}
阶段3:BOOT_PROGRESS_PMS_DATA_SCAN_START:扫描data目录阶段
对于不仅仅解析核心应用的情况下,还处理data目录的应用信息,及时更新,去除不必要的数据
if (!mOnlyCore) {
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
SystemClock.uptimeMillis());
// 扫描app安装目录:/data/app
scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
// 扫描app-private目录:/data/app-private
scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
| PackageParser.PARSE_FORWARD_LOCK,
scanFlags | SCAN_REQUIRE_KNOWN, 0);
// 移除通过OTA删除的更新系统应用程序的禁用package设置
// 如果更新不再存在,则完全删除该应用。否则,撤消其系统权限
for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
mSettings.removeDisabledSystemPackageLPw(deletedAppName);
final String msg;
if (deletedPkg == null) {
// should have found an update, but, we didn't; remove everything
msg = "Updated system package " + deletedAppName
+ " 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 + " + deletedAppName
+ " no longer exists; revoking system privileges";
// Don't do anything if a stub is removed from the system image. If
// we were to remove the uncompressed version from the /data partition,
// this is where it'd be done.
final PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
}
logCriticalInfo(Log.WARN, msg);
}
// 确保期望在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);
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 {
//扫描APK
scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);
} catch (PackageManagerException e) {
Slog.e(TAG, "Failed to parse original system package: "
+ e.getMessage());
}
}
}
// 解压缩并安装任何存根系统应用程序。必须最后执行此操作以确保替换或禁用所有存根
decompressSystemApplications(stubSystemApps, scanFlags);
......
}
mExpectingBetter.clear();
// 获取storage manager包名
mStorageManagerPackage = getStorageManagerPackageName();
// 解决受保护的action过滤器。只允许setup wizard(开机向导)为这些action
// 设置高优先级过滤器
mSetupWizardPackage = getSetupWizardPackageName();
......
// 更新客户端以确保持有正确的共享库路径
updateAllSharedLibrariesLPw(null);
......
// 读取并更新要保留的package的上次使用时间
mPackageUsage.read(mPackages);
mCompilerStats.read();
阶段4:BOOT_PROGRESS_PMS_SCAN_END:扫描结束
- (1) 【sdk版本】变更,更新权限;
- (2) 【OTA升级】后首次启动,清除不必要的缓存数据;
- (3) 【权限】等默认项更新完后,清理相关数据;
- (4) 【更新】package.xml
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
SystemClock.uptimeMillis());
Slog.i(TAG, "Time to scan packages: "
+ ((SystemClock.uptimeMillis()-startTime)/1000f)
+ " seconds");
// (1) sdk版本变更,更新权限;
// 如果自上次启动以来,平台SDK已改变,则需要重新授予应用程序权限以捕获出现的任何新权限
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);
// 设置sdk的版本
ver.sdkVersion = mSdkVersion;
// 如果这是第一次启动或来自Android M之前的版本的升级,并且它是正常启动,那需要在
// 所有已定义的用户中初始化默认的首选应用程序
if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
for (UserInfo user : sUserManager.getUsers(true)) {
mSettings.applyDefaultPreferredAppsLPw(this, user.id);
applyFactoryDefaultBrowserLPw(user.id);
primeDomainVerificationsLPw(user.id);
}
}
// 在启动期间确实为系统用户准备存储,因为像SettingsProvider和SystemUI这样的核
// 心系统应用程序无法等待用户启动
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.get().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) {
PackageParser.Package pkg = null;
synchronized (mPackages) {
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");
// (2) OTA升级后首次启动,清除不必要的缓存数据;
// 如果是在OTA之后首次启动,并且正常启动,那需要清除代码缓存目录,但不清除应用程序配置文件
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)) {
// No apps are running this early, so no need to freeze
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();
// (3) 权限等默认项更新完后,清理相关数据;
// 仅在权限或其它默认配置更新后清除
mExistingSystemPackages.clear();
mPromoteSystemApps = false;
// 所有变更均在扫描过程中完成
ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
//【同学们注意】(4) 更新package.xml
// 降级去读取
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
mSettings.writeLPr();
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
阶段5:BOOT_PROGRESS_PMS_READY:pms做准备
GC回收内存 和一些细节而已
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;
}
mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
SharedLibraryInfo.VERSION_UNDEFINED);
mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
SharedLibraryInfo.VERSION_UNDEFINED);
} else {
......省略,都是if体的清空数据
}
// 创建PackageInstallerService服务
mInstallerService = new PackageInstallerService(context, this);
final Pair<ComponentName, String> instantAppResolverComponent =
getInstantAppResolverLPr();
if (instantAppResolverComponent != null) {
if (DEBUG_EPHEMERAL) {
Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
}
mInstantAppResolverConnection = new EphemeralResolverConnection(
mContext, instantAppResolverComponent.first,
instantAppResolverComponent.second);
mInstantAppResolverSettingsComponent =
getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
} else {
mInstantAppResolverConnection = null;
mInstantAppResolverSettingsComponent = null;
}
updateInstantAppInstallerLocked(null);
// 阅读并更新dex文件的用法
// 在PM init结束时执行此操作,以便所有程序包都已协调其数据目录
// 此时知道了包的代码路径,因此可以验证磁盘文件并构建内部缓存
// 使用文件预计很小,因此与其他活动(例如包扫描)相比,加载和验证它应该花费相当小的时间
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);
} // synchronized (mPackages)
} // synchronized (mInstallLock)
// GC回收内存
// 打开应用之后,及时回收处理
Runtime.getRuntime().gc();
// 返回栈的回滚
FallbackCategoryProvider.loadFallbacks();
// 上面的初始扫描在持有mPackage锁的同时对installd进行了多次调用
mInstaller.setWarnIfHeld(mPackages);
// 将PackageManagerInternalImpl添加到本地服务中
LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
下一篇继续,将进入三部曲
PackageManagerService Android 8.1 源码解读 03