Android framework PakcageManagerService之启动

启动篇

android-12.0.0_r28\frameworks/base/services/java/com/android/server/SystemServer.java

1、startBootstrapServices

private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
    
    
	// 1. 启动Installer服务
	Installer installer = mSystemServiceManager.startService(Installer.class);
	
	// 2. 如果设备加密了,刚只解析"core"应用
	// Only run "core" apps if we're encrypting the device.
	String cryptState = VoldProperties.decrypt().orElse("");
	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;
	}
    // 3.启动DomainVerificationService服务
    DomainVerificationService domainVerificationService = new DomainVerificationService(
                mSystemContext, SystemConfig.getInstance(), platformCompat);
        mSystemServiceManager.startService(domainVerificationService);
	
	// 4.调用PackageManagerService.main方法初始化
	mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                    domainVerificationService, mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF,
                    mOnlyCore);
    
    // Now that the package manager has started, register the dex load reporter to capture any
    // dex files loaded by system server.
    // These dex files will be optimized by the BackgroundDexOptService.
    SystemServerDexLoadReporter.configureSystemServerDexReporter(mPackageManagerService);
    
    OtaDexoptService.main(mSystemContext, mPackageManagerService);
    
}

小结:

  • 启动Installer服务,该服务主要是定义一些与安装应用和处理应用数据相关的操作。该服务的API包了一层IInstalld.aidl的方法,调用的时候,实际上是调用了在IInstalld.aidl服务端的方法,实现的地方是在:在:frameworks/native/cmds/installd/InstalldNativeService.cpp,后面有机会分析一下
  • 根据设备/data目录下的数据是不是加密,来决定mOnlyCore的值,一般不加密的是false
  • 启动DomainVerificationService服务,后面有机会分析一下
  • 调用PackageManagerService.main方法,初始化PackageManagerService服务

2、startOtherServices

private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
    
    
	...
    if(!mOnlyCore){
    
    
        ...
        // 完成dex优化    
		mPackageManagerService.updatePackagesIfNeeded();
	}
	...
    // 完成磁盘维护
    mPackageManagerService.performFstrimIfNeeded();
    ....
    //PMS准备就绪    
    mPackageManagerService.systemReady();
    ....
    // Wait for all packages to be prepared
    mPackageManagerService.waitForAppDataPrepared();
}

PackageManagerService.main()方法

android-12.0.0_r28\frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

public static PackageManagerService main(Context context, Installer installer,
            @NonNull DomainVerificationService domainVerificationService, boolean factoryTest,
            boolean onlyCore) {
    
    
    //检查指定的系统属性是否被设值与被设值的合法性
	PackageManagerServiceCompilerMapping.checkProperties();
	//两把对象用作锁
    final PackageManagerTracedLock lock = new PackageManagerTracedLock();
    final Object installLock = new Object();
    //通过Injector包装子组件,子组件就是PKMS的功能模块,其中比较重要的就是Settings
    Injector injector = new Injector(
        	...,
			//...省略部分参数
        	// lambda,通过injector.getSettings()首次调用时,会调用new Settings(...),单例模式。
			(i, pm) -> new Settings(Environment.getDataDirectory(),
 				RuntimePermissionsPersistence.createInstance(),
				i.getPermissionManagerServiceInternal(),
				domainVerificationService, lock),
        	//...省略部分参数 
        	...,
    //PMS的构造方法
    PackageManagerService m = new PackageManagerService(injector, onlyCore, factoryTest,
                Build.FINGERPRINT, Build.IS_ENG, Build.IS_USERDEBUG, Build.VERSION.SDK_INT,
                Build.VERSION.INCREMENTAL);
    //省略部分代码...
	// 将PackageManagerService注册到了ServiceManager
	ServiceManager.addService("package", m);
	// 创建了一个PackageManagerNative
	final PackageManagerNative pmn = m.new PackageManagerNative();
	// 将PackageManagerNative注册到了ServiceManager
	ServiceManager.addService("package_native", pmn);
}

检查指定的系统属性是否被设值与被设值的合法性

这些属性值是:

"pm.dexopt.first-boot",
"pm.dexopt.boot-after-ota",
"pm.dexopt.post-boot",
"pm.dexopt.install",
"pm.dexopt.install-fast",
"pm.dexopt.install-bulk",
"pm.dexopt.install-bulk-secondary",
"pm.dexopt.install-bulk-downgraded",
"pm.dexopt.install-bulk-secondary-downgraded",
"pm.dexopt.bg-dexopt",
"pm.dexopt.ab-ota",
"pm.dexopt.inactive",
"pm.dexopt.cmdline",
"pm.dexopt.shared"

多个子组件创建出来

这些组件都是PackageManagerService功能列表,后面有机会将各个组件分析一下,目前只分析 Settings

public static class Injector {
    
    

	@VisibleForTesting(visibility = Visibility.PRIVATE)
    interface Producer<T> {
    
    
        /** Produce an instance of type {@link T} */
        T produce(Injector injector, PackageManagerService packageManager);
    }

    //...

    @VisibleForTesting(visibility = Visibility.PRIVATE)
    static class Singleton<T> {
    
    
        private final Producer<T> mProducer;
        private volatile T mInstance = null;
        // Singleton的构造方法是需要Producer<T>
        Singleton(Producer<T> producer) {
    
    
            this.mProducer = producer;
        }
        //get(),得到T类型的实例,这个T类型的实例通过Producer<T>接口方法produce()生成的,
        T get(Injector injector, PackageManagerService packageManagerService) {
    
    
            if (mInstance == null) {
    
    
                mInstance = mProducer.produce(injector, packageManagerService);
            }
            return mInstance;
        }
    }

    //...

    // PackageManagerService的子组件创建
    // ----- producers -----
    //...
    private final Singleton<Settings> mSettingsProducer;
    //...

    // Injector的构造 方法
    Injector(
            //...传的是new Producter<Settings>
            Producer<Settings> settingsProducer,
            //...
            ) {
    
    
        //...
        mSettingsProducer = new Singleton<>(settingsProducer);
        //...
        
    }
	//...
    public Settings getSettings() {
    
    
        return mSettingsProducer.get(this, mPackageManager);
    }
	//...
}

Injector类:负责将PackageManagerService的子组件初始化出来。

构造PackageManagerService

将PackageManagerService和PackageManagerNative注释到ServiceManager

PackageManagerService构造方法

android-12.0.0_r28\frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

public PackageManagerService(PackageManagerServiceInjector injector, boolean onlyCore,
            boolean factoryTest, final String buildFingerprint, final boolean isEngBuild,
            final boolean isUserDebugBuild, final int sdkVersion, final String incrementalVersion) {
    
    
    	...
    	//第1阶段:BOOT_PROGRESS_PMS_START
    	EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
                        SystemClock.uptimeMillis());
    	...
            
    	//第2阶段:BOOT_PROGRESS_PMS_SYSTEM_SCAN_START
    	EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
                    startTime);
    	...
            
    	//第2阶段:BOOT_PROGRESS_PMS_SYSTEM_SCAN_START
    	if (!mOnlyCore) {
    
    
             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
                        SystemClock.uptimeMillis());
        }
    	...
    	//第4阶段:BOOT_PROGRESS_PMS_SCAN_END
    	EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
                    SystemClock.uptimeMillis());
    	...
    	//第5阶段:BOOT_PROGRESS_PMS_READY
     	EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
                    SystemClock.uptimeMillis());
        
}

**阶段1:**BOOT_PROGRESS_PMS_START

android-12.0.0_r28\frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

public PackageManagerService(Injector injector, boolean onlyCore, boolean factoryTest,
            final String buildFingerprint, final boolean isEngBuild,
            final boolean isUserDebugBuild, final int sdkVersion, final String incrementalVersion) {
    
    
        mIsEngBuild = isEngBuild;
        mIsUserDebugBuild = isUserDebugBuild;
        mSdkVersion = sdkVersion;
        mIncrementalVersion = incrementalVersion;
        mInjector = injector;
    	// 禁用所有不应该在系统服务中使用的应用包缓存
        mInjector.getSystemWrapper().disablePackageCaches();

        final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",
                Trace.TRACE_TAG_PACKAGE_MANAGER);
    	// PendingPackageBroadcasts类维护了一个列表,用于管理待处理的应用程序安装、卸载、更新等操作所触发的广播
        mPendingBroadcasts = new PendingPackageBroadcasts();

    	
        mInjector.bootstrap(this);
        mLock = injector.getLock();
        mInstallLock = injector.getInstallLock();
        LockGuard.installLock(mLock, LockGuard.INDEX_PACKAGES);
    	// 阶段1:BOOT_PROGRESS_PMS_START
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START
                SystemClock.uptimeMillis());
        mSystemWrapper = injector.getSystemWrapper();

        mContext = injector.getContext();
        mFactoryTest = factoryTest;
        mOnlyCore = onlyCore;
    	// 初始化设备的屏幕信息类,后面会通过
    	// “mContext.getSystemService(DisplayManager.class)
        //         .getDisplay(Display.DEFAULT_DISPLAY).getMetrics(mMetrics)”,用默认屏幕信息初始化mMetrics
        mMetrics = injector.getDisplayMetrics();
    	// 与安装应用的相关
        mInstaller = injector.getInstaller();
        mEnableFreeCacheV2 = SystemProperties.getBoolean("fw.free_cache_v2", true);

        // 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(TestUtilityService.class, this);
        mTestUtilityService = LocalServices.getService(TestUtilityService.class);
        LocalServices.addService(PackageManagerInternal.class, mPmInternal);
    	// 多用户管理
        mUserManager = injector.getUserManagerService();
    	Resolves all Android component types [activities, services, providers and receivers].
        // 解析所有Android组件类型[activity, services, providers and receivers]。    
        mComponentResolver = injector.getComponentResolver();
    	// 权限管理器,可以被系统服务中的其他组件使用,实际返回的是PermissionManagerServiceInternalImpl(PermissionManagerService内部类),
    	// 这类服务可以间接调用PermissionManagerService方法
        mPermissionManager = injector.getPermissionManagerServiceInternal();
    	// 创建Settings对象,这个很重要,下面重点分析
        mSettings = injector.getSettings();
    	// 增量服务,用来管理升级的
        mIncrementalManager = mInjector.getIncrementalManager();
     	// 用于管理默认应用程序的信息
        mDefaultAppProvider = mInjector.getDefaultAppProvider();
    	// 用来处理旧版本应用程序(targetSDK < 23)的权限请求
        mLegacyPermissionManager = mInjector.getLegacyPermissionManagerInternal();
    	// 用于处理与平台版本相关的兼容性问题
        PlatformCompat platformCompat = mInjector.getCompatibility();
    	// 回调接口,用于接收解析 APK 文件过程中的事件通知
        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等几种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);
        mSettings.addSharedUserLPw("android.uid.uwb", UWB_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 = ParsingPackageUtils.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;
        }
		// 用于优化应用程序Dex代码的类(为了提高应用程序的启动速度和性能,系统会在应用程序第一次运行时对其Dex代码进行优化)
        mPackageDexOptimizer = injector.getPackageDexOptimizer();
    	// 负责管理DEX 文件
        mDexManager = injector.getDexManager();
    	// 负责管理应用程序运行时(ART)的服务
        mArtManagerService = injector.getArtManagerService();
    	// 负责管理移动应用程序包时进行进度跟踪和通知
        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
		// 用于将布局文件编译为二进制格式,当应用第一次加载布局文件时,系统会将布局文件编译为二进制格式并保存到应用的资源目录中。这样,当下次加载布局文件时,		// 系统就可以直接使用编译好的二进制文件,从而避免了解析XML文件的开销
        mViewCompiler = injector.getViewCompiler();
		// 初始化DisplayMetrics对象,其中包括屏幕分辨率、密度等
        mContext.getSystemService(DisplayManager.class)
                .getDisplay(Display.DEFAULT_DISPLAY).getMetrics(mMetrics);

        t.traceBegin("get system config");
    	// 创建SystemConfig时,会在以下目录的解析所有.xml读取权限 
    	// /system/etc/sysconfig,
    	// /system//etc/permissions,
    	// /vendor/etc/sysconfig,
    	// /vendor/etc/permissions,
    	// /odm/etc/sysconfig,
    	// /odm/etc/permissions,
    	// /oem/etc/sysconfig,
    	// /oem/etc/permissions,
    	// /product/etc/sysconfig,
    	// /product/etc/permissions,
    	// /system_ext/etc/sysconfig,
    	// /system_ext/etc/permissions,
        SystemConfig systemConfig = injector.getSystemConfig();
        mAvailableFeatures = systemConfig.getAvailableFeatures();
        t.traceEnd();

        mProtectedPackages = new ProtectedPackages(mContext);
		
    	// 用于管理 APEX(系统级组件格式,用于升级APEX 类似于应用程序,但其目的是为了允许 Android 平台以可更新的方式提供系统组件,而无需完全进行系统升级		   // 或重新启动
        mApexManager = injector.getApexManager();
        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);
            }
        }
		
    	// 与谷歌的即时应用相关
        mInstantAppRegistry = new InstantAppRegistry(this, mPermissionManager);

        mDirsToScanAsSystem = new ArrayList<>();
    	// 初始化某些包含app的目录,比如/system/app/,/system/priv-app/,/system/overlay/...等等
        mDirsToScanAsSystem.addAll(injector.getSystemPartitions());
        mDirsToScanAsSystem.addAll(scanPartitions);
        Slog.d(TAG, "Directories scanned as system partitions: " + mDirsToScanAsSystem);
		// /data/app/目录 
        mAppInstallDir = new File(Environment.getDataDirectory(), "app");
    	// /data/app-lib
        mAppLib32InstallDir = getAppLib32InstallDir();

        mDomainVerificationManager = injector.getDomainVerificationManagerInternal();
        mDomainVerificationManager.setConnection(mDomainVerificationConnection);

        synchronized (mLock) {
    
    
            // Create the computer as soon as the state objects have been installed.  The
            // cached computer is the same as the live computer until the end of the
            // constructor, at which time the invalidation method updates it.  The cache is
            // corked initially to ensure a cached computer is not built until the end of the
            // constructor.
            mSnapshotStatistics = new SnapshotStatistics();
            sSnapshotConsumer = this;
            sSnapshotCorked.set(1);
            sSnapshotInvalid.set(true);
            mLiveComputer = createLiveComputer();
            mSnapshotComputer = null;
            mSnapshotEnabled = SNAPSHOT_ENABLED;
            registerObserver();
        }

        // CHECKSTYLE:OFF IndentationCheck
        synchronized (mInstallLock) {
    
    
        // writer
        synchronized (mLock) {
    
    
            mHandler = injector.getHandler();
            mProcessLoggingHandler = new ProcessLoggingHandler();
            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);

            // 从系统配置信息中获取共享库,这些共享库由SystemConfig创建的时候解析xml得出来
            ArrayMap<String, SystemConfig.SharedLibraryEntry> libConfig
                    = systemConfig.getSharedLibraries();
            final int builtInLibCount = libConfig.size();
            for (int i = 0; i < builtInLibCount; i++) {
    
    
                // 用于向系统添加内置共享库
                addBuiltInSharedLibraryLocked(libConfig.valueAt(i));
            }

            // 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++) {
    
    
                    // 主要用于检查应用程序是否正确地声明了其所需的共享库,并在解析 APK 文件时更新共享库信息
                    final SharedLibraryInfo dependency =
                        getSharedLibraryInfoLPr(entry.dependencies[j], undefinedVersion);
                    if (dependency != null) {
    
    
                        getSharedLibraryInfoLPr(name, undefinedVersion).addDependency(dependency);
                    }
                }
            }
			// 读取所有mac linuxe的所有信息:/etc/selinux/xxxx_mac_permissions.xml
            SELinuxMMAC.readInstallPolicy();

            t.traceBegin("loadFallbacks");
           	// 设置特定某个应用的类别信息可用于描述应用程序的性质或用途,例如游戏、社交网络、工具等。
            // (设置com.android.printspooler,7),7代表ApplicationInfo.CATEGORY_PRODUCTIVITY
            // 该类型主要是生产力应用程序的类别,如云存储或工作场所应用程序。
            FallbackCategoryProvider.loadFallbacks();
            t.traceEnd();

            t.traceBegin("read user settings");
            
            //读取/data/system/package***.xml相关标签数据
            mFirstBoot = !mSettings.readLPw(mInjector.getUserManagerInternal().getUsers(
                    /* excludePartial= */ true,
                    /* excludeDying= */ false,
                    /* excludePreCreated= */ false));
            t.traceEnd();

            // 将Settings读取到/system/etc/permission/**.xml等的permissions与persmission-trees标签传给PermisisonManager
            mPermissionManager.readLegacyPermissionsTEMP(mSettings.mPermissions);
            // 读取所有UID的权限的授权权限 
            mPermissionManager.readLegacyPermissionStateTEMP();

            // 如果不是首次启动,也不是core应用,则拷贝预编译的DEX文件
            if (!mOnlyCore && mFirstBoot) {
    
    
                requestCopyPreoptedFiles(mInjector);
            }

            String customResolverActivityName = Resources.getSystem().getString(
                    R.string.config_customResolverActivity);
            if (!TextUtils.isEmpty(customResolverActivityName)) {
    
    
                mCustomResolverComponentName = ComponentName.unflattenFromString(
                        customResolverActivityName);
            }
重点解析一下Settings相关的

android-12.0.0_r28\frameworks/base/services/core/java/com/android/server/pm/Settings.java

Settings构造方法
Settings(File dataDir, RuntimePermissionsPersistence runtimePermissionsPersistence,
            LegacyPermissionDataProvider permissionDataProvider,
            @NonNull DomainVerificationManagerInternal domainVerificationManager,
            @NonNull PackageManagerTracedLock lock)  {
    
    
    //...
    mSystemDir = new File(dataDir, "system");
    mSystemDir.mkdirs();
    FileUtils.setPermissions(mSystemDir.toString(),
            FileUtils.S_IRWXU|FileUtils.S_IRWXG
            |FileUtils.S_IROTH|FileUtils.S_IXOTH,
            -1, -1);
    mSettingsFilename = new File(mSystemDir, "packages.xml");
    mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml");
    mPackageListFilename = new File(mSystemDir, "packages.list");
    FileUtils.setPermissions(mPackageListFilename, 0640, SYSTEM_UID, PACKAGE_INFO_GID);
	...
    mStoppedPackagesFilename = new File(mSystemDir, "packages-stopped.xml");
    mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml");
	//...
    }

Settings对象的构造过程很简单,重点的就是创建一些目录和文件。首先创建/data/system/目录,然后分别创建以下四个文件:

#文件用于记录系统中所安装的Package信息:
/data/system/packages.xml

#对packages.xml的备份
/data/system/packages-backup.xml

#保存系统中存在的所有非系统自带的APK信息,即UID大于1000的apk
/data/system/packages.list

#文件用于记录系统中强制停止运行的Package信息
/data/system/packages-stopped.xml

#packages-stopped.xml的备份
/data/system/packages-stopped-backup.xml
Settings.addSharedUserLPw

SharedUserSetting类就是一个有特定共享用户UID的数据,包括权限,uidgid,签名等信息

UID>= Process.FIRST_APPLICATION_UID(10000)(即是普通应用的UID),创建SharedUserSetting放到mAppIds列表里,

UID<Process.FIRST_APPLICATION_UID(即是系统内置的UID,比如Process.SYSTEM_UID等 ),创建的SharedUserSetting放到mOtherUserIds列表里,

最后把上面两者mAppIdsmOtherUserIds所有SharedUserSetting放到别外一个容器里mSharedUsers,通过一个name作为它们的key,来找到具体的SharedUserSetting

这个机制用处:

  • 同一种 sharedUserId的不同的App 可共享彼此的数据且也可运行在同一进程中。

  • 通过在清单文件中指定对应的 sharedUserId,可以使得 App 所在进程将被赋予指定的 UID。例如在应用清单里配置了android:sharedUserId="android.uid.system"属性,如果该App的签名也是使用platform级别的签名证书(即在其 Android.mk 中需要额外声明 LOCAL_CERTIFICATE := platform)时,相当于是把该进程的UID设置为systemUID,也就拥有了系统权限。

Settings.readLPw
boolean readLPw(@NonNull List<UserInfo> users) {
       		...
            // 解析"/data/system/packages.xml"
            final TypedXmlPullParser parser = Xml.resolvePullParser(str);

            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;
                }
				// 对各个标签进行解析,建立对应的数据结构
                String tagName = parser.getName();
                if (tagName.equals("package")) {
                    readPackageLPw(parser, users);
                } 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, users);
                } 
                ....
                }
            }

            str.close();
        } catch (IOException | XmlPullParserException e) {
            mReadMessages.append("Error reading: " + e.toString());
            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
            Slog.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
        }
    	....
    }
小结
  • 初始化一些屏幕信息DisplayMestrics,与应用相关的Installer,多用户管理UserManager
  • 初始化保存系统包信息的Settings,并将一些重要的uid,比如system,phone添加进去
  • 初始化SystemConfig去读取某些目录下配置,权限,so库

**阶段2:**BOOT_PROGRESS_PMS_SYSTEM_SCAN_START

android-12.0.0_r28\frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

			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");

            if (bootClassPath == null) {
    
    
                Slog.w(TAG, "No BOOTCLASSPATH found!");
            }

            if (systemServerClassPath == null) {
    
    
                Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
            }
			
            // 目录 /system/framework
            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
			// 获取内部版本号
            final VersionInfo ver = mSettings.getInternalVersion();
			// 通过fingerprint是否有更新
            mIsUpgrade =
                    !buildFingerprint.equals(ver.fingerprint);
            if (mIsUpgrade) {
    
    
                PackageManagerServiceUtils.logCriticalInfo(Log.INFO,
                        "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
            }

            // when upgrading from pre-M, promote system app permissions from install to runtime
			// 当是从Android 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.
			// 当是从Android N版本升级上来,需像首次启动一样处理包
            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;

            final WatchedArrayMap<String, PackageSetting> packageSettings =
                mSettings.getPackagesLocked();

            // Save the names of pre-existing packages prior to scanning, so we can determine
            // which system packages are completely new due to an upgrade.
            // 在扫描之前保存现有包的名称,以便我们可以确定哪些系统包是由于升级而全新的。
            if (isDeviceUpgrading()) {
    
    
                mExistingPackages = new ArraySet<>(packageSettings.size());
                for (PackageSetting ps : packageSettings.values()) {
    
    
                    mExistingPackages.add(ps.name);
                }
            }
			// 目录/data/system/package_cache
            mCacheDir = preparePackageParserCache(mIsEngBuild);

            // 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;
            }

            final int systemParseFlags = mDefParseFlags | ParsingPackageUtils.PARSE_IS_SYSTEM_DIR;
            final int systemScanFlags = scanFlags | SCAN_AS_SYSTEM;

            // 创建 PackageParser2 对象 packageParser,后续用来解析各种 apk 文件
            PackageParser2 packageParser = injector.getScanningCachingPackageParser();
			// packageParser 解析用的线程池
            ExecutorService executorService = ParallelPackageParser.makeExecutorService();
            // Prepare apex package info before scanning APKs, these information are needed when
            // scanning apk in apex.
            // 在扫描 APK 之前,准备好 apex 包信息,在以下情况下需要扫描apk时需要这些信息
            mApexManager.scanApexPackagesTraced(packageParser, executorService);
            // Collect vendor/product/system_ext 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.
            for (int i = mDirsToScanAsSystem.size() - 1; i >= 0; i--) {
    
    
                final ScanPartition partition = mDirsToScanAsSystem.get(i);
                if (partition.getOverlayFolder() == null) {
    
    
                    continue;
                }
                // mDirsToScanAsSystem是阶段1的时候声明的,里面就是/system/app,/system/priv-app,/system/overlay等目录
                // 解析DirsToScanAsSystem的overlay目录目录所有apk等信息,耗时操作
                scanDirTracedLI(partition.getOverlayFolder(), systemParseFlags,
                        systemScanFlags | partition.scanFlag, 0,
                        packageParser, executorService);
            }
			// 扫描 /system/framework 目录
            scanDirTracedLI(frameworkDir, systemParseFlags,
                    systemScanFlags | SCAN_NO_DEX | SCAN_AS_PRIVILEGED, 0,
                    packageParser, executorService);
            if (!mPackages.containsKey("android")) {
    
    
                throw new IllegalStateException(
                        "Failed to load frameworks package; check log for warnings");
            }
            // 开始扫描各个目录
            for (int i = 0, size = mDirsToScanAsSystem.size(); i < size; i++) {
    
    
                final ScanPartition partition = mDirsToScanAsSystem.get(i);
                if (partition.getPrivAppFolder() != null) {
    
    
                    //解析DirsToScanAsSystem的priv-app目录目录所有apk等信息,耗时操作
                    scanDirTracedLI(partition.getPrivAppFolder(), systemParseFlags,
                            systemScanFlags | SCAN_AS_PRIVILEGED | partition.scanFlag, 0,
                            packageParser, executorService);
                }
                //解析DirsToScanAsSystem的app目录目录所有apk等信息,耗时操作
                scanDirTracedLI(partition.getAppFolder(), systemParseFlags,
                        systemScanFlags | partition.scanFlag, 0,
                        packageParser, executorService);
            }

            // Parse overlay configuration files to set default enable state, mutability, and
            // priority of system overlays.
			// 解析overlay配置文件以设置系统覆盖的默认启用状态、可变性和优先级。
            mOverlayConfig = OverlayConfig.initializeSystemInstance(
                    consumer -> mPmInternal.forEachPackage(
                            pkg -> consumer.accept(pkg, pkg.isSystem())));

            // Prune any system packages that no longer exist.
			// 收集可能不再存在的系统App
            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<>();
            final int[] userIds = mUserManager.getUserIds();
            // 如果不是只加载核心apk,一般情况都是false
            if (!mOnlyCore) {
    
    
                // do this first before mucking with mPackages for the "expecting better" case
                final int numPackages = mPackages.size();
                for (int index = 0; index < numPackages; index++) {
    
    
                    final AndroidPackage pkg = mPackages.valueAt(index);
                    if (pkg.isStub()) {
    
    
                        stubSystemApps.add(pkg.getPackageName());
                    }
                }

                // Iterates PackageSettings in reversed order because the item could be removed
                // during the iteration.
                for (int index = packageSettings.size() - 1; index >= 0; index--) {
    
    
                    final PackageSetting ps = packageSettings.valueAt(index);

                    /*
                     * If this is not a system app, it can't be a
                     * disable system app.
                     */
                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
    
    
                        continue;
                    }

                    /*
                     * If the package is scanned, it's not erased.
                     */
                    final AndroidPackage 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.getPathString()
                                    + ", versionCode=" + ps.versionCode
                                    + "; scanned versionCode=" + scannedPkg.getLongVersionCode());
                            removePackageLI(scannedPkg, true);
                            mExpectingBetter.put(ps.name, ps.getPath());
                        }

                        continue;
                    }

                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
    
    
                        logCriticalInfo(Log.WARN, "System package " + ps.name
                                + " no longer exists; it's data will be wiped");
                        removePackageDataLIF(ps, userIds, null, 0, false);
                    } 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.getPath() == null || !disabledPs.getPath().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.getPath());
                        }
                    }
                }
            }

            final int cachedSystemApps = PackageCacher.sCachedPackageReadCount.get();

            // Remove any shared userIDs that have no associated packages
            mSettings.pruneSharedUsersLPw();
            final long systemScanTime = SystemClock.uptimeMillis() - startTime;
            final int systemPackagesCount = mPackages.size();
            Slog.i(TAG, "Finished scanning system apps. Time: " + systemScanTime
                    + " ms, packageCount: " + systemPackagesCount
                    + " , timePerPackage: "
                    + (systemPackagesCount == 0 ? 0 : systemScanTime / systemPackagesCount)
                    + " , cached: " + cachedSystemApps);
            if (mIsUpgrade && systemPackagesCount > 0) {
    
    
                //CHECKSTYLE:OFF IndentationCheck
                FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_DURATION_REPORTED,
                    BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_SYSTEM_APP_AVG_SCAN_TIME,
                    systemScanTime / systemPackagesCount);
                //CHECKSTYLE:ON IndentationCheck
            }
小结
  • 对于旧版本升级的情况,将安装时获取权限变更为运行时申请权限;

  • 扫描system/vendor/product/odm/oem等目录的priv-appappoverlay包-

  • 清除安装时临时文件以及其他不必要的信息。

**阶段3:**BOOT_PROGRESS_PMS_DATA_SCAN_START

android-12.0.0_r28\frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

 			// 如果不是只加载核心apk,一般情况都是false
            if (!mOnlyCore) {
    
    
                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
                        SystemClock.uptimeMillis());
                // 在/data/app目录扫描用户安装文件,mAppInstallDir 目录是在阶段1中创建的
                scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0,
                        packageParser, executorService);

            }

            packageParser.close();

            List<Runnable> unfinishedTasks = executorService.shutdownNow();
            if (!unfinishedTasks.isEmpty()) {
    
    
                throw new IllegalStateException("Not all tasks finished before calling close: "
                        + unfinishedTasks);
            }

            if (!mOnlyCore) {
    
    
                // 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.
                // 删除已通过OTA删除的更新系统应用程序的禁用包设置。如果更新不再存在,则完全删除应用程序。否则,取消其系统权限。
                for (int i = possiblyDeletedUpdatedSystemApps.size() - 1; i >= 0; --i) {
    
    
                    final String packageName = possiblyDeletedUpdatedSystemApps.get(i);
                    final AndroidPackage 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.getPath());
                            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.getPackageLPr(packageName);
                    if (ps != null && mPackages.get(packageName) == null) {
    
    
                        removePackageDataLIF(ps, userIds, null, 0, false);

                    }
                    logCriticalInfo(Log.WARN, msg);
                }

                /*
                 * Make sure all system apps that we expected to appear on
                 * the userdata partition actually showed up. If they never
                 * appeared, crawl back and revive the system version.
                 */
                 // 确保所有期望在用户数据分区上的系统应用程序都能出现。
				 // 如果没有出现就回滚系统版本
                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");

                        @ParseFlags int reparseFlags = 0;
                        @ScanFlags int rescanFlags = 0;
                        for (int i1 = mDirsToScanAsSystem.size() - 1; i1 >= 0; i1--) {
    
    
                            final ScanPartition partition = mDirsToScanAsSystem.get(i1);
                            if (partition.containsPrivApp(scanFile)) {
    
    
                                reparseFlags = systemParseFlags;
                                rescanFlags = systemScanFlags | SCAN_AS_PRIVILEGED
                                        | partition.scanFlag;
                                break;
                            }
                            if (partition.containsApp(scanFile)) {
    
    
                                reparseFlags = systemParseFlags;
                                rescanFlags = systemScanFlags | partition.scanFlag;
                                break;
                            }
                        }
                        if (rescanFlags == 0) {
    
    
                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
                            continue;
                        }
                        mSettings.enableSystemPackageLPw(packageName);

                        try {
    
    
                            final AndroidPackage newPkg = scanPackageTracedLI(
                                    scanFile, reparseFlags, rescanFlags, 0, null);
                            // We rescanned a stub, add it to the list of stubbed system packages
                            if (newPkg.isStub()) {
    
    
                                stubSystemApps.add(packageName);
                            }
                        } 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);

                final int cachedNonSystemApps = PackageCacher.sCachedPackageReadCount.get()
                                - cachedSystemApps;

                final long dataScanTime = SystemClock.uptimeMillis() - systemScanTime - startTime;
                final int dataPackagesCount = mPackages.size() - systemPackagesCount;
                Slog.i(TAG, "Finished scanning non-system apps. Time: " + dataScanTime
                        + " ms, packageCount: " + dataPackagesCount
                        + " , timePerPackage: "
                        + (dataPackagesCount == 0 ? 0 : dataScanTime / dataPackagesCount)
                        + " , cached: " + cachedNonSystemApps);
                if (mIsUpgrade && dataPackagesCount > 0) {
    
    
                    //CHECKSTYLE:OFF IndentationCheck
                    FrameworkStatsLog.write(
                        FrameworkStatsLog.BOOT_TIME_EVENT_DURATION_REPORTED,
                        BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_DATA_APP_AVG_SCAN_TIME,
                        dataScanTime / dataPackagesCount);
                    //CHECKSTYLE:OFF IndentationCheck
                }
            }
            mExpectingBetter.clear();

            // Resolve the storage manager.
            mStorageManagerPackage = getStorageManagerPackageName();

            // Resolve protected action filters. Only the setup wizard is allowed to
            // have a high priority filter for these actions.
            mSetupWizardPackage = getSetupWizardPackageNameImpl();
            mComponentResolver.fixProtectedFilterPriorities();

            mDefaultTextClassifierPackage = getDefaultTextClassifierPackageName();
            mSystemTextClassifierPackageName = getSystemTextClassifierPackageName();
            mDocumenterPackage = getDocumenterPackageName();
            mConfiguratorPackage = getDeviceConfiguratorPackageName();
            mAppPredictionServicePackage = getAppPredictionServicePackageName();
            mIncidentReportApproverPackage = getIncidentReportApproverPackageName();
            mRetailDemoPackage = getRetailDemoPackageName();
            mOverlayConfigSignaturePackage = getOverlayConfigSignaturePackageName();
            mRecentsPackage = getRecentsPackageName();

            // Now that we know all of the shared libraries, update all clients to have
            // the correct library paths.
            // 现在解析完了所有的共享库,更新到所有的客户端,
            // 以保证它拥有正确的库路径。
            updateAllSharedLibrariesLocked(null, 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 =
                        applyAdjustedAbiToSharedUser(setting, null /*scannedPackage*/,
                        mInjector.getAbiHelper().getAdjustedAbiForSharedUser(
                                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.
                // 调整seInfo以确保共享UserId的应用程序被放置在同一个
                // SELinux域。
                setting.fixSeInfoLocked();
                setting.updateProcesses();
            }

            // Now that we know all the packages we are keeping,
            // read and update their last usage times.
            //现在我们知道了我们要保留的所有软件包。
            // 读取并更新它们的最后使用时间。
            mPackageUsage.read(packageSettings);
            mCompilerStats.read();

小结

这里就是对/data/app进行了扫描,主要工作与扫描系统App目录是一样的。

**阶段4:**BOOT_PROGRESS_PMS_SCAN_END

android-12.0.0_r28\frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

			EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
                    SystemClock.uptimeMillis());
            Slog.i(TAG, "Time to scan packages: "
                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
                    + " seconds");

            // If the build fingerprint has changed since the last time we booted,
            // we need to re-grant app permission to catch any new ones that
            // appear.  This is really a hack, and means that apps can in some
            // cases get permissions that the user didn't initially explicitly
            // allow...  it would be nice to have some better way to handle
            // this situation.
            if (mIsUpgrade) {
    
    
                Slog.i(TAG, "Build fingerprint changed from " + ver.fingerprint + " to "
                        + Build.FINGERPRINT + "; regranting permissions for internal storage");
            }
            // 如果在上次启动之后,build fingerprint发生了变化。
			// 就需要重新授予应用程序权限,以捕捉任何新出现的情况
			// 这意味着应用程序在某些情况下可以获得用户最初没有明确允许的权限。
            mPermissionManager.onStorageVolumeMounted(
                    StorageManager.UUID_PRIVATE_INTERNAL, mIsUpgrade);
            ver.sdkVersion = mSdkVersion;

            // If this is the first boot or an update from pre-M, and it is a normal
            // boot, then we need to initialize the default preferred apps across
            // all defined users.
            // 如果这是第一次启动或从Android M之前的更新,并且是正常的启动
			// 那么我们就初始化所有定义的用户默认首选应用程序。
            if (!mOnlyCore && (mPromoteSystemApps || mFirstBoot)) {
    
    
                for (UserInfo user : mInjector.getUserManagerInternal().getUsers(true)) {
    
    
                    mSettings.applyDefaultPreferredAppsLPw(user.id);
                }
            }

            // Prepare storage for system user really early during boot,
            // since core system apps like SettingsProvider and SystemUI
            // can't wait for user to start
            // 在启动过程中为系统用户真正提前准备好存储。
			// 因为核心系统应用程序(如 SettingsProvide r和 SystemUI)不能等待用户启动
            final int storageFlags;
            if (StorageManager.isFileEncryptedNativeOrEmulated()) {
    
    
                storageFlags = StorageManager.FLAG_STORAGE_DE;
            } else {
    
    
                storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
            }
            List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
                    UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
                    true /* onlyCoreApps */);
            mPrepareAppDataFuture = SystemServerInitThreadPool.submit(() -> {
    
    
                TimingsTraceLog traceLog = new TimingsTraceLog("SystemServerTimingAsync",
                        Trace.TRACE_TAG_PACKAGE_MANAGER);
                traceLog.traceBegin("AppDataFixup");
                try {
    
    
                    mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
                } catch (InstallerException e) {
    
    
                    Slog.w(TAG, "Trouble fixing GIDs", e);
                }
                traceLog.traceEnd();

                traceLog.traceBegin("AppDataPrepare");
                if (deferPackages == null || deferPackages.isEmpty()) {
    
    
                    return;
                }
                int count = 0;
                final Installer.Batch batch = new Installer.Batch();
                for (String pkgName : deferPackages) {
    
    
                    AndroidPackage pkg = null;
                    synchronized (mLock) {
    
    
                        PackageSetting ps = mSettings.getPackageLPr(pkgName);
                        if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
    
    
                            pkg = ps.pkg;
                        }
                    }
                    if (pkg != null) {
    
    
                        prepareAppDataAndMigrate(batch, pkg, UserHandle.USER_SYSTEM, storageFlags,
                                true /* maybeMigrateAppData */);
                        count++;
                    }
                }
                synchronized (mInstallLock) {
    
    
                    executeBatchLI(batch);
                }
                traceLog.traceEnd();
                Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
            }, "prepareAppData");

            // If this is first boot after an OTA, and a normal boot, then
            // we need to clear code cache directories.
            // Note that we do *not* clear the application profiles. These remain valid
            // across OTAs and are used to drive profile verification (post OTA) and
            // profile compilation (without waiting to collect a fresh set of profiles).
            // 如果这是OTA后的第一次启动,而且是正常启动,
			// 那么我们就清除代码缓存目录。
			// 注意,我们并不清除应用程序配置文件。这些文件仍然有效
			// 在不同的OTA中都是有效的
            if (mIsUpgrade && !mOnlyCore) {
    
    
                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
                for (int i = 0; i < packageSettings.size(); i++) {
    
    
                    final PackageSetting ps = packageSettings.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
                                        | Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES);
                    }
                }
                ver.fingerprint = Build.FINGERPRINT;
            }

            // Legacy existing (installed before Q) non-system apps to hide
            // their icons in launcher.
            // 在Q之前安装的非系统应用程序,隐藏它们在 Launch 中的图标。
            if (!mOnlyCore && mIsPreQUpgrade) {
    
    
                Slog.i(TAG, "Whitelisting all existing apps to hide their icons");
                int size = packageSettings.size();
                for (int i = 0; i < size; i++) {
    
    
                    final PackageSetting ps = packageSettings.valueAt(i);
                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
    
    
                        continue;
                    }
                    ps.disableComponentLPw(PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME,
                            UserHandle.USER_SYSTEM);
                }
            }

            // clear only after permissions and other defaults have been updated
            // 只有在权限和其他默认值被更新后才能清除
            mPromoteSystemApps = false;

            // All the changes are done during package scanning.
            // 所有的变化都是在软件包扫描期间完成的
            ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
			
            // can downgrade to reader
            t.traceBegin("write settings");
            // 将信息写到 packages.xml 文件
            writeSettingsLPrTEMP();
            t.traceEnd();
            
小结

这里主要做了如下几件事情:

  1. 如果SDK版本发生了变化(升级系统),重新对App进行授权
  2. 为系统核心服务准备存储空间
  3. 如果是升级后第一次正常启动,需要清除代码缓存,但不是会清除应用的配置文件
  4. 把更新后的信息写回对应的xml文件中

**阶段5:**BOOT_PROGRESS_PMS_READY

android-12.0.0_r28\frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

			EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
                    SystemClock.uptimeMillis());

            if (!mOnlyCore) {
    
    
                mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
                mRequiredInstallerPackage = getRequiredInstallerLPr();
                mRequiredUninstallerPackage = getRequiredUninstallerLPr();
                ComponentName intentFilterVerifierComponent =
                        getIntentFilterVerifierComponentNameLPr();
                ComponentName domainVerificationAgent =
                        getDomainVerificationAgentComponentNameLPr();

                DomainVerificationProxy domainVerificationProxy = DomainVerificationProxy.makeProxy(
                        intentFilterVerifierComponent, domainVerificationAgent, mContext,
                        mDomainVerificationManager, mDomainVerificationManager.getCollector(),
                        mDomainVerificationConnection);

                mDomainVerificationManager.setProxy(domainVerificationProxy);

                mServicesExtensionPackageName = getRequiredServicesExtensionPackageLPr();
                mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
                        PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
                        SharedLibraryInfo.VERSION_UNDEFINED);
            } else {
    
    
                mRequiredVerifierPackage = null;
                mRequiredInstallerPackage = null;
                mRequiredUninstallerPackage = null;
                mServicesExtensionPackageName = null;
                mSharedSystemSharedLibraryPackageName = null;
            }

            // PermissionController hosts default permission granting and role management, so it's a
            // critical part of the core system.
            // PermissionController主持默认的权限授予和角色管理,
			// 所以它是一个核心系统的关键部分
            mRequiredPermissionControllerPackage = getRequiredPermissionControllerLPr();

            mSettings.setPermissionControllerVersion(
                    getPackageInfo(mRequiredPermissionControllerPackage, 0,
                            UserHandle.USER_SYSTEM).getLongVersionCode());

            // Initialize InstantAppRegistry's Instant App list for all users.
            // 为所有用户初始化InstantAppRegistry的即时应用程序列表。
            for (AndroidPackage pkg : mPackages.values()) {
    
    
                if (pkg.isSystem()) {
    
    
                    continue;
                }
                for (int userId : userIds) {
    
    
                    final PackageSetting ps = getPackageSetting(pkg.getPackageName());
                    if (ps == null || !ps.getInstantApp(userId) || !ps.getInstalled(userId)) {
    
    
                        continue;
                    }
                    mInstantAppRegistry.addInstantAppLPw(userId, ps.appId);
                }
            }

            mInstallerService = mInjector.getPackageInstallerService();
            final ComponentName instantAppResolverComponent = getInstantAppResolverLPr();
            if (instantAppResolverComponent != null) {
    
    
                if (DEBUG_INSTANT) {
    
    
                    Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
                }
                mInstantAppResolverConnection =
                        mInjector.getInstantAppResolverConnection(instantAppResolverComponent);
                mInstantAppResolverSettingsComponent =
                        getInstantAppResolverSettingsLPr(instantAppResolverComponent);
            } else {
    
    
                mInstantAppResolverConnection = null;
                mInstantAppResolverSettingsComponent = null;
            }
            updateInstantAppInstallerLocked(null);

            // Read and update the usage of dex files.
            // Do this at the end of PM init so that all the packages have their
            // data directory reconciled.
            // At this point we know the code paths of the packages, so we can validate
            // the disk file and build the internal cache.
            // The usage file is expected to be small so loading and verifying it
            // should take a fairly small time compare to the other activities (e.g. package
            // scanning).
            // 读取并更新dex文件的用法。在PM init的结束时执行,
			// 以便协调所有的包都的数据目录。因为我们现在已经知道软件包的路径
			// 所以我们可以验证磁盘文件并建立内部缓存。
			// 预计使用文件会很小,所以加载和验证它与其他活动(如软件包扫描)相比
			// 应该只会花费相当少的时间。

            final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
            for (int userId : userIds) {
    
    
                userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
            }
            mDexManager.load(userPackages);
            if (mIsUpgrade) {
    
    
                FrameworkStatsLog.write(
                        FrameworkStatsLog.BOOT_TIME_EVENT_DURATION_REPORTED,
                        BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_INIT_TIME,
                        SystemClock.uptimeMillis() - startTime);
            }

            // Rebild the live computer since some attributes have been rebuilt.
            // 由于一些属性已经被重建,所以要重新建立实时计算
            mLiveComputer = createLiveComputer();

        } // synchronized (mLock)
        } // synchronized (mInstallLock)
        // CHECKSTYLE:ON IndentationCheck

        mModuleInfoProvider = mInjector.getModuleInfoProvider();
        mInjector.getSystemWrapper().enablePackageCaches();

        // Now after opening every single application zip, make sure they
        // are all flushed.  Not really needed, but keeps things nice and
        // tidy.
        t.traceBegin("GC");
        VMRuntime.getRuntime().requestConcurrentGC();
        t.traceEnd();

        // The initial scanning above does many calls into installd while
        // holding the mPackages lock, but we're mostly interested in yelling
        // once we have a booted system.
        mInstaller.setWarnIfHeld(mLock);

        ParsingPackageUtils.readConfigUseRoundIcon(mContext.getResources());

        mServiceStartWithDelay = SystemClock.uptimeMillis() + (60 * 1000L);

        Slog.i(TAG, "Fix for b/169414761 is applied");

小结

  • 创建PackageInstallerService对象

  • GC回收内存

猜你喜欢

转载自blog.csdn.net/weixin_45767368/article/details/129656219