Skip to content

PMS架构全景

从 SystemServer 启动、Binder 与进程内接口、Computer 快照、Settings 状态和安装辅助类建立 Android PMS 源码地图。

基于android-17.0.0_r1
AndroidPackageManagerServicePMSsystem_server架构源码阅读

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

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

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

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

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

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

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

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

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

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

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

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

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

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分工 ​

领域主要 ownerPMS 的角色后续专题
启动扫描InitAppsHelper、PackageParser2提供状态与提交入口PMS016 起
安装InstallingSession、InstallPackageHelper冻结、锁、提交、广播PMS043 起
删除DeletePackageHelper、RemovePackageHelper状态变更和回调PMS061 起
权限PermissionManagerServiceInternal调用、同步 package statePMS073 起
IntentComputerEngine、ComponentResolversnapshot 与接口发布PMS091 起
持久化Settings、PackageSetting锁内更新和调度写盘PMS004 起
Dex/ARTDexOptHelper、ART Service调度与 package metadataPMS113 起
APEX/stagedApexManager、StagingManagerpackage/session 统一视图PMS133 起

6.2 安装helper ​

源码文件:frameworks/base/services/core/java/com/android/server/pm/InstallPackageHelper.java

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

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

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

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/constructorsystem_server crash,服务未发布
Settings 读取Settings/ResilientAtomicFilebackup/fallback/reconcile 或 fatal inconsistency
system/data 扫描InitAppsHelper/PackageParser2单包 parse/scan error、禁用/移除或启动失败
permission/component 重建PermissionManager/Resolver查询结果或授权状态不完整
Binder 发布前PMS mainapp 无法取得 package service
systemReadyPMS + 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

kotlin
@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

text
runtest -c android.content.pm.PackageManagerTests frameworks-core
cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases

PMS 类注释要求核心修改运行 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
权限/IntentPMS073/PMS091 起已定位 PermissionManager/Resolver

11.2 源码导航 ​

  1. frameworks/base/services/java/com/android/server/SystemServer.java:PMS main 与 systemReady 生命周期。
  2. PackageManagerService.java:核心状态、接口发布、snapshot 和编排。
  3. PackageManagerServiceInjector.java:子系统 producer 和测试替换边界。
  4. IPackageManagerBase.java、PMS IPackageManagerImpl:Java Binder 查询/写入分工。
  5. PackageManagerNative.java:native Binder 查询接口。
  6. PackageManagerLocal.java、local/PackageManagerLocalImpl.java:进程内 scoped snapshot API。
  7. Computer.java、ComputerEngine.java:只读查询引擎。
  8. Settings.java、PackageSetting.java:持久化和 per-user package state。
  9. resolution/ComponentResolver.java:组件/IntentFilter 索引。
  10. InstallPackageHelper.java、DeletePackageHelper.java:主要写路径 owner。
  11. permission/PermissionManagerService.java:权限子系统。
  12. frameworks/base/services/tests/PackageManagerServiceTests/:unit/server/host 反向证据。

12. 读码练习 ​

选择一个 getPackageInfo() 查询和一个安装请求,分别回答:

  1. 调用从 Binder/Local 哪个接口进入,何时取得 Computer?
  2. 查询组合了 Settings、mPackages、AppsFilter、user state 中哪些 owner?
  3. 写路径何时持有 mInstallLock,何时短暂进入 mLock?
  4. 哪个状态变更会使 snapshot version 失效,查询线程如何避免重复重建?
  5. Installer、PermissionManager、ComponentResolver、Settings 各自消费或产生什么结果?
  6. 失败发生在磁盘操作、内存提交、持久化、回调还是可见性过滤时,调用者看到什么?

能回答这些问题后,再进入启动、扫描、解析、安装等专题;否则直接阅读单个长函数,很容易把 PMS 编排层和子系统 owner 混为一谈。