PackageManagerService(简称PKMS),是Aandroid系统中核心服务之一,负责应用程序的安装、卸载、信息查询等工作。
PMS概述:
Android系统启动时,在SystemServer的main函数中会启动应用程序管理服务器PKMS。
[-->SystemServer.java]
private void startBootstrapServices() {
mPackageManagerService = PackageManagerService.main(mSystemContext, installer, //初始化PKMS
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
mFirstBoot = mPackageManagerService.isFirstBoot(); //是否是第一次启动
mPackageManager = mSystemContext.getPackageManager(); // 获取到PackageManager
}
[PackageManagerService.java]
public class PackageManagerService extends IPackageManager.Stub { //PKMS继承IPackageManager.Stub,实现其所有的接口
public static final PackageManagerService main(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
PackageManagerService m = new PackageManagerService(context, installer, //创建PackageManagerService
factoryTest, onlyCore);
ServiceManager.addService("package", m); //将PKMS加入到ServiceManager 这里相当于添加的是IPackageManager.Stub 服务端
return m;
}
}
[SystemServer中获取PackageManager的过程 -->mSystemContext.getPackageManager()]
[ContextImpl.java]
public PackageManager getPackageManager() {
if (mPackageManager != null) {
return mPackageManager;
}
IPackageManager pm = ActivityThread.getPackageManager(); //由ActivityThread获取IPackageManager
if (pm != null) {
// Doesn't matter if we make more than one instance.
return (mPackageManager = new ApplicationPackageManager(this, pm)); //ApplicationPackageManager继承于PackageManager
}
return null;
}
[ActivityThread.java]
public static IPackageManager getPackageManager() {
if (sPackageManager != null) {
//Slog.v("PackageManager", "returning cur default = " + sPackageManager);
return sPackageManager;
}
IBinder b = ServiceManager.getService("package"); //获取到main函数中添加IPackageManager.Stub,获取到Binder服务端
//Slog.v("PackageManager", "default service binder = " + b);
sPackageManager = IPackageManager.Stub.asInterface(b); //返回IPackageManager.Stub.Proxy 代理对象
//Slog.v("PackageManager", "default service = " + sPackageManager);
return sPackageManager;
}
[ApplicationPackageManager.java]
最后返回new ApplicationPackageManager(this, pm))
也就是返回new ApplicationPackageManager(this, IPackageManager.Stub.asInterface(b)))
PKMS类之间的继承关系图
简单概括以下PKMS的核心功能
1.解析AndroidManifest.xml清单文件,解析清单文件中的所有节点信息
2.扫描.apk文件,安装系统应用,安装本地应用
3.管理本地应用,主要有安装、卸载、应用信息查询等
客户端可以通过Context.getPackageManager()获得ApplicationPackageManager对象,ApplicationPackageManager对象的成员变量mPM指向的是IPackageManager.Stub.Proxy代理对象,通过Binder机制中的mRemote与服务端PackageManagerService通信,并调用PackageManagerService的方法。
1.PKMS启动流程图
1.1PKMS启动的七个步骤
第一步 到 第四步:
startBootstrapServices()首先启动Installer服务,也就是安装器,随后判断当前的设备是否处于加密
状态,如果是则只是解析核心应用,接着调用PackageManagerService的静态方法main来创建pms对
象
第一步: 启动Installer服务
第二步:获取设备是否加密(手机设置密码),如果设备加密了,则只解析"core"应用
第三步: 调用PKMS main方法初始化PackageManagerService,其中调用PackageManagerService()
构造函数创建了PKMS对象
第四步: 如果设备没有加密,操作它。管理A/B OTA dexopting。
private void startBootstrapServices() {
//..........省略
//第一步:启动Installer,以便有机会创建合适的权限相关的目录,比如/data/user。需要在初始化其它服务之前完成此任务
Installer installer = mSystemServiceManager.startService(Installer.class);
//..........省略
// Activity manager runs the show.
traceBeginAndSlog("StartActivityManager");
mActivityManagerService = mSystemServiceManager.startService( //启动AMS
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer); //将installer设置给AMS
traceEnd();
//...........省略
// Only run "core" apps if we're encrypting the device.
//第二步:获取设备是否是加密状态(手机是否设置密码),如果设备是加密状态就只解析“core”APP,后面在PKMS中会利用mOnlyCore条件进行各种判断
String cryptState = SystemProperties.get("vold.decrypt");
if (ENCRYPTING_STATE.equals(cryptState)) {
Slog.w(TAG, "Detected encryption in progress - only parsing core apps");
mOnlyCore = true;
} else if (ENCRYPTED_STATE.equals(cryptState)) {
Slog.w(TAG, "Device encrypted - only parsing core apps");
mOnlyCore = true;
}
//...........省略
//第三步: 调用PKMS的main方法初始化PackageManagerService
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
//是否是第一次启动
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();
traceEnd();
if (!mRuntimeRestart && !isFirstBootOrUpgrade()) {
MetricsLogger.histogram(null, "boot_package_manager_init_ready",
(int) SystemClock.elapsedRealtime());
}
//第四步:如果设备没有加密,就管理A/B OTA dexopting
// Manages A/B OTA dexopting. This is a bootstrap service as we need it to rename
// A/B artifacts after boot, before anything else might touch/need them.
// Note: this isn't needed during decryption (we don't have /data anyways).
if (!mOnlyCore) {
boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt",
false);
if (!disableOtaDexopt) {
traceBeginAndSlog("StartOtaDexOptService");
try {
OtaDexoptService.main(mSystemContext, mPackageManagerService);
} catch (Throwable e) {
reportWtf("starting OtaDexOptService", e);
} finally {
traceEnd();
}
}
}
}
第五步,第六步,第七步:
startOtherServices
第五步: 执行 updatePackagesIfNeeded ,完成dex优化;
第六步: 执行 performFstrimIfNeeded ,完成磁盘维护;
第七步: 调用systemReady,准备就绪。
private void startOtherServices() {
...
if (!mOnlyCore) {
...
// 第五步:如果设备没有加密,执行performDexOptUpgrade,完成dex优化;
mPackageManagerService.updatePackagesIfNeeded();
}
...
// 第六步:最终执行performFstrim,完成磁盘维护
mPackageManagerService.performFstrimIfNeeded();
...
// 第七步:PKMS准备就绪
mPackageManagerService.systemReady();
...
}
主要分析第三步:
public static PackageManagerService main(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
// Self-check for initial settings.
//检查package编译相关的系统属性pm.dexopt.first-boot,pm.dexopt.boot,pm.dexopt.install,pm.dexopt.bg-dexopt,pm.dexopt.ab-ota等
PackageManagerServiceCompilerMapping.checkProperties();
//调用PKMS的构造函数
PackageManagerService m = new PackageManagerService(context, installer,
factoryTest, onlyCore);
//启用部分应用服务于多用户场景
m.enableSystemUserPackages();
//往ServiceManager中注册"package"和"package_native"
ServiceManager.addService("package", m);
final PackageManagerNative pmn = m.new PackageManagerNative();
ServiceManager.addService("package_native", pmn);
return m;
}
[PKMS构造方法]
PKMS中两个重要锁:
mInstallLock:用来保护所有安装apk的访问权限,此操作通常涉及繁重的磁盘数据读写操作,并且是单线程操作,故有时候会处理很慢,此锁不会在已经持有mPackages锁的情况下获得。反过来在已经持有mInstallLock锁的情况下,立即获取mPackages是安全的。
mPackages:用来解析内存中所有apk的package信息及相关状态。
PKMS构造函数的五个阶段
[阶段1:BOOT_PROGRESS_PMS_START]
(1)构造DisplayMetrics类:描述界面显示,尺寸,分辨率,密度。构造完后并获取默认的信息保存到变量mMetrics中
(2)构造Settings类:Setttings是Android的全局管理者,用于协助PKMS保存所有的安装包信息
(3)保存Installer对象
(4)获取系统配置信息:SystemConfig构造构造函数中会通过readPermissions()解析指定目录下的所有xml文件,然后把这些信息保存到systemConfig中,涉及目录有如下:
/system/etc/sysconfig
/system/etc/permissions
/oem/etc/sysconfig
/oem/etc/permissions
(5)创建名为PackageHandler的Handler线程,建立PackageHandler消息循环,用于处理外部安装请求等消息
(6)创建data下的各种目录,比如data/app,data/app-private等
(7)创建用户管理服务UserManagerService
(8)把SystemConfig关于xml中的标签所指的动态库保存到mSharedLibraries,Settings.readLPw扫描解析data/system/packages.xml和data/system/packages-backup.xml
和Settings.readLPw对应是Settings.writeLPr,writeLPr将
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");
mContext = context;
mFactoryTest = factoryTest;// 一般为false,即非工厂模式
mOnlyCore = onlyCore; //标记是否只加载核心服务
mMetrics = new DisplayMetrics(); //构造DispalyMetrics保存分辨率等相关信息
mInstaller = installer; //保存installer对象
// Create sub-components that provide services / data. Order here is important.
synchronized (mInstallLock) {
synchronized (mPackages) {
// Expose private service for system components to use.
LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl()); //本地服务
sUserManager = new UserManagerService(context, this,
new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages); //多用户管理服务
mComponentResolver = new ComponentResolver(sUserManager,
LocalServices.getService(PackageManagerInternal.class),
mPackages);
mPermissionManager = PermissionManagerService.create(context, //权限管理服务,创建PermissionManager对象,进行权限管理
mPackages /*externalLock*/);
mDefaultPermissionPolicy = mPermissionManager.getDefaultPermissionGrantPolicy();
//构造Settings类,保存安装包信息,清除路径不存在的孤立应用,主要涉及/data/system/目录的packages.xml,packages-backup.xml,packages.list
//packages-stopped.xml,packages-stopped-backup.xml等文件
mSettings = new Settings(Environment.getDataDirectory(), //创建Settings对象
mPermissionManager.getPermissionSettings(), mPackages);
}
}
//添加system,phone,log,nfc,bluetooth,shell,se,networkstack 这8种shareUserId到mSettings
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);
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;
}
// 构造PackageDexOptimizer及DexManager类,处理dex优化
mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
"*dexopt*");
mDexManager = new DexManager(mContext, this, mPackageDexOptimizer, installer, mInstallLock);
//ART虚拟机管理服务
mArtManagerService = new ArtManagerService(mContext, this, installer, mInstallLock);
mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
mViewCompiler = new ViewCompiler(mInstallLock, mInstaller);
//权限变化监听器
mOnPermissionChangeListeners = new OnPermissionChangeListeners(
FgThread.get().getLooper());
//获取默认分辨率
getDefaultDisplayMetrics(context, mMetrics);
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
//创建SystemConfig实例,获取系统配置信息,配置共享lib库
//在SystemConfig的构造函数中会调用readPermissions()读取/etc/permission和etc/sysconfig下面的xml文件
SystemConfig systemConfig = SystemConfig.getInstance();
mAvailableFeatures = systemConfig.getAvailableFeatures();
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
mProtectedPackages = new ProtectedPackages(mContext);
mApexManager = new ApexManager(context);
synchronized (mInstallLock) {
// writer
synchronized (mPackages) {
//启动PackageManager线程,负责apk的安装、卸载
mHandlerThread = new ServiceThread(TAG,
Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
mHandlerThread.start();
//创建PackageManager的Handler线程,循环处理外部安装相关消息。 应用handler
mHandler = new PackageHandler(mHandlerThread.getLooper());
//进程记录handler
mProcessLoggingHandler = new ProcessLoggingHandler();
//watchdog监听serviceThread是否超时: 10分钟
Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
//Instant应用注册
mInstantAppRegistry = new InstantAppRegistry(this);
//共享lib库配置
ArrayMap<String, SystemConfig.SharedLibraryEntry> libConfig
= systemConfig.getSharedLibraries();
final int builtInLibCount = libConfig.size();
for (int i = 0; i < builtInLibCount; i++) {
String name = libConfig.keyAt(i);
SystemConfig.SharedLibraryEntry entry = libConfig.valueAt(i);
addBuiltInSharedLibraryLocked(entry.filename, name);
}
// Now that we have added all the libraries, iterate again to add dependency
// information IFF their dependencies are added.
long undefinedVersion = SharedLibraryInfo.VERSION_UNDEFINED;
for (int i = 0; i < builtInLibCount; i++) {
String name = libConfig.keyAt(i);
SystemConfig.SharedLibraryEntry entry = libConfig.valueAt(i);
final int dependencyCount = entry.dependencies.length;
for (int j = 0; j < dependencyCount; j++) {
final SharedLibraryInfo dependency =
getSharedLibraryInfoLPr(entry.dependencies[j], undefinedVersion);
if (dependency != null) {
getSharedLibraryInfoLPr(name, undefinedVersion).addDependency(dependency);
}
}
}
//读取安装相关的SE linux策略
SELinuxMMAC.readInstallPolicy();
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
//返回栈加载
FallbackCategoryProvider.loadFallbacks();
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
//通过mSettings读取data/system/下的packages.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();
}
//...............省略 只是第一阶段分析
}
[接上面的mSettings.readLPw]
readLPw会扫描下面的5个文件
”data/system/packages.xml" 所有安装app信息
"data/syatem/packages-backup" 所有安装app的备份信息
"data/system/packages.list" 所有安装的app包名和所在安装目录
"data/system/packages-stopped.xml" 所有强制停止app信息
"data/system/packages-stopped-backup.xml" 所有强制停止app备份信息
以上文件分为三组:
packages.xml:PKMS扫描完目标文件夹后会创建该文件,当系统进行程序安装、卸载和更新等操作时,均会更新该文件。该文件保存了系统中与package相关的一些信息
packages.list:扫描系统中存在的所有非系统自带APK信息,里面包含app的包名,进程id,userID,和app安装目录等
packages-stopped.xml:从系统自带的设置程序中,强制停止某个应用,系统会将应用的相关信息记录到此文件中,该文件保存系统中被用户强制停止的package信息
这些目录的创建都是在Settings的构造函数中完成,得到目录后调用readLPw进行扫描
[Settings构造函数]
Settings(File dataDir, PermissionSettings permission, Object lock) {
mLock = lock;
mPermissions = permission;
mRuntimePermissionsPersistence = new RuntimePermissionPersistence(mLock);
mSystemDir = new File(dataDir, "system"); //mSystemDir指向目录 /data/system
mSystemDir.mkdirs(); //创建data/system目录
FileUtils.setPermissions(mSystemDir.toString(), //设置权限
FileUtils.S_IRWXU|FileUtils.S_IRWXG
|FileUtils.S_IROTH|FileUtils.S_IXOTH,
-1, -1);
mSettingsFilename = new File(mSystemDir, "packages.xml"); //mSettingsFilename指向 /data/system/packages.xml
mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml"); //mBackupSettingsFilename指向 data/system/packages-backup.xml
mPackageListFilename = new File(mSystemDir, "packages.list"); //mPackageListFilename指向 data/system/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
mStoppedPackagesFilename = new File(mSystemDir, "packages-stopped.xml");//mStoppedPackagesFilename指向data/system/packages-stopped.xml
mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml");
}
[readLPw函数]
boolean readLPw(@NonNull List<UserInfo> users) {
//...............................
try {
if (str == null) {
if (!mSettingsFilename.exists()) {
mReadMessages.append("No settings file found\n");
PackageManagerService.reportSettingsProblem(Log.INFO,
"No settings file; creating initial state");
// It's enough to just touch version details to create them
// with default values
findOrCreateVersion(StorageManager.UUID_PRIVATE_INTERNAL).forceCurrent();
findOrCreateVersion(StorageManager.UUID_PRIMARY_PHYSICAL).forceCurrent();
return false;
}
str = new FileInputStream(mSettingsFilename); //创建文件"读入"流,来解析packages.xml文件
}
XmlPullParser parser = Xml.newPullParser();
parser.setInput(str, StandardCharsets.UTF_8.name());
int type;
while ((type = parser.next()) != XmlPullParser.START_TAG
&& type != XmlPullParser.END_DOCUMENT) {
;
}
if (type != XmlPullParser.START_TAG) {
mReadMessages.append("No start tag found in settings file\n");
PackageManagerService.reportSettingsProblem(Log.WARN,
"No start tag found in package manager settings");
Slog.wtf(PackageManagerService.TAG,
"No start tag found in package manager settings");
return false;
}
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中的各个节点进行解析,读取permissions,shared-user等
String tagName = parser.getName();
if (tagName.equals("package")) {
readPackageLPw(parser);
} else if (tagName.equals("permissions")) {
mPermissions.readPermissions(parser);
} else if (tagName.equals("permission-trees")) {
mPermissions.readPermissionTrees(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);
} else if (tagName.equals("cleaning-package")) {
//.............................
return true;
}
[阶段2:BOOT_PROGRESS_PMS_SYSTEM_SCAN_START]
(1)从init.rc中获取环境变量 BOOTCLASSPATH和SYSTESERVERCLASSPATH
(2)对于旧版升级的情况,将安装时获取权限变更为运行时申请权限
(3)扫描system/vendor/product/odm/oem等目录的priv-app、app、overlay包
(4)清除安装时临时文件以及其它不必要信息
[PackageManagerService构造函数解析阶段2]
public PackageManagerService(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
long startTime = SystemClock.uptimeMillis(); //记录扫描开始时间
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
startTime);
final String bootClassPath = System.getenv("BOOTCLASSPATH"); //从init.rc中获取环境变量BOOTCLASSPATH和SYSTESERVERCLASSPATH
final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
//............................
File frameworkDir = new File(Environment.getRootDirectory(), "framework");/获取system/framework目录
final VersionInfo ver = mSettings.getInternalVersion();// 获取手机的版本 ,volumUuid
mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
if (mIsUpgrade) {
logCriticalInfo(Log.INFO,
"Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
}
// when upgrading from pre-M, promote system app permissions from install to runtime
//对于Aandroid M之前版本升级上来的情况,需将系统应用程序权限从安装升级到运行时
mPromoteSystemApps =
mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
// When upgrading from pre-N, we need to handle package extraction like first boot,
// as there is no profiling data available.
mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
mIsPreQUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.Q;
int preUpgradeSdkVersion = ver.sdkVersion;
// save off the names of pre-existing system packages prior to scanning; we don't
// want to automatically grant runtime permissions for new system apps
//扫描之前保存预先存在的system packages,不希望自动为新system app赋予运行时权限
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();
// 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/product_services 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);
scanDirTracedLI(new File(PRODUCT_SERVICES_OVERLAY_DIR),
mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM_DIR,
scanFlags
| SCAN_AS_SYSTEM
| SCAN_AS_PRODUCT_SERVICES,
0);
scanDirTracedLI(new File(ODM_OVERLAY_DIR),
mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM_DIR,
scanFlags
| SCAN_AS_SYSTEM
| SCAN_AS_ODM,
0);
scanDirTracedLI(new File(OEM_OVERLAY_DIR),
mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM_DIR,
scanFlags
| SCAN_AS_SYSTEM
| SCAN_AS_OEM,
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);
if (!mPackages.containsKey("android")) {
throw new IllegalStateException(
"Failed to load frameworks package; check log for warnings");
}
// 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);
// Collected privileged /product_services packages.
File privilegedProductServicesAppDir =
new File(Environment.getProductServicesDirectory(), "priv-app");
try {
privilegedProductServicesAppDir =
privilegedProductServicesAppDir.getCanonicalFile();
} catch (IOException e) {
// failed to look up canonical path, continue with original one
}
scanDirTracedLI(privilegedProductServicesAppDir,
mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM_DIR,
scanFlags
| SCAN_AS_SYSTEM
| SCAN_AS_PRODUCT_SERVICES
| SCAN_AS_PRIVILEGED,
0);
// Collect ordinary /product_services packages.
File productServicesAppDir = new File(Environment.getProductServicesDirectory(), "app");
try {
productServicesAppDir = productServicesAppDir.getCanonicalFile();
} catch (IOException e) {
// failed to look up canonical path, continue with original one
}
scanDirTracedLI(productServicesAppDir,
mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM_DIR,
scanFlags
| SCAN_AS_SYSTEM
| SCAN_AS_PRODUCT_SERVICES,
0);
// Prune any system packages that no longer exist.
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();
/*
* If this is not a system app, it can't be a 不是系统应用,不被允许disable
* disable system app.
*/
if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
continue;
}
/*
* If the package is scanned, it's not erased. 如果应用被扫描,则不允许被擦除
*/
final PackageParser.Package scannedPkg = mPackages.get(ps.name);
if (scannedPkg != null) {
/*
* If the system app is both scanned and in the
* disabled packages list, then it must have been
* added via OTA. Remove it from the currently
* scanned package so the previously user-installed
* application can be scanned.
*/
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");
// 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);
} else {
// We're expecting that the system app should remain disabled, but add
// it to expecting better to recover in case the data version cannot
// be scanned.
mExpectingBetter.put(disabledPs.name, disabledPs.codePath);
}
}
}
}
//delete tmp files 删除安装产生的临时文件
deleteTempPackageFiles();
final int cachedSystemApps = PackageParser.sCachedPackageReadCount.get();
// Remove any shared userIDs that have no associated packages 删除没有关联shared userID的package
mSettings.pruneSharedUsersLPw();
}
[阶段3:BOOT_PROGRESS_PMS_DATA_SCAN_START]
[PackageManagerService构造函数解析阶段3]
处理data目录的应用信息,及时更新,去除不必要的数据
public PackageManagerService(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
if (!mOnlyCore) {
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
SystemClock.uptimeMillis());
scanDirTracedLI(sAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
// Remove disable package settings for updated system apps that were
// removed via an OTA. If the update is no longer present, remove the
// app completely. Otherwise, revoke their system privileges.
for (int i = possiblyDeletedUpdatedSystemApps.size() - 1; i >= 0; --i) {
final String packageName = possiblyDeletedUpdatedSystemApps.get(i);
final PackageParser.Package pkg = mPackages.get(packageName);
final String msg;
// remove from the disabled system list; do this first so any future
// scans of this package are performed without this state
mSettings.removeDisabledSystemPackageLPw(packageName);
if (pkg == null) {
// should have found an update, but, we didn't; remove everything
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";
// NOTE: We don't do anything special if a stub is removed from the
// system image. But, if we were [like removing the uncompressed
// version from the /data partition], this is where it'd be done.
// remove the package from the system and re-scan it without any
// special privileges
removePackageLI(pkg, true);
try {
final File codePath = new File(pkg.applicationInfo.getCodePath());
scanPackageTracedLI(codePath, 0, scanFlags, 0, null);
} catch (PackageManagerException e) {
Slog.e(TAG, "Failed to parse updated, ex-system package: "
+ e.getMessage());
}
}
// one final check. if we still have a package setting [ie. it was
// previously scanned and known to the system], but, we don't have
// a package [ie. there was an error scanning it from the /data
// partition], completely remove the package data.
final PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps != null && mPackages.get(packageName) == null) {
removePackageDataLIF(ps, null, null, 0, false);
}
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");
final @ParseFlags int reparseFlags;
final @ScanFlags int rescanFlags;
if (FileUtils.contains(privilegedAppDir, scanFile)) {
reparseFlags =
mDefParseFlags |
PackageParser.PARSE_IS_SYSTEM_DIR;
rescanFlags =
scanFlags
| SCAN_AS_SYSTEM
| SCAN_AS_PRIVILEGED;
} else if (FileUtils.contains(systemAppDir, scanFile)) {
reparseFlags =
mDefParseFlags |
PackageParser.PARSE_IS_SYSTEM_DIR;
rescanFlags =
scanFlags
| SCAN_AS_SYSTEM;
} else if (FileUtils.contains(privilegedVendorAppDir, scanFile)
|| FileUtils.contains(privilegedOdmAppDir, scanFile)) {
reparseFlags =
mDefParseFlags |
PackageParser.PARSE_IS_SYSTEM_DIR;
rescanFlags =
scanFlags
| SCAN_AS_SYSTEM
| SCAN_AS_VENDOR
| SCAN_AS_PRIVILEGED;
} else if (FileUtils.contains(vendorAppDir, scanFile)
|| FileUtils.contains(odmAppDir, scanFile)) {
reparseFlags =
mDefParseFlags |
PackageParser.PARSE_IS_SYSTEM_DIR;
rescanFlags =
scanFlags
| SCAN_AS_SYSTEM
| SCAN_AS_VENDOR;
} else if (FileUtils.contains(oemAppDir, scanFile)) {
reparseFlags =
mDefParseFlags |
PackageParser.PARSE_IS_SYSTEM_DIR;
rescanFlags =
scanFlags
| SCAN_AS_SYSTEM
| SCAN_AS_OEM;
} else if (FileUtils.contains(privilegedProductAppDir, scanFile)) {
reparseFlags =
mDefParseFlags |
PackageParser.PARSE_IS_SYSTEM_DIR;
rescanFlags =
scanFlags
| SCAN_AS_SYSTEM
| SCAN_AS_PRODUCT
| SCAN_AS_PRIVILEGED;
} else if (FileUtils.contains(productAppDir, scanFile)) {
reparseFlags =
mDefParseFlags |
PackageParser.PARSE_IS_SYSTEM_DIR;
rescanFlags =
scanFlags
| SCAN_AS_SYSTEM
| SCAN_AS_PRODUCT;
} else if (FileUtils.contains(privilegedProductServicesAppDir, scanFile)) {
reparseFlags =
mDefParseFlags |
PackageParser.PARSE_IS_SYSTEM_DIR;
rescanFlags =
scanFlags
| SCAN_AS_SYSTEM
| SCAN_AS_PRODUCT_SERVICES
| SCAN_AS_PRIVILEGED;
} else if (FileUtils.contains(productServicesAppDir, scanFile)) {
reparseFlags =
mDefParseFlags |
PackageParser.PARSE_IS_SYSTEM_DIR;
rescanFlags =
scanFlags
| SCAN_AS_SYSTEM
| SCAN_AS_PRODUCT_SERVICES;
} else {
Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
continue;
}
mSettings.enableSystemPackageLPw(packageName);
try {
//扫描APK
scanPackageTracedLI(scanFile, reparseFlags, rescanFlags, 0, null);
} catch (PackageManagerException e) {
Slog.e(TAG, "Failed to parse original system package: "
+ e.getMessage());
}
}
}
// Uncompress and install any stubbed system applications.
// This must be done last to ensure all stubs are replaced or disabled.
installSystemStubPackages(stubSystemApps, scanFlags);//解压缩并安装任何存根系统应用程序,必须最后执行此操作以确保替换或禁用所有存根
//......................
}
}
mExpectingBetter.clear();
// Resolve the storage manager. 获取到storage manager包名
mStorageManagerPackage = getStorageManagerPackageName();
// Resolve protected action filters. Only the setup wizard is allowed to
// have a high priority filter for these actions.
mSetupWizardPackage = getSetupWizardPackageName();
mComponentResolver.fixProtectedFilterPriorities();
mSystemTextClassifierPackage = getSystemTextClassifierPackageName();
mWellbeingPackage = getWellbeingPackageName();
mDocumenterPackage = getDocumenterPackageName();
mConfiguratorPackage =
mContext.getString(R.string.config_deviceConfiguratorPackageName);
mAppPredictionServicePackage = getAppPredictionServicePackageName();
mIncidentReportApproverPackage = getIncidentReportApproverPackageName();
// Now that we know all of the shared libraries, update all clients to have
// the correct library paths. 更新客户端以确保持有正确的共享库路径
updateAllSharedLibrariesLocked(null, Collections.unmodifiableMap(mPackages));
for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
// NOTE: We ignore potential failures here during a system scan (like
// the rest of the commands above) because there's precious little we
// can do about it. A settings error is reported, though.
final List<String> changedAbiCodePath =
adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
final String codePathString = changedAbiCodePath.get(i);
try {
mInstaller.rmdex(codePathString,
getDexCodeInstructionSet(getPreferredInstructionSet()));
} catch (InstallerException ignored) {
}
}
}
// Adjust seInfo to ensure apps which share a sharedUserId are placed in the same
// SELinux domain.
setting.fixSeInfoLocked();
}
// Now that we know all the packages we are keeping,
// read and update their last usage times. 读取并更新要保留的package的上次使用时间
mPackageUsage.read(mPackages);
mCompilerStats.read();
}
[阶段4:BOOT_PROGRESS_PMS_SCAN_END]
[PackageManagerService构造函数解析阶段4]
(1)sdk版本变更,更新权限
(2)OTA升级后首次启动,清除不必要的缓存数据
(3)权限等默认项更新完后,清除相关数据
(4)更新packages.xml
public PackageManagerService(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
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);
if (sdkUpdated) {
Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
+ mSdkVersion + "; regranting permissions for internal storage");
}
mPermissionManager.updateAllPermissions(
StorageManager.UUID_PRIVATE_INTERNAL, sdkUpdated, mPackages.values(),
mPermissionCallback);
ver.sdkVersion = mSdkVersion;
// 如果是第一次启动或者来自Android M之前的版本升级,并且它是正常启动,那需要在所有一定以的用户中初始化默认的首选应用程序
if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
for (UserInfo user : sUserManager.getUsers(true)) {
mSettings.applyDefaultPreferredAppsLPw(user.id);
primeDomainVerificationsLPw(user.id);
}
}
//在boot期间更早的为用户准备storage,因为像SettingsProvider和SystemUI这样的核心应用无法等到用户去启动
final int storageFlags;
if (StorageManager.isFileEncryptedNativeOrEmulated()) {
storageFlags = StorageManager.FLAG_STORAGE_DE;
} else {
storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
}
//............................
// 如果是在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,
FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL
| Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
}
}
ver.fingerprint = Build.FINGERPRINT;
}
// Grandfather existing (installed before Q) non-system apps to hide
// 安装Android-Q前的非系统应用程序在Launcher中隐藏他们的图标
if (!onlyCore && 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);
}
}
// 仅在权限或其它默认配置更新后清除
mExistingSystemPackages.clear();
mPromoteSystemApps = false;
// 所有变更均在扫描过程中完成
ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
// 更新packages.xml
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
mSettings.writeLPr();
}
[阶段4:BOOT_PROGRESS_PMS_READY]
[PackageManagerService构造函数解析阶段5]
GC回收内存
Runtime.getRuntime().gc();
2.PKMS APK扫描
扫描APK的AndroidManifest.xml中的各个标签信息,例如"application"、"overlay"、"permission"、"uses-permission"等信息。再针对各个标签的子标签在进行扫描,例如application会扫描"activity"、"receiver"、"service"、"provider"等信息。
PKMS的构造函数中调用了scanDirTracedLI方法来扫描某个目录的apk文件。
android10.0中PKMS主要扫描以下路径的APK信息
/vendor/overlay 系统的APP类别
/product/overlay 系统的APP类别
/product_services/overlay 系统的APP类别
/odm/overlay 系统的APP类别
/oem/overlay 系统的APP类别
/system/framework 系统的APP类别
/system/priv-app 系统的APP类别
/system/app 系统的APP类别
/vendor/priv-app 系统的APP类别
/vendor/app 系统的APP类别
/odm/priv-app 系统的APP类别
/odm/app 系统的APP类别
/oem/app 系统的APP类别
/oem/priv-app 系统的APP类别
/product/priv-app 系统的APP类别
/product/app 系统的APP类别
/product_services/priv-app 系统的APP类别
/product_services/app 系统的APP类别
/product_services/priv-app 系统的APP类别
APK扫描整体流程图
3.APK安装的流程
(1)把APK的信息以IO流的形式写入到PackageInstaller.Session中
(2)调用PackageInstaller.Session的commit方法,将APK的信息交给PKMS处理
(3)进行APK的copy操作,进行安装
4.PKMS权限管理
读取/etc/sysconfig和/etc/permissions目录下的xml文件