从APK安装过程来认识PMS
Posted 丶笑看退场
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从APK安装过程来认识PMS相关的知识,希望对你有一定的参考价值。
在涉及到一个包的安装过程的时候,往往都绕不开PackageManagerService
,它是android系统中最常用的服务之一。主要负责系统中Package的管理,应用程序的安装、卸载、信息查询等工作。
开始前想先了解下什么是PMS(Android 11):
一、 PMS的启动过程
PMS也是在systemServer
中创建的,涉及到PMS的创建部分:
//SystemServer
private void startBootstrapServices(@NonNull TimingsTraceAndSlog t)
......
//创建PMS对象
try
Watchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain");
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
finally
Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain");
//PMS是不是首次启动
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();
private void startOtherServices(@NonNull TimingsTraceAndSlog t)
......
//完成dex优化
mPackageManagerService.updatePackagesIfNeeded();
//完成磁盘维护
mPackageManagerService.performFstrimIfNeeded();
//通知系统进入就绪状态
mPackageManagerService.systemReady();
在这个启动过程中,PMS的main函数
是整个的核心,现在我们就继续进行分析:
public static PackageManagerService main(Context context, Installer installer,
boolean factoryTest, boolean onlyCore)
//对PMS对象
PackageManagerService m = new PackageManagerService(injector, onlyCore, factoryTest);
t.traceEnd(); // "create package manager"
//将 package 服务注册到 ServiceManager,这是 binder 服务的常规注册流程
ServiceManager.addService("package", m);
final PackageManagerNative pmn = m.new PackageManagerNative();
ServiceManager.addService("package_native", pmn);
return m;
main方法的代码不多,主要是调用到了PMS的构造函数,而由于PMS中做了很多工作,这也就是Android启动速度慢的主要原因之一。
在其构造方法中,主要的工作是扫描Android系统中几个目标文件夹中的apk,之后建立合适的数据结构和管理如Package信息,四大组件信息,权限信息等各种信息。PKMS的工作流程可以分为五个阶段来分析:
public PackageManagerService(Injector injector, boolean onlyCore, boolean factoryTest)
......
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
SystemClock.uptimeMillis());
......
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
startTime);
......
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
SystemClock.uptimeMillis());
......
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
SystemClock.uptimeMillis());
......
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
SystemClock.uptimeMillis());
可以看到系统根据EventLog将PKMS的初始化分为以下几个阶段:
BOOT_PROGRESS_PMS_START
启动阶段BOOT_PROGRESS_PMS_SYSTEM_SCAN_START
启动阶段BOOT_PROGRESS_PMS_DATA_SCAN_START
启动阶段BOOT_PROGRESS_PMS_SCAN_END
启动阶段BOOT_PROGRESS_PMS_READY
启动阶段
1.1 BOOT_PROGRESS_PMS_START 阶段
PackageManager.disableApplicationInfoCache();
PackageManager.disablePackageInfoCache();
PackageManager.corkPackageInfoCache();
final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",
Trace.TRACE_TAG_PACKAGE_MANAGER);
mPendingBroadcasts = new PendingPackageBroadcasts();
mInjector = injector;
mInjector.bootstrap(this);
mLock = injector.getLock();
mInstallLock = injector.getInstallLock();
LockGuard.installLock(mLock, LockGuard.INDEX_PACKAGES);
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
SystemClock.uptimeMillis());
if (mSdkVersion <= 0)
Slog.w(TAG, "**** ro.build.version.sdk not set!");
mContext = injector.getContext();
mFactoryTest = factoryTest; //开机模式
mOnlyCore = onlyCore; //是否对包做dex优化
mMetrics = new DisplayMetrics(); //分辨率的配置
mInstaller = injector.getInstaller(); //保存installer对象
// Create sub-components that provide services / data. Order here is important.
t.traceBegin("createSubComponents");
// Expose private service for system components to use.
mPmInternal = new PackageManagerInternalImpl();
LocalServices.addService(PackageManagerInternal.class, mPmInternal);
mUserManager = injector.getUserManagerService();
mComponentResolver = injector.getComponentResolver();
mPermissionManager = injector.getPermissionManagerServiceInternal();
//创建setting对象
mSettings = injector.getSettings();
//权限管理服务
mPermissionManagerService = (IPermissionManager) ServiceManager.getService("permissionmgr");
mIncrementalManager =
(IncrementalManager) mContext.getSystemService(Context.INCREMENTAL_SERVICE);
PlatformCompat platformCompat = mInjector.getCompatibility();
mPackageParserCallback = new PackageParser2.Callback()
@Override
public boolean isChangeEnabled(long changeId, @NonNull ApplicationInfo appInfo)
return platformCompat.isChangeEnabled(changeId, appInfo);
@Override
public boolean hasFeature(String feature)
return PackageManagerService.this.hasSystemFeature(feature, 0);
;
// CHECKSTYLE:ON IndentationCheck
t.traceEnd();
t.traceBegin("addSharedUsers");
//添加system phone log nfc bluetooth shell se net networkstack这8种shareUserId带mSetting
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);
t.traceEnd();
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;
//DexOpt的优化
mPackageDexOptimizer = new PackageDexOptimizer(mInstaller, mInstallLock, mContext,
"*dexopt*");
mDexManager =
new DexManager(mContext, this, mPackageDexOptimizer, mInstaller, mInstallLock);
//mArt虚拟机管理服务
mArtManagerService = new ArtManagerService(mContext, this, mInstaller, mInstallLock);
mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
mViewCompiler = new ViewCompiler(mInstallLock, mInstaller);
getDefaultDisplayMetrics(mInjector.getDisplayManager(), mMetrics);
t.traceBegin("get system config");
SystemConfig systemConfig = SystemConfig.getInstance();
mAvailableFeatures = systemConfig.getAvailableFeatures();
ApplicationPackageManager.invalidateHasSystemFeatureCache();
t.traceEnd();
mProtectedPackages = new ProtectedPackages(mContext);
mApexManager = ApexManager.getInstance();
mAppsFilter = mInjector.getAppsFilter();
final List<ScanPartition> scanPartitions = new ArrayList<>();
final List<ApexManager.ActiveApexInfo> activeApexInfos = mApexManager.getActiveApexInfos();
for (int i = 0; i < activeApexInfos.size(); i++)
final ScanPartition scanPartition = resolveApexToScanPartition(activeApexInfos.get(i));
if (scanPartition != null)
scanPartitions.add(scanPartition);
mDirsToScanAsSystem = new ArrayList<>();
mDirsToScanAsSystem.addAll(SYSTEM_PARTITIONS);
mDirsToScanAsSystem.addAll(scanPartitions);
Slog.d(TAG, "Directories scanned as system partitions: " + mDirsToScanAsSystem);
// CHECKSTYLE:OFF IndentationCheck
synchronized (mInstallLock)
// writer
synchronized (mLock)
//启动packageManger线程,负责apk的安装、卸载
mHandlerThread = new ServiceThread(TAG,
Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
mHandlerThread.start();
mHandler = new PackageHandler(mHandlerThread.getLooper());
//进程记录handler
mProcessLoggingHandler = new ProcessLoggingHandler();
//watchdog监听ServiceThread是否超时,
Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
//mInstant应用注册
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);
//读取安装相关SELinux策略
SELinuxMMAC.readInstallPolicy();
t.traceBegin("loadFallbacks");
FallbackCategoryProvider.loadFallbacks();
t.traceEnd();
t.traceBegin("read user settings");
//读取并解析/data/system下的XML文件
mFirstBoot = !mSettings.readLPw(mInjector.getUserManagerInternal().getUsers(false));
t.traceEnd();
//清理代码路径不存在的孤立软件包
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();
//获取资配置
String customResolverActivityName = Resources.getSystem().getString(
R.string.config_customResolverActivity);
if (!TextUtils.isEmpty(customResolverActivityName))
mCustomResolverComponentName = ComponentName.unflattenFromString(
customResolverActivityName);
//获取扫描开始的时间
long startTime = SystemClock.uptimeMillis();
在第一阶段主要做了初始化的工作,为后续做扫描工作的准备。这里面你可能会发现一个复杂的数据结构Settings以及它的addShareUserLPw
函数。而Settiing
在里面又起了什么作用?
1.1.1 Setting
首先我们先分析addShareUserLPw
函数:
//使用了系统进程使用的用户id
mSettings.addSharedUserLPw("android.uid.system"以上是关于从APK安装过程来认识PMS的主要内容,如果未能解决你的问题,请参考以下文章