PackageManagerService的启动过程——Android 12(一)

目录

1. PackageManagerService概述

1.1 PackageManagerService职责

1.2 PKMS内部三把重要的锁

1.3 PKMS在SystemServer中全部业务

2. PKMS的启动

2.1 SystemServer.startBootstrapServices()

2.2 PackageManagerService.main()

2.3 PackageManagerService构造函数

2.3.1 PKMS构造函数BOOT_PROGRESS_PMS_START阶段

2.3.2 PKMS构造函数BOOT_PROGRESS_PMS_SYSTEM_SCAN_START 阶段

2.3.3 PKMS构造函数BOOT_PROGRESS_PMS_DATA_SCAN 阶段

2.3.4 PKMS构造函数BOOT_PROGRESS_PMS_READY阶段

2.4 PKMS.installWhitelistedSystemPackages()

2.5 PackageManagerNative类


1. PackageManagerService概述

1.1 PackageManagerService职责

PackageManagerService(简称PKMS)的官方解释:随时随地跟踪所有的APKs。主要职责分为:

  • 启动过程中扫描App所有安装目录,解析其中的Apk将相关信息加载到PKMS的数据结构中,同时同步到/data/system/packages.xml中;注册APK信息和其四大组件到PKMS中。
  • 负责App的安装和卸载。
  • 对外提供接口查询App相关信息。

1.2 PKMS内部三把重要的锁

mLock:用来守护内存中解析的package详情和其他相关状态。这是一个细粒度的锁,只应该短暂持有,因为它是系统中竞争最激烈的锁之一。

mInstallLock :用来守护所有对installd的访问,其操作通常涉及到磁盘上应用数据繁重的读写操作。由于installd是单线程,它的操作经常会很慢,因此在持有该锁的情况下不能再获取该锁。相反,在持有该锁时如果短暂获取mLock锁时安全的。(关于installd请参考)

mSnapshotLock :  用来守护对两个snapshot字段的访问:snapshot本身和snapshot 失效标志。当持有mLock锁时不能获取该锁,相反,在持有mSnapshotLock锁时暂时获取mLock锁是安全的。

final PackageManagerTracedLock mLock;
final Object mInstallLock;
private final Object mSnapshotLock = new Object();

1.3 PKMS在SystemServer中全部业务

PKMS在SystemServer.startBootstrapService()中调用PKMS.main()启动PKMS;如果设备没加密,则管理A/B OTA dexopting;

在SystemServer.startOtherServices()中,如果设备没加密,调用PKMS.updatePackagesIfNeeded()完成dex优化;调用PKMS.performFstrimIfNeeded()完成磁盘维护;最后调用PKMS.systemReady()服务启动就绪;最后调用PKMS.waitForAppDataPrepared()等待所有package准备就绪,整个过程如下图所示:

 主要涉及的文件有:

/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java,代码参考地址:PackageManagerService.java
/frameworks/native/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl,代码参考地址:IPackageManagerNative.aidl

/frameworks/base/core/java/android/content/pm/IPackageManager.aidl,代码参考地址:IPackageManager.aidl


2. PKMS的启动

2.1 SystemServer.startBootstrapServices()

public final class SystemServer implements Dumpable {
    private PackageManagerService mPackageManagerService;
    private PackageMamager mPackageManager;     
    private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
        t.traceBegin("StartPackageManagerService");
        try {
            Watchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain");
            mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                    domainVerificationService, mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF,
                    mOnlyCore);
        } finally {
            Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain");
        }
        //既然package manager已经启动.注册dex load report来捕获system server加载的dex文件,
        //这些dex文件会被BackgroundDexOptService优化.                        
        SystemServerDexLoadReporter.configureSystemServerDexReporter(mPackageManagerService);

        mFirstBoot = mPackageManagerService.isFirstBoot();
        mPackageManager = mSystemContext.getPackageManager();
        t.traceEnd();
        ...
    }
}

2.2 PackageManagerService.main()

如果设备加密,则运行core应用,即onlyCore=true,主要工作有:

  • 创建Injector实例
  • 创建PKMS实例,安装白名单
  • 把PKMS注册到ServiceManager
  • 创建PKMNative实例,并注册到ServiceManager中
public class PackageManagerService extends IPackageManager.Stub
        implements PackageSender, TestUtilityService {
    public static PackageManagerService main(Context context, Installer installer,
            @NonNull DomainVerificationService domainVerificationService, boolean factoryTest,
            boolean onlyCore) {
        ...
        //1.创建PKMS实例
        PackageManagerService m = new PackageManagerService(injector, onlyCore, factoryTest,
                Build.FINGERPRINT, Build.IS_ENG, Build.IS_USERDEBUG, Build.VERSION.SDK_INT,
                Build.VERSION.INCREMENTAL);
        ...
        //2.安装白名单
        m.installWhitelistedSystemPackages();
        //3.把PKMS注册到ServiceManager中
        ServiceManager.addService("package", m);
        //创建PKMNative实例
        final PackageManagerNative pmn = m.new PackageManagerNative();
        3.把PKMNative注册到ServiceManager中
        ServiceManager.addService("package_native", pmn);
        return m;
    }
}

2.3 PackageManagerService构造函数

PKMS的构造函数非常复杂,包含四个过程:

  • 第一阶段:BOOT_PROGRESS_PMS_START,初始化PKMS中重要的成员变量,其中包括构建Settings和SystemConfig对象。
  • 第二阶段:BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,扫描系统App目录
  • 第三阶段:该阶段包含两部分:BOOT_PROGRESS_PMS_DATA_START和BOOT_PROGRESS_PMS_DATA_END,START阶段负责扫描Data分区,END阶段扫描结束做相关收尾工作,其中包含清除缓存和更新Settings。
  • 第四阶段:BOOT_PROGRESS_PMS_READY,PMS准备就绪阶段,管理安装会话服务和请求GC。

2.3.1 PKMS构造函数BOOT_PROGRESS_PMS_START阶段

public class PackageManagerService extends IPackageManager.Stub
        implements PackageSender, TestUtilityService {
    private final PackageManagerInternal mPmInternal;
    private final ComponentResolver mComponentResolver;
    private final PermissionManagerServiceInternal mPermissionManager;
    final Settings mSettings;
    private final PackageDexOptimizer mPackageDexOptimizer;
    private final DexManager mDexManager;
    public PackageManagerService(Injector injector, boolean onlyCore, boolean factoryTest,
            final String buildFingerprint, final boolean isEngBuild,
            final boolean isUserDebugBuild, final int sdkVersion, final String incrementalVersion) {
        //1.从Injector中初始化获取锁对象
        mLock = injector.getLock();
        mInstallLock = injector.getInstallLock();
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, SystemClock.uptimeMillis());
        //2.保存Display分辨率相关对象
        mMetrics = injector.getDisplayMetrics();
        //3.与apk安装和dex优化相关的对象
        mInstaller = injector.getInstaller();
        //4.暴露PKMS本地服务给系统使用
        mPmInternal = new PackageManagerInternalImpl();
        //5.用户管理对象
        mUserManager = injector.getUserManagerService();
        //6.组件解析对象
        mComponentResolver = injector.getComponentResolver();
        //7.权限管理对象
        mPermissionManager = injector.getPermissionManagerServiceInternal();
        //8.设置相关对象
        mSettings = injector.getSettings();
        ...
        t.traceBegin("addSharedUsers");
        //9.添加system/phone/log/nfc/bluetooth/shell/se/networkstack/uwb这9种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);
        ...
        t.traceEnd();
        //Dex优化相关
        mPackageDexOptimizer = injector.getPackageDexOptimizer();
        mDexManager = injector.getDexManager();
        //ART虚拟机管理
        mArtManagerService = injector.getArtManagerService();
        //获取默认分辨率
        mContext.getSystemService(DisplayManager.class)
                .getDisplay(Display.DEFAULT_DISPLAY).getMetrics(mMetrics);
        //创建SystemConfig实例,获取设备可用的features.
        SystemConfig systemConfig = injector.getSystemConfig();
        mAvailableFeatures = systemConfig.getAvailableFeatures();
        //data/app目录
        mAppInstallDir = new File(Environment.getDataDirectory(), "app");
        //获取SystemConfig的共享库
        ArrayMap<String, SystemConfig.SharedLibraryEntry> libConfig = systemConfig.getSharedLibraries();
        SELinuxMMAC.readInstallPolicy();
        mPermissionManager.readLegacyPermissionsTEMP(mSettings.mPermissions);
        mFirstBoot = !mSettings.readLPw(mInjector.getUserManagerInternal().getUsers(true, false, true);
        mPermissionManager.readLegacyPermissionsTEMP(mSettings.mPermissions);
        ...
    }
}

2.3.2 PKMS构造函数BOOT_PROGRESS_PMS_SYSTEM_SCAN_START 阶段

这个阶段主要工作:

  • 获取环境变量和/system/framework目录
  • 扫描system/vendor/product/odm/oem等目录的priv-app、app、overlay包;
  • 清除安装时临时文件以及其他不必要的信息
public class PackageManagerService extends IPackageManager.Stub
        implements PackageSender, TestUtilityService {
    public PackageManagerService(Injector injector, boolean onlyCore, boolean factoryTest,
            final String buildFingerprint, final boolean isEngBuild,
            final boolean isUserDebugBuild, final int sdkVersion, final String incrementalVersion) {
        ...
        synchronized (mInstallLock) {
        synchronized (mLock) {
            ...
            long startTime = SystemClock.uptimeMillis();
            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, startTime);
            //获取环境变量
            final String bootClassPath = System.getenv("BOOTCLASSPATH");
            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
            //system/framework目录
            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
            final VersionInfo ver = mSettings.getInternalVersion();      
            //接下来就是扫描system/vendor/product/odm/oem等目录的priv-app、app、overlay包;
            //清除安装时临时文件以及其他不必要的信息
            ...      
        }
        }
        ...
    }
}

系统App安装目录常见的有:

/system/app系统app,不能被普通用户卸载的app
/system/priv-app系统核心app,权限更大
/vendor/appOEM/ODM厂商预置的系统app
/vendor/priv-appOEM/ODM厂商预置的系统app

普通用户自己安装的App在/data/app目录下。 

2.3.3 PKMS构造函数BOOT_PROGRESS_PMS_DATA_SCAN 阶段

该阶段包含START和END,在START阶段:扫描Data分区(它用来存储所有用户的个人数据和配置文件),更新和去除不必要的数据。在END阶段根据是否是OTA升级后的首次启动,清除缓存数据,把Settings的内容保存到package.xml中。

public class PackageManagerService extends IPackageManager.Stub
        implements PackageSender, TestUtilityService {
    public PackageManagerService(Injector injector, boolean onlyCore, boolean factoryTest,
            final String buildFingerprint, final boolean isEngBuild,
            final boolean isUserDebugBuild, final int sdkVersion, final String incrementalVersion) {
        ...
        synchronized (mInstallLock) {
        synchronized (mLock) {
            ...
            if (!mOnlyCore) { //设备没有加密时
                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
                        SystemClock.uptimeMillis());
                //扫描data/app目录
                scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0,
                        packageParser, executorService);

            }
            ...      
            final PackageSetting ps = mSettings.getPackageLPr(packageName);
            if (ps != null && mPackages.get(packageName) == null) {
                removePackageDataLIF(ps, userIds, null, 0, false);
            }
            
           //安装存根系统应用程序
           installSystemStubPackages(stubSystemApps, scanFlags);
installSystemStubPackages(stubSystemApps, scanFlags);
           mStorageManagerPackage = getStorageManagerPackageName();
           mSetupWizardPackage = getSetupWizardPackageNameImpl();
           //默认文本分类器package
           mDefaultTextClassifierPackage = getDefaultTextClassifierPackageName();
           //系统文本分类器package
           mSystemTextClassifierPackageName = getSystemTextClassifierPackageName(); 
           mDocumenterPackage = getDocumenterPackageName();//文档的package
           mConfiguratorPackage = getDeviceConfiguratorPackageName();//设备配置package
           //使所有客户端都能访问共享库路径
           updateAllSharedLibrariesLocked(null, null, Collections.unmodifiableMap(mPackages));
           EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END, SystemClock.uptimeMillis());
            ...
        }
        }
        ...
    }
}

下面列出Data分区部分子目录:

/data/app存储用户自己安装的app
/data/data/存储已安装app的数据目录
/data/app-privateApp的私有存储空间
/data/app-lib存储所有app的Jni库
/data/system存放系统配置文件
/data/anr存储ANR时的traces文件

mSettings.readLPw()会扫描下面5个文件 
1. "/data/system/packages.xml" 所有安装app信息,包括系统permissions、apk的name、codePath、version等通过AndroidManifest.xml解析的内容。
2. "/data/system/packages-backup.xml" 所有安装app信息之备份的信息记录 
3. "/data/system/packages.list" 所有安装app信息 
4. "/data/system/packages-stopped.xml" 所有强制停止app信息 
5. "/data/system/packages-stopped-backup.xml" 所有强制停止app信息之备份的信息记录。

其中packages-backup.xml和packages-stopped-backup.xml文件是在写对应文件之前,会先备份,如果写成功会把备份文件删除。

5个文件共分为三组,简单的作用描述如下: 
packages.xml:PKMS扫描完目标文件夹后会创建该文件。当系统进行程序安装、卸载和更新等操作时,均会更新该文件。该文件保存了系统中与package 相关的一些信息。
packages.list:描述系统中存在的所有APK的信息。当这些程序有变动时,PKMS就会更新该文件。

packages-stopped.xml:从系统自带的设置程序中进入应用程序页面,然后在选择强制停止 (ForceStop)某个应用时,系统会将该应用的相关信息记录到此文件中。也就是该文件保存系统中被用户强制停止的Package的信息。

2.3.4 PKMS构造函数BOOT_PROGRESS_PMS_READY阶段

这个阶段的主要工作包括:管理安装会话服务和请求GC等。

public class PackageManagerService extends IPackageManager.Stub
        implements PackageSender, TestUtilityService {
    public PackageManagerService(Injector injector, boolean onlyCore, boolean factoryTest,
            final String buildFingerprint, final boolean isEngBuild,
            final boolean isUserDebugBuild, final int sdkVersion, final String incrementalVersion) {
        ...
        synchronized (mInstallLock) {
        synchronized (mLock) {
            ...
            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY, SystemClock.uptimeMillis());
            //管理安装会话的服务
            mInstallerService = mInjector.getPackageInstallerService();
            final ComponentName instantAppResolverComponent = getInstantAppResolverLPr();
            ...
            updateInstantAppInstallerLocked(null);
            ...      
            VMRuntime.getRuntime().requestConcurrentGC();//请求GC
        }
        }
        ...
    }
}

2.4 PKMS.installWhitelistedSystemPackages()

安装白名单中的系统App。

public class PackageManagerService extends IPackageManager.Stub
        implements PackageSender, TestUtilityService {
    /** Install/uninstall system packages for all users based on their user-type, as applicable. */
    private void installWhitelistedSystemPackages() {
        synchronized (mLock) {
            final boolean scheduleWrite = mUserManager.installWhitelistedSystemPackages(
                    isFirstBoot(), isDeviceUpgrading(), mExistingPackages);
            if (scheduleWrite) {
                scheduleWritePackageRestrictionsLocked(UserHandle.USER_ALL);
                scheduleWriteSettingsLocked();
            }
        }
    }
    }
}

2.5 PackageManagerNative类

PackageManagerNative是PKMS的内部类,extends IPackageManagerNative.Stub,主要用来与native层通过AIDL通信。

public class PackageManagerService extends IPackageManager.Stub
        implements PackageSender, TestUtilityService {​
    private class PackageManagerNative extends IPackageManagerNative.Stub {
        @Override
        public String[] getAllPackages() {
            return PackageManagerService.this.getAllPackages().toArray(new String[0]);
        }
        ...
    ​}
}