赞
踩
PackageManagerService(简称PKMS),是Aandroid系统中核心服务之一,负责应用程序的安装、卸载、信息查询等工作。
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的方法。
第一步 到 第四步:
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();
扫描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扫描整体流程图
(1)把APK的信息以IO流的形式写入到PackageInstaller.Session中
(2)调用PackageInstaller.Session的commit方法,将APK的信息交给PKMS处理
(3)进行APK的copy操作,进行安装
读取/etc/sysconfig和/etc/permissions目录下的xml文件
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。