PMS架构全景
本文是 PackageManagerService 系列的入口地图,面向已经了解 SystemServer 和 Binder 基础的读者。前置可阅读 Bootstrap服务 与 Binder调用源码地图。本文只回答四个架构问题:PMS 在何时创建并发布哪些接口,核心可变状态由谁拥有,只读查询为什么走 Computer 快照,安装/删除/权限/解析等写路径由哪些 helper 接管。启动扫描、构造函数、Settings 文件格式和安装事务都有后续专题,本文不给出“全流程”结论。
Android 17 的 PMS 已不是一个类包办所有功能的旧模型。PackageManagerService 仍是状态与编排中心,但 Binder 接口由内部 IPackageManagerImpl 承担,系统内进程访问有 PackageManagerInternal 和 PackageManagerLocal,只读查询由 ComputerEngine 处理,持久化由 Settings 管理,组件索引由 ComponentResolver 管理,权限由 PermissionManagerServiceInternal 管理,安装/删除由 helper 管理。正确阅读方式是先找 owner,再沿接口进入专题,而不是在 8849 行主类中搜索所有业务。
1. 系统位置
1.1 启动入口
源码文件:frameworks/base/services/java/com/android/server/SystemServer.java
t.traceBegin("StartPackageManagerService");
try {
Watchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain");
mPackageManagerService = PackageManagerService.main(
mSystemContext, installer, domainVerificationService,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF);
} finally {
Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain");
}
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();
t.traceEnd();SystemServer 在 bootstrap services 阶段启动 PMS,且临时暂停 Watchdog 对当前线程的监视,因为首次扫描和 Settings 恢复可能耗时很长。PMS 返回后,SystemServer 才取得 framework PackageManager 客户端;后续 systemReady() 又在其他服务启动后单独调用。因此“PMS 对象已创建”和“系统包管理已 ready”是两个状态。
1.2 ready时机
源码文件:frameworks/base/services/java/com/android/server/SystemServer.java
t.traceBegin("MakePackageManagerServiceReady");
mPackageManagerService.systemReady();
t.traceEnd();main() 完成核心状态恢复、扫描和接口发布,systemReady() 再处理依赖系统配置、默认应用、权限策略和延迟任务的逻辑。后续启动专题会详细拆分阶段;架构上只需记住 ready 是显式生命周期屏障,不是构造函数末尾的同义词。
1.3 进程边界
应用查询经过 Binder;system_server 内部消费者优先使用 Local 接口和 snapshot;写磁盘/应用数据会进入 Installer/installd。图中箭头表达主要控制流,不表示所有接口都由 PMS 自己实现。
2. 创建与发布
2.1 main编排
源码文件:frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
public static PackageManagerService main(Context context,
Installer installer,
@NonNull DomainVerificationService domainVerificationService,
boolean factoryTest) {
final PackageManagerTracedLock lock = new PackageManagerTracedLock("mLock");
final PackageManagerTracedLock installLock =
new PackageManagerTracedLock("mInstallLock");
HandlerThread backgroundThread = new ServiceThread("PackageManagerBg",
Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
backgroundThread.start();
Handler backgroundHandler = new Handler(backgroundThread.getLooper(),
BACKGROUND_HANDLER_CALLBACK);
PackageManagerServiceInjector injector = new PackageManagerServiceInjector(
context, lock, installer, installLock, new PackageAbiHelperImpl(),
backgroundHandler, SYSTEM_PARTITIONS,
/* subsystem producers omitted in this focused excerpt */);
PackageManagerService service = new PackageManagerService(
injector, factoryTest, PackagePartitions.FINGERPRINT,
Build.IS_ENG, Build.IS_USERDEBUG, Build.VERSION.SDK_INT,
Build.VERSION.INCREMENTAL, Build.VERSION.SDK_INT_FULL);main() 自己拥有锁、后台线程和 Injector 的组装;构造函数消费 Injector。省略的是源码中 ComponentResolver、PermissionManager、Settings、PackageParser2、ApexManager、PackageInstallerService 等 producer 参数,后文会按 owner 展开。这里的重要状态是依赖图在构造前已经确定。
2.2 接口发布
源码文件:frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
service.installAllowlistedSystemPackages();
IPackageManagerImpl iPackageManager = service.new IPackageManagerImpl();
ServiceManager.addService("package", iPackageManager);
final PackageManagerNative packageManagerNative = new PackageManagerNative(service);
ServiceManager.addService("package_native", packageManagerNative);
return service;Java Binder 服务名是 package,native Binder 服务名是 package_native。接口发布发生在 PMS 对象完成主要初始化之后;发布后远程调用可能到达,因此构造阶段必须先建立查询 snapshot、Settings、resolver 和 permission owner。
2.3 进程内接口
源码文件:frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
LocalServices.addService(PackageManagerInternal.class,
new PackageManagerInternalImpl());
LocalManagerRegistry.addManager(PackageManagerLocal.class,
new PackageManagerLocalImpl(this));
LocalServices.addService(TestUtilityService.class, this);
mUserManager = injector.getUserManagerService();
mComponentResolver = injector.getComponentResolver();
mPermissionManager = injector.getPermissionManagerServiceInternal();
mSettings = injector.getSettings();PackageManagerInternal 是旧式 LocalServices 接口;PackageManagerLocal 提供 snapshot-scoped 新接口;TestUtilityService 只服务测试。它们与 Binder 服务共享同一 PMS 状态 owner,但调用者身份、可见性过滤和生命周期契约不同。
3. 状态所有权
3.1 三把锁
源码文件:frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
/**
* mLock guards parsed package details and related in-memory state.
* mInstallLock guards installd access and slow disk operations.
* mSnapshotLock only guards cached snapshot fields and invalidation state.
*
* Never acquire mInstallLock or mSnapshotLock while holding mLock.
* It is safe to acquire mLock momentarily while holding either outer lock.
*
* fooLI(): mInstallLock held
* fooLIF(): mInstallLock held and package frozen
* fooLPr(): mLock held for reading
* fooLPw(): mLock held for writing
*/
public class PackageManagerService implements PackageSender, TestUtilityService {注释本身就是锁协议。mLock 是高竞争、短持有的内存状态锁;mInstallLock 序列化 installd 重操作;mSnapshotLock 只允许在 snapshotComputer() 使用。方法后缀是静态的锁文档,不是编译器自动加锁。
3.2 核心状态
源码文件:frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
@Watched
@GuardedBy("mLock")
final WatchedArrayMap<String, AndroidPackage> mPackages = new WatchedArrayMap<>();
@Watched
@GuardedBy("mLock")
final Settings mSettings;
@GuardedBy("mLock")
final WatchedArrayMap<String, Integer> mFrozenPackages = new WatchedArrayMap<>();
final PermissionManagerServiceInternal mPermissionManager;
final ComponentResolver mComponentResolver;
private final DeletePackageHelper mDeletePackageHelper;
@NonNull private final InstallPackageHelper mInstallPackageHelper;mPackages 保存解析后的 AndroidPackage,Settings 保存安装状态和 per-user 状态,frozen map 阻止更新中的包被启动。PermissionManager 和 ComponentResolver 各自拥有权限/组件索引逻辑;安装/删除 helper 消费并修改这些状态。PMS 是编排 owner,而不是所有数据结构的唯一实现类。
3.3 owner图
4. 查询架构
4.1 Binder代理层
源码文件:frameworks/base/services/core/java/com/android/server/pm/IPackageManagerBase.java
public abstract class IPackageManagerBase extends IPackageManager.Stub {
@NonNull
private final PackageManagerService mService;
protected Computer snapshot() {
return mService.snapshotComputer();
}
@Override
public final boolean activitySupportsIntentAsUser(ComponentName component,
Intent intent, String resolvedType, int userId) {
return snapshot().activitySupportsIntentAsUser(
mResolveComponentName, component, intent, resolvedType, userId);
}
}IPackageManagerBase 实现大量“取 snapshot 后直接代理”的 Binder 方法,避免每个 API 重复锁和状态获取。复杂写操作仍由 IPackageManagerImpl 覆盖并进入 PMS/helper。PMS 本身不继承 IPackageManager.Stub,这是阅读 Android 17 源码时必须先修正的旧模型。
4.2 snapshot版本
源码文件:frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
public Computer snapshotComputer(boolean allowLiveComputer) {
final boolean isHoldingPackageLock = Thread.holdsLock(mLock);
if (allowLiveComputer && isHoldingPackageLock) {
// A writer holding mLock must observe its own not-yet-invalidated state.
return mLiveComputer;
}
final Computer oldSnapshot = sSnapshot.get();
final int pendingVersion = sSnapshotPendingVersion.get();
if (oldSnapshot != null && oldSnapshot.getVersion() == pendingVersion) {
return oldSnapshot.use();
}
synchronized (mSnapshotLock) {
Computer rebuildSnapshot = sSnapshot.get();
int rebuildVersion = sSnapshotPendingVersion.get();
if (rebuildSnapshot != null
&& rebuildSnapshot.getVersion() == rebuildVersion) {
return rebuildSnapshot.use();
}
synchronized (mLock) {
// Recheck version before copying watched state.
final Computer newSnapshot = rebuildSnapshot(
rebuildSnapshot, sSnapshotPendingVersion.get());
sSnapshot.set(newSnapshot);
return newSnapshot.use();
}
}
}查询先比较 cached snapshot version 与 pending invalidation version;有效则无须获取 mLock。重建路径遵守 mSnapshotLock → mLock,且进入每层后重新检查版本,避免多个等待线程重复复制。持有 mLock 的 writer 返回 live computer,确保看到自己尚未发布的修改。
4.3 snapshot内容
源码文件:frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
class Snapshot {
public final Settings settings;
public final WatchedArrayMap<String, AndroidPackage> packages;
public final ComponentResolverApi componentResolver;
public final AppsFilterSnapshot appsFilter;
public final InstantAppRegistry instantAppRegistry;
public final WatchedArrayMap<String, Integer> frozenPackages;
Snapshot(int type) {
if (type == Snapshot.SNAPPED) {
settings = mSettings.snapshot();
packages = mPackagesSnapshot.snapshot();
componentResolver = mComponentResolver.snapshot();
appsFilter = mAppsFilter.snapshot();
instantAppRegistry = mInstantAppRegistry.snapshot();
frozenPackages = mFrozenPackagesSnapshot.snapshot();
} else if (type == Snapshot.LIVE) {
settings = mSettings;
packages = mPackages;
componentResolver = mComponentResolver;
appsFilter = mAppsFilter;
instantAppRegistry = mInstantAppRegistry;
frozenPackages = mFrozenPackages;
} else {
throw new IllegalArgumentException();
}
}
}snapshot 不只是 mPackages 的浅拷贝,它组合 Settings、resolver、apps visibility、instant app、frozen state 等多个 watched owner。所有只读查询必须在同一版本快照上组合结果,否则包元数据、per-user state 和 component index 可能来自不同时间点。
4.4 Computer自包含
源码文件:frameworks/base/services/core/java/com/android/server/pm/ComputerEngine.java
/**
* This class contains the implementation of the Computer functions.
* It is entirely self-contained - it has no implicit access to
* PackageManagerService.
*/
public class ComputerEngine implements Computer {
protected class Settings {
@NonNull
private final com.android.server.pm.Settings mSettings;
@Nullable
public PackageStateInternal getPackage(@NonNull String packageName) {
return mSettings.getPackageLPr(packageName);
}
public boolean isEnabledAndMatch(ComponentInfo componentInfo,
int flags, int userId) {
PackageStateInternal pkgState = getPackage(componentInfo.packageName);
if (pkgState == null) return false;
return PackageUserStateUtils.isMatch(
pkgState.getUserStateOrDefault(userId), componentInfo, flags);
}
}
}ComputerEngine 只能通过构造时取得的 snapshot state 工作,不能偷偷回读 live PMS。这一约束让查询结果可复现,也使测试可以单独构造 Computer。内部 Settings wrapper 仍提供 package/per-user state,但它引用的是 snapshot 或 live 版本对应的 Settings。
5. 依赖注入
5.1 Singleton语义
源码文件:frameworks/base/services/core/java/com/android/server/pm/PackageManagerServiceInjector.java
static class Singleton<T> {
private final Producer<T> mProducer;
private volatile T mInstance = null;
Singleton(Producer<T> producer) {
mProducer = producer;
}
T get(PackageManagerServiceInjector injector,
PackageManagerService packageManagerService) {
if (mInstance == null) {
mInstance = mProducer.produce(injector, packageManagerService);
}
return mInstance;
}
}Injector 把实例构造与 PMS 主类解耦,并让测试替换 producer。getter 每次返回同一实例是类注释的契约;它不是通用线程安全 DI 容器,主要在 PMS 单线程构造阶段初始化。改变 producer 顺序可能破坏依赖初始化。
5.2 子系统producer
源码文件:frameworks/base/services/core/java/com/android/server/pm/PackageManagerServiceInjector.java
private final Singleton<ComponentResolver> mComponentResolverProducer;
private final Singleton<PermissionManagerServiceInternal>
mPermissionManagerServiceProducer;
private final Singleton<UserManagerService> mUserManagerProducer;
private final Singleton<Settings> mSettingsProducer;
private final Singleton<AppsFilterImpl> mAppsFilterProducer;
private final Singleton<ApexManager> mApexManagerProducer;
private final Producer<PackageParser2> mScanningCachingPackageParserProducer;
private final Producer<PackageParser2> mScanningPackageParserProducer;
private final SingletonWithArgument<PackageInstallerService, ComponentName>
mPackageInstallerServiceProducer;有状态共享服务用 Singleton,PackageParser2 使用 Producer 按阶段创建,PackageInstallerService 需要 verifier package 参数所以使用带参数 singleton。Injector 字段就是 PMS 架构依赖表,比主类 import 列表更适合判断谁拥有某项功能。
6. 写路径
6.1 Helper分工
| 领域 | 主要 owner | PMS 的角色 | 后续专题 |
|---|---|---|---|
| 启动扫描 | InitAppsHelper、PackageParser2 | 提供状态与提交入口 | PMS016 起 |
| 安装 | InstallingSession、InstallPackageHelper | 冻结、锁、提交、广播 | PMS043 起 |
| 删除 | DeletePackageHelper、RemovePackageHelper | 状态变更和回调 | PMS061 起 |
| 权限 | PermissionManagerServiceInternal | 调用、同步 package state | PMS073 起 |
| Intent | ComputerEngine、ComponentResolver | snapshot 与接口发布 | PMS091 起 |
| 持久化 | Settings、PackageSetting | 锁内更新和调度写盘 | PMS004 起 |
| Dex/ART | DexOptHelper、ART Service | 调度与 package metadata | PMS113 起 |
| APEX/staged | ApexManager、StagingManager | package/session 统一视图 | PMS133 起 |
6.2 安装helper
源码文件:frameworks/base/services/core/java/com/android/server/pm/InstallPackageHelper.java
final class InstallPackageHelper {
private final PackageManagerService mPm;
private final AppDataHelper mAppDataHelper;
private final BroadcastHelper mBroadcastHelper;
private final RemovePackageHelper mRemovePackageHelper;
private final DeletePackageHelper mDeletePackageHelper;
private final IncrementalManager mIncrementalManager;
private final ApexManager mApexManager;
private final PackageAbiHelper mPackageAbiHelper;
private final SharedLibrariesImpl mSharedLibraries;
private final PackageManagerServiceInjector mInjector;
private final Object mInternalLock = new Object();
@GuardedBy("mInternalLock")
private PowerManager.WakeLock mInstallingWakeLock;
private final Set<String> mInstallingPackages;
}安装 helper 本身又协调 app data、删除旧版本、增量文件系统、APEX、ABI、共享库和广播。它保留 PMS 引用说明重构仍未完全解耦,但业务 owner 已从主类拆出。安装中的 wakelock/安装包集合由 helper 内部锁保护,不等同于 PMS mInstallLock。
6.3 写入阶段
写路径通常遵循“慢磁盘操作在 mInstallLock 下完成,短内存提交在 mLock 下完成,提交后 invalidates snapshot,再异步广播/写盘”。具体事务会因安装、卸载、user state 变化而不同;架构篇不把它简化成一个万能流程,但下面的 owner 顺序可作为阅读导航。
7. 接口表面
7.1 Java Binder
源码文件:frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
public class IPackageManagerImpl extends IPackageManagerBase {
public IPackageManagerImpl() {
super(PackageManagerService.this, mContext, mDexOptHelper,
mModuleInfoProvider, mPreferredActivityHelper,
mResolveIntentHelper, mDomainVerificationManager,
mDomainVerificationConnection, mInstallerService,
mPackageProperty, mResolveComponentName,
mInstantAppResolverSettingsComponent,
mServicesExtensionPackageName,
mSharedSystemSharedLibraryPackageName);
}
@Override
public void clearApplicationUserData(String packageName,
IPackageDataObserver observer, int userId,
boolean restorePregrantedPermissions) {
clearApplicationUserData_enforcePermission();
final Computer snapshot = snapshotComputer();
snapshot.enforceCrossUserPermission(Binder.getCallingUid(), userId,
true, false, "clear application data");
// The real implementation continues with protected-package checks,
// package freezing, a posted Runnable, AppDataHelper, and observer callbacks.
}
}简单查询继承自 Base 并直接 snapshot;涉及权限、跨用户、冻结、异步任务的写 API 在 Impl 覆盖。代码中的 task 参数为聚焦摘录,真实实现创建 Runnable、调用 AppDataHelper 并回调 observer。Binder thread 不应直接执行所有慢 I/O。
7.2 Native Binder
源码文件:frameworks/base/services/core/java/com/android/server/pm/PackageManagerNative.java
final class PackageManagerNative extends IPackageManagerNative.Stub {
private final PackageManagerService mPm;
@Override
public String[] getNamesForUids(int[] uids) {
String[] names = mPm.snapshotComputer().getNamesForUids(uids);
String[] results = names != null ? names : new String[uids.length];
for (int i = results.length - 1; i >= 0; --i) {
if (results[i] == null) results[i] = "";
}
return results;
}
@Override
public int getPackageUid(String packageName, long flags, int userId) {
return mPm.snapshotComputer().getPackageUid(packageName, flags, userId);
}
}package_native 面向 native consumers,接口集合更窄,仍复用 Computer 快照。它对 null 名称转换为空字符串,是为了 native Binder 可解析的返回契约;不能把 Java IPackageManager 的全部 API 外推到 native 服务。
7.3 Local接口
源码文件:frameworks/base/services/core/java/com/android/server/pm/PackageManagerLocal.java
/** In-process API for server side PackageManager infrastructure. */
public interface PackageManagerLocal {
@NonNull UnfilteredSnapshot withUnfilteredSnapshot();
@NonNull FilteredSnapshot withFilteredSnapshot();
@NonNull FilteredSnapshot withFilteredSnapshot(
int callingUid, @NonNull UserHandle user);
}Local snapshot 是可关闭的 scope object,调用者必须短期使用并及时 close。FilteredSnapshot 应用包可见性、权限和跨用户过滤;UnfilteredSnapshot 代表 system owner 视角。Local API 不是“绕过 Binder 就自动拥有全部权限”。
8. 外部协作
8.1 Installer链路
PMS 通过 Installer 系统服务包装对 installd 的 Binder 调用,处理 app data、dex、profile、删除等磁盘状态。mInstallLock 的注释明确说明 installd 是 slow/single-threaded 资源;因此任何调用链进入 Installer 前都应检查锁顺序和是否冻结 package。
8.2 权限与AppOps
PMS 保存 package、UID、签名和声明信息,PermissionManager 拥有权限定义/授予状态,AppOps 负责运行时 operation mode。checkPermission 在 PMS 中委托给 mPermissionManager;权限文章会分别解释 package state 和 uid permission state,架构篇只划分 owner。
8.3 UserManager与AMS
UserManager 提供用户列表与类型、per-user install state;AMS/ATMS 消费 package query 并在更新时配合停止进程。PMS 不能在持有高竞争 mLock 时等待 app process 退出,否则可能形成跨服务锁等待;代码中多处先取 snapshot、退出锁,再调用 ActivityManagerInternal。
8.4 APEX与ART
ApexManager 为系统模块提供 active/package 信息,StagingManager/PackageInstaller 处理 staged session;DexOptHelper 与 ART Service 处理编译。PMS 维护统一 package view 和安装生命周期,但不实现 dm-verity、APEX mount 或 dex2oat 编译器本身。
9. 失败边界
9.1 启动失败
| 阶段 | owner | 常见结果 |
|---|---|---|
| Injector/subcomponent 创建 | PMS main/constructor | system_server crash,服务未发布 |
| Settings 读取 | Settings/ResilientAtomicFile | backup/fallback/reconcile 或 fatal inconsistency |
| system/data 扫描 | InitAppsHelper/PackageParser2 | 单包 parse/scan error、禁用/移除或启动失败 |
| permission/component 重建 | PermissionManager/Resolver | 查询结果或授权状态不完整 |
| Binder 发布前 | PMS main | app 无法取得 package service |
| systemReady | PMS + other services | 默认应用、权限、用户状态延迟失败 |
9.2 查询失败
查询返回 null/空列表可能来自包不存在、用户未安装、component disabled、AppsFilter 可见性、跨用户权限或 instant app 过滤,不只来自 mPackages 没有记录。必须保留 callingUid、userId、flags 和 snapshot version,才能复现查询。
9.3 写入失败
安装/删除失败时区分磁盘阶段与内存提交阶段:Installer errno、签名/解析失败、包冻结/进程停止失败、Settings 写入失败、observer 死亡、广播延迟分别属于不同 owner。后续流程篇会追踪 rollback;架构篇不能用一个 PackageManagerException 概括所有清理路径。
10. 测试证据
10.1 Snapshot隔离
源码文件:frameworks/base/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/PackageManagerLocalSnapshotTest.kt
@Test
fun unfiltered() {
val snapshot = pmLocal().withUnfilteredSnapshot()
snapshot.use {
val packageStates = it.packageStates
assertFailsWith<UnsupportedOperationException> {
it.packageStates.clear()
}
assertThat(it.packageStates).isSameInstanceAs(packageStates)
val filteredOne = it.filtered(1000, UserHandle.getUserHandleForUid(1000))
val filteredTwo = it.filtered(1000, UserHandle.getUserHandleForUid(1000))
assertThat(filteredOne).isNotSameInstanceAs(filteredTwo)
filteredOne.close()
assertThat(filteredTwo.getPackageState("com.package.all")).isNotNull()
}
assertFailsWith<IllegalStateException> { snapshot.packageStates }
}输入是包含全局、user 0、user 10 三个 package state 的 mock Computer。断言覆盖 map 不可修改、同一 snapshot 返回同一 map、同 caller 的 filtered siblings 仍相互隔离、关闭一个 child 不影响另一个、parent 关闭后访问失败。它证明 snapshot scope 和过滤生命周期,不证明真实扫描或 Binder 权限。
10.2 安全测试范围
源码文件:frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
runtest -c android.content.pm.PackageManagerTests frameworks-core
cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCasesPMS 类注释要求核心修改运行 framework package manager tests 与 CTS app security host tests。单元测试适合数据结构和 helper,CTS 覆盖跨包可见性、签名、权限等产品安全契约;两者都不能替代安装/OTA/多用户设备场景回归。
11. 阅读路由
11.1 按需求停止
| 需求 | 下一篇/专题 | 本篇停止点 |
|---|---|---|
| PMS 为何在 bootstrap 启动 | PMS002 | 已找到 SystemServer→main |
| 构造阶段具体顺序 | PMS003 | 已知道 Injector/subcomponents owner |
| packages.xml 恢复 | PMS004 | 已定位 Settings |
| package/per-user state 字段 | PMS005 | 已定位 PackageSetting/Settings |
| Binder API 分类 | PMS007 | 已定位 IPackageManagerBase/Impl |
| 查询快照/并发 | PMS009/PMS010/PMS012 | 已定位 Computer 与三把锁 |
| 启动扫描 | PMS016 起 | 已定位 InitAppsHelper/Parser |
| 安装/卸载 | PMS043/PMS061 起 | 已定位 Helper/Installer |
| 权限/Intent | PMS073/PMS091 起 | 已定位 PermissionManager/Resolver |
11.2 源码导航
frameworks/base/services/java/com/android/server/SystemServer.java:PMS main 与 systemReady 生命周期。PackageManagerService.java:核心状态、接口发布、snapshot 和编排。PackageManagerServiceInjector.java:子系统 producer 和测试替换边界。IPackageManagerBase.java、PMSIPackageManagerImpl:Java Binder 查询/写入分工。PackageManagerNative.java:native Binder 查询接口。PackageManagerLocal.java、local/PackageManagerLocalImpl.java:进程内 scoped snapshot API。Computer.java、ComputerEngine.java:只读查询引擎。Settings.java、PackageSetting.java:持久化和 per-user package state。resolution/ComponentResolver.java:组件/IntentFilter 索引。InstallPackageHelper.java、DeletePackageHelper.java:主要写路径 owner。permission/PermissionManagerService.java:权限子系统。frameworks/base/services/tests/PackageManagerServiceTests/:unit/server/host 反向证据。
12. 读码练习
选择一个 getPackageInfo() 查询和一个安装请求,分别回答:
- 调用从 Binder/Local 哪个接口进入,何时取得 Computer?
- 查询组合了 Settings、mPackages、AppsFilter、user state 中哪些 owner?
- 写路径何时持有
mInstallLock,何时短暂进入mLock? - 哪个状态变更会使 snapshot version 失效,查询线程如何避免重复重建?
- Installer、PermissionManager、ComponentResolver、Settings 各自消费或产生什么结果?
- 失败发生在磁盘操作、内存提交、持久化、回调还是可见性过滤时,调用者看到什么?
能回答这些问题后,再进入启动、扫描、解析、安装等专题;否则直接阅读单个长函数,很容易把 PMS 编排层和子系统 owner 混为一谈。
