Android 11.0 PackageManagerService(一)工作原理和启动流程

1. 概述

  PackageManagerService是Android系统核心服务之一,也是Android中最常用的服务之一。它主要负责的工作如下:

    1.  解析AndroidManifest.xml文件,解析清单文件中的所有节点信息。

    2.  扫描.apk文件,安装系统应用,本地应用等。

    3.  管理本地应用,主要有:安装、卸载、应用信息查询等。

2. 核心源码

/frameworks/base/core/java/android/app/ApplicationPackageManager.java
/frameworks/base/services/java/com/android/server/SystemServer.java
/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
/frameworks/base/services/core/java/com/android/server/pm/PackageDexOptimizer.java
/frameworks/base/services/core/java/com/android/server/pm/Installer.java
/frameworks/base/services/core/java/com/android/server/pm/Settings.java
/frameworks/base/services/core/java/com/android/server/pm/permission/BasePermission.java
/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
/frameworks/base/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
/frameworks/base/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
/frameworks/base/core/java/android/content/pm/IPackageManager.aidl
/frameworks/base/core/java/android/content/pm/PackageManager.java
/frameworks/base/core/java/com/android/server/SystemConfig.java

3. PKMS架构

3.1 继承关系

客户端可通过context.getPackageManager()获得ApplicationPackageManager对象,而mPm指向的是Proxy代理,当调用到mPm的方法时,将会调用到IPackageManager的Proxy代理方法,然后通过Binder机制中的mRemote与服务端PackageManagerService通信,并调用到PackageManagerService的方法。因此,PKMS是属于Binder机制中的服务端角色。

3.2 启动过程

启动过程描述:

SystemServer启动PKMS:先是在SystemServer.startBootstrapServices()函数中启动PKMS服务,再调用startOtherServices()函数中对dex优化,磁盘管理功能,让PKMS进入SystemReady状态。

4. 启动过程

上文提到,PKMS服务由SystemServer进行启动。其启动过程具体由以下七步来完成。具体如下:

1. SystemServer启动Boot服务

调用startBootstrapServices()服务
(1) 启动Installer服务:mSystemServiceManager.startService(Installer.class);
(2) 获取设备是否加密(手机设置密码),如果设备加密了,则只解析"core"应用

String cryptState = VoldProperties.decrypt().orElse(""); 

(3) 调用PKMS.main()方法初始化PackageManagerService

PackageManagerService.main(mSystemContext,installer,mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);       
PackageManagerService m = new PackageManagerService(context, installer,
                factoryTest, onlyCore); // 构造PackageManagerService对象
ServiceManager.addService("package",m); // 把实例化出来的PKMS丢给ServiceManager进行注册
final PackageManagerNative pmn = m.new PackageManagerNative(); // 构造PackageManagerNative对象
ServiceManager.addService("package_native", pmn); // 启动package_native服务

(4) 如果设备没有加密,操作它。管理A/B OTA dexopting

if (!mOnlyCore)  // 判断是否只是核心应用

2. SystemServer启动其他服务,并使一些核心服务处于ready状态
   调用startOtherServices()方法

(5) // 如果设备没有加密,执行performDexoptUpgrade,完成dexopt优化

mPackageManagerService.updatePackagesIfNeeded();   
该方法,作用:检查是否需要去更新Packages并进行dex优化。

条件:没有OTA升级,没有大版本升级,
          没有清除过dalvik虚拟机的缓存,可以去更新Packages。
更新Packages的优先级:core app > system app > other app,调用performDexOptUpgrade()方法进行更新

(6) mPackageManagerService.performFstrimIfNeeded(); // 执行performFstrimIfNeeded(),完成磁盘维护
(7) mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService());// PackageManagerNative 准备就绪
     DefaultPermissionPolicy.grantDefaultPermissions(userId); // 启动之前授予默认所有权限

4.1.1 SystemServer.java startBootstrapServices()

说明:startBootstrapServices()首先启动Installer服务,也就是安装器,随后判断当前的设备是否是出于加密状态。如果是出于加密状态则只是解析核心应用,接着调用PackageManagerService的静态方法main来创建PKMS对象。

(1) 启动Installer对象

(2) 获取设备是否加密(手机设置密码),如果设备加密了,则只解析"core"应用。

(3) 调用PKMS main方法初始化PackageManagerService,其中调用PackageManagerService()构造方法创建了PKMS对象。

(4) 如果设备没有加密,操作它。管理A/B OTA dexopting。

源码:

private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
        
		// (1)启动Installer服务
        // 阻塞等待installed完成启动,以便有机会创建具有适当权限的关键目录,
        // 如/data/user。我们需要在初始化其他服务之前完成此任务。
        Installer installer = mSystemServiceManager.startService(Installer.class);

		// 初始化AMS
        mActivityManagerService = ActivityManagerService.Lifecycle.startService(
                mSystemServiceManager, atm);
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
		// 我们需要在初始化其他服务之前完成此任务
        mActivityManagerService.setInstaller(installer);

        // Only run "core" apps if we're encrypting the device.
        // (2).获取设备是否加密
        // 如果设备加密了,则只解析 "core" 应用
        // mOnlyCore = true,后面会频繁使用该变量进行条件判断
        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) 调用PKMS的main方法,初始化PKMS
            mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                    mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
        
		// PKMS 是否是第一次启动
        mFirstBoot = mPackageManagerService.isFirstBoot();
        // 通过context.getPackageManager()来获得PackageManager对象
        mPackageManager = mSystemContext.getPackageManager();
        
        // (4) 如果设备没有加密,操作它。管理A/B OTA dexopting
        if (!mOnlyCore) {
            boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt",
                    false);
            if (!disableOtaDexopt) {
                t.traceBegin("StartOtaDexOptService");
                try {
                    Watchdog.getInstance().pauseWatchingCurrentThread("moveab");
                    OtaDexoptService.main(mSystemContext, mPackageManagerService);
                } catch (Throwable e) {
                    reportWtf("starting OtaDexOptService", e);
                } finally {
                    Watchdog.getInstance().resumeWatchingCurrentThread("moveab");
                    t.traceEnd();
                }
            }
        }

    }

4.1.2 [SystemServer.java] startOtherServices()

说明:

(5) 执行updatePackageIfNeeded,完成dex优化

(6) 执行performFstrimIfNeeded,完成磁盘维护

(7) 调用systemReady,准备就绪

源码:

private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
        

        if (!mOnlyCore) {
            try {
                Watchdog.getInstance().pauseWatchingCurrentThread("dexopt");
				// (5) 如果设备没有加密,执行performDexoptUpgrade,完成dexopt优化
                mPackageManagerService.updatePackagesIfNeeded();
            } catch (Throwable e) {
                reportWtf("update packages", e);
            } finally {
                Watchdog.getInstance().resumeWatchingCurrentThread("dexopt");
            }
        }
       
        try {
			// (6) 执行performFstrim,完成磁盘维护
            mPackageManagerService.performFstrimIfNeeded();
        } catch (Throwable e) {
            reportWtf("performing fstrim", e);
        }
		// (7) PackageManagerService准备就绪
        mPackageManagerService.systemReady();
        
    }

我们重点分析一下第三步。也就是PKMS的main方法

4.1.3 [PackageManagerService.java] main()

main函数主要工作:

(1) 检查Package编译相关系统属性

(2) 调用PackageManagerService构造方法

(3) 启用部分应用服务于多用户场景

(4) 往ServiceManager中注册 "package" 和 "package_native'。

源码:

public static PackageManagerService main(Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {
        // Self-check for initial settings.
        // (1) 检查Package编译相关系统属性
        PackageManagerServiceCompilerMapping.checkProperties();
        
		// (2) 构造PackageManagerService对象
        PackageManagerService m = new PackageManagerService(injector, onlyCore, factoryTest);
       
        // 基于用户类型,为所有用户安装/卸载系统应用
        m.installWhitelistedSystemPackages();
		// 向ServiceManager注册PKMS(启动package服务)
        ServiceManager.addService("package", m);
		// 构造PackageManagerNative对象
        final PackageManagerNative pmn = m.new PackageManagerNative();
		// 启动package_native服务
        ServiceManager.addService("package_native", pmn);
        return m;
    }

PKMS 初始化时的核心部分为PackageManagerService的构造函数的内容,现在我们来看一下该函数。

4.2 PKMS构造函数分析

此函数由两个重要的锁(mInstallLock和mLock)和五个阶段构成。在Android 10.0源码中是由(mInstallLock和mPackages)两个锁

mInstallLock、mLock:用来保护所有安装apk的访问权限,此操作通常涉及繁重的磁盘数据读写等操作。并且是单线程操作,所以有时候会处理很慢。此锁不会在已经持有了mLock锁的情况下加锁,反之,在已经持有mInstallLock锁的情况下,立即获得mLock是安全的。

mPackages(mLock):用来解析内存中所有apk的package信息及相关状态。

PKMS服务也是通过Binder进行通信,IPackageManager.aidl由工具转换后自动生成Binder的服务端IPackageManager.Stub和客户端IPackageManager.Stub.Proxy。

Binder服务端:PackageManagerService继承自IPackageManager.Stub

Binder客户端:ApplicationPackageManager(简称APM)的成员变量mPm继承于IPackageManager.Stub.Proxy。本身APM继承与PackageManager对象。

如 3.1 中的继承关系图所示

5个阶段:

阶段一:BOOT_PROGRESS_PMS_START
阶段二:BOOT_PROGRESS_PMS_SYSTEM_SCAN_START
阶段三:BOOT_PROGRESS_PMS_DATA_SCAN_START
阶段四:BOOT_PROGRESS_PMS_SCAN_END
阶段五:BOOT_PROGRESS_PMS_READY

4.2.1 [PackageManagerService.java]

说明:IPackageManager.Stub是IPackageManager.aidl自动生成的,正好也说明了PKMS是service端的,通过binder交互

源码:


public class PackageManagerService extends IPackageManager.Stub
        implements PackageSender {
}

4.2.2 [PackageManagerService.java]   PackageManagerService()

说明:PackageManagerService构造函数

源码:

public PackageManagerService(Context context, Installer installer,
        boolean factoryTest, boolean onlyCore) {
        ...
        //阶段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);
        ...
        
        //阶段3:BOOT_PROGRESS_PMS_DATA_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());
}

4.2.3 阶段1:BOOT_PROGRESS_PMS_START

主要工作:

(1) 构造 DisplayMetrics,保存分辨率相关信息。

(2) 创建Installer对象,与installd交互

(3) 创建mPermissionManager对象,进行权限管理

(4) 构造Settings类,保存安装包信息,清除路径不存在的孤立应用,主要涉及/data/system/目录的packages.xml,
     packages-backup.xml,packages.list,packages-stopped.xml,packages-stopped-backup.xml等文件。
(5) 构造PackageDexOptimizer及DexManager类,处理dex优化;
(6) 创建SystemConfig实例,获取系统配置信息,配置共享lib库;
(7) 创建PackageManager的Handler线程,循环处理外部安装相关消息。

源码:

public PackageManagerService(Injector injector, boolean onlyCore, boolean factoryTest) {
        
		// 第一阶段
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
                SystemClock.uptimeMillis());
		// mSdkVersion是编译的SDK版本
        if (mSdkVersion <= 0) {
            Slog.w(TAG, "**** ro.build.version.sdk not set!");
        }

        mFactoryTest = factoryTest;	// 假设为false,即运行在非工厂模式下
        mOnlyCore = onlyCore;// 假设为false,即运行在普通模式下。标记是否只加载核心服务
        // (1) mMetrics用于存储与显示屏相关的一些属性,例如屏幕的宽高尺寸、分辨率等信息
        mMetrics = new DisplayMetrics();
		// (2) 构建Installer对象,与installed交互
        mInstaller = injector.getInstaller();

        
		// 本地服务
        LocalServices.addService(PackageManagerInternal.class, mPmInternal);
		// 构建多用户管理服务
        mUserManager = injector.getUserManagerService();
        mComponentResolver = injector.getComponentResolver();
		// (3) 构建权限管理服务
        mPermissionManager = injector.getPermissionManagerServiceInternal();
		// 创建Settings对象,Settings是一个非常重要的类,用于存储系统运行过程中的一些设置
        mSettings = injector.getSettings();
        
		// (4)构造Settings类,保存安装包信息,清除路径不存在的孤立应用,主要涉
		// 及/data/system/目录的packages.xml,packages-backup.xml, packages.list,
		// packages-stopped.xml,packages-stopped-backup.xml等文件。
		// 添加system,phone,log,nfc,bluetooth,shell,se,networkstack这八种shareUserId到settings对象中
        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);
        
		// (5)构造PackageDexOptimizer及DexManager类,处理dex优化
        mPackageDexOptimizer = new PackageDexOptimizer(mInstaller, mInstallLock, mContext,
                "*dexopt*");
        mDexManager =
                new DexManager(mContext, this, mPackageDexOptimizer, mInstaller, mInstallLock);
		// 创建ATR虚拟机管理服务
        mArtManagerService = new ArtManagerService(mContext, this, mInstaller, mInstallLock);
        
		// 获取默认分辨率
        getDefaultDisplayMetrics(mInjector.getDisplayManager(), mMetrics);

		// (6)创建SystemConfig实例,获取系统配置信息,配置共享lib库;
        //拿到SystemConfig()的对象,其中会调用SystemConfig的readPermissions()完成权限的读取
        SystemConfig systemConfig = SystemConfig.getInstance();        
        // CHECKSTYLE:OFF IndentationCheck
        synchronized (mInstallLock) {
        // writer
        synchronized (mLock) {
            //(7)创建PackageManager的handler线程,循环处理外部安装相关消息
        	//启动PackageManager线程,负责apk的安装、卸载
            mHandlerThread = new ServiceThread(TAG,
                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
            mHandlerThread.start();
			// 应用Handler
            mHandler = new PackageHandler(mHandlerThread.getLooper());
			// 进程记录handler
            mProcessLoggingHandler = new ProcessLoggingHandler();
			// WatchDog监听ServiceThread是否超时:10分钟
            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
			// Instant应用注册
            mInstantAppRegistry = new InstantAppRegistry(this);

			// 共享lib库配置
            ArrayMap<String, SystemConfig.SharedLibraryEntry> libConfig
                    = systemConfig.getSharedLibraries();
            final int builtInLibCount = libConfig.size();
            for (int i = 0; i < builtInLibCount; i++) {
                String name = libConfig.keyAt(i);
                SystemConfig.SharedLibraryEntry entry = libConfig.valueAt(i);
                addBuiltInSharedLibraryLocked(entry.filename, name);
            }         

			// 读取安装SELinux相关策略
            SELinuxMMAC.readInstallPolicy();
			// 返回栈加载
            FallbackCategoryProvider.loadFallbacks();

			// 读取并解析/data/system下的XML文件
			
            mFirstBoot = !mSettings.readLPw(mInjector.getUserManagerInternal().getUsers(false));

            // Clean up orphaned packages for which the code path doesn't exist
            // and they are an update to a system app - caused by bug/32321269
            // 清理代码路径不存在的孤立软件包
            final int packageSettingCount = mSettings.mPackages.size();
            for (int i = packageSettingCount - 1; i >= 0; i--) {
                PackageSetting ps = mSettings.mPackages.valueAt(i);
                if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
                        && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
                    mSettings.mPackages.removeAt(i);
                    mSettings.enableSystemPackageLPw(ps.name);
                }
            }
			// 如果不是首次启动,也不是CORE应用,则拷贝预编译的DEX文件
            if (!mOnlyCore && mFirstBoot) {
                requestCopyPreoptedFiles();
            }
            
            ......

         }    // synchronized (mPackages)

        }
    }

readLPw()会扫描下面5个文件

1) "/data/system/packages.xml"                                       // 所有安装app信息

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信息的备份的信息记录

5个文件共分为三组,简单的作用描述如下:

1. packages.xml: PKMS扫描完成目标文件夹之后会创建该文件。当系统进行程序安装、卸载和更新等操作时,均会更新该文件。该文件保存了系统中与 package相关的一些信息。

2. packages.list: 描述系统中存在的所有非系统自带的apk的信息。当这些程序有变动时 PKMS 就会更新该文件。

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

这些目录的指向,都在settings中的构造函数中完成,如下所示,得到目录后调用readLpw()进行扫描。

看一下settings的构造函数(package com.android.server.pm)

源码:

Settings(File dataDir, PermissionSettings permission,
            Object lock) {
        mLock = lock;
        mPermissions = permission;
        mRuntimePermissionsPersistence = new RuntimePermissionPersistence(mLock);

        mSystemDir = new File(dataDir, "system");				//mSystemDir指向目录"/data/system"
        mSystemDir.mkdirs();		//创建 "/data/system"
        // 设置权限
        FileUtils.setPermissions(mSystemDir.toString(),
                FileUtils.S_IRWXU|FileUtils.S_IRWXG
                |FileUtils.S_IROTH|FileUtils.S_IXOTH,
                -1, -1);
		//(1)指向目录"/data/system/packages.xml"
        mSettingsFilename = new File(mSystemDir, "packages.xml");
		//(2)指向目录"/data/system/packages-backup.xml"
        mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml");
		//(3)指向目录"/data/system/packages.list"
        mPackageListFilename = new File(mSystemDir, "packages.list");
        FileUtils.setPermissions(mPackageListFilename, 0640, SYSTEM_UID, PACKAGE_INFO_GID);

        final File kernelDir = new File("/config/sdcardfs");
        mKernelMappingFilename = kernelDir.exists() ? kernelDir : null;

        // Deprecated: Needed for migration
        //(4)指向目录"/data/system/packages-stopped.xml"
        mStoppedPackagesFilename = new File(mSystemDir, "packages-stopped.xml");
		//(5)指向目录"/data/system/packages-stopped-backup.xml"
        mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml");
    }

解析上面这几个xml的内容,建立对应的数据结构
 

Setting.java

boolean readLPw(@NonNull List<UserInfo> users) {
        FileInputStream str = null;   
        if (str == null) {
         
           str = new FileInputStream(mSettingsFilename);
        }
	    // 解析 "/data/system/packages.xml
        XmlPullParser parser = Xml.newPullParser();
        parser.setInput(str, StandardCharsets.UTF_8.name());

        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;
                }
				// 根据xml的各个节点进行各种操作,例如读取权限、shared-user等
                String tagName = parser.getName();
                if (tagName.equals("package")) {
                    readPackageLPw(parser);
                } 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);
                } .....

            str.close();       

        for (int i = 0; i < N; i++) {
            final PackageSetting p = mPendingPackages.get(i);
            final int sharedUserId = p.getSharedUserId();
            final Object idObj = getSettingLPr(sharedUserId);
            if (idObj instanceof SharedUserSetting) {
				// 创建SharedUserSetting对象并添加到Settings的成员变量mSharedUsers中,
				// 在Android系统中,多个Package通过设置SharedUserId属性可以运行在同一个进程,共享同一个UID
                final SharedUserSetting sharedUser = (SharedUserSetting) idObj;
                p.sharedUser = sharedUser;
                p.appId = sharedUser.userId;
                addPackageSettingLPw(p, sharedUser);
            }

        return true;
    }

说明:创建 SharedUserSetting 对象并添加到 Settings 的成员变量 mSharedUsers 中,在 Android 系统中,多个 package 通过设置 sharedUserId 属性可以运行在同一个进程,共享同一个 UID。

源码:

mSettings.addSharedUserLPw("android.uid.system", // 字符串
                            Process.SYSTEM_UID, //系统进程使用的用户id,值为1000
                            ApplicationInfo.FLAG_SYSTEM, //标志系统 Package
                            ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); //特权系统应用  

 SharedUserSetting addSharedUserLPw(String name, int uid, int pkgFlags, int pkgPrivateFlags) {
    	// mSharedUsers是一个HashMap,key是字符串,值为 SharedUserSetting对象
        SharedUserSetting s = mSharedUsers.get(name);
        if (s != null) {
            if (s.userId == uid) {
                return s;
            }
            PackageManagerService.reportSettingsProblem(Log.ERROR,
                    "Adding duplicate shared user, keeping first: " + name);
            return null;
        }
		// 创建一个 SharedUserSetting对象,并设置userId为UID
        s = new SharedUserSetting(name, pkgFlags, pkgPrivateFlags);
        s.userId = uid;
        if (registerExistingAppIdLPw(uid, s, name)) {
            mSharedUsers.put(name, s);// 将name与键值对添加到mSharedUsers中保存
            return s;
        }
        return null;
    }

4.2.4 阶段2:BOOT_PROGRESS_PMS_SYSTEM_SCAN_START

主要工作:

(1) 从init.rc中获取环境变量BOOTCLASSPATH和SYSTEMSERVERCLASSPATH;

(2) 对于旧版本升级的情况,将安装时获取权限变更为运行时申请权限;

(3) 扫描system/vendor/product/odm/oem等目录的priv-app、app、overlay包;

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

源码:

public PackageManagerService(Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {
           // 记录扫描开始时间
           long startTime = SystemClock.uptimeMillis();

           // 第二阶段
           EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
                    startTime);
			// 获取环境变量,init.rc
            final String bootClassPath = System.getenv("BOOTCLASSPATH");
            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
            
			// 获取system/frameworks目录
            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
			// 获取内部版本
            final VersionInfo ver = mSettings.getInternalVersion();
			// 判断fingerprint是否更新
            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);           
            // 对于Android M之前版本升级上来的情况,需要将系统应用程序权限从安装升级到运行时
            mPromoteSystemApps =
                    mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
            
            // 对于Android N之前版本升级上来的情况,需要像首次启动一样处理package
            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;

            // 在扫描之前保存预先存在的系统Package的名称,这样我们可以确定哪些系统包在升级后是全新的。
            if (isDeviceUpgrading()) {
                mExistingPackages = new ArraySet<>(mSettings.mPackages.size());
                for (PackageSetting ps : mSettings.mPackages.values()) {
                    mExistingPackages.add(ps.name);
                }
            }
			// 准备解析Package的缓存
            mCacheDir = preparePackageParserCache();

            // Set flag to monitor and not change apk file paths when
            // scanning install directories.
            // 设置Flag,而不在扫描安装时更改文件路径
            int scanFlags = SCAN_BOOTING | SCAN_INITIAL;

            // 在Android 10.0 中,此处会扫描以下路径
            //扫描以下路径:/vendor/overlay、/product/overlay、/product_services/overlay、                  
            // /odm/overlay、/oem/overlay、/system/framework、/system/priv-app、
            // /system/app、/vendor/priv-app、/vendor/app、/odm/priv-app、/odm/app、
            // /oem/app、/oem/priv-app、/product/priv-app、/product/app、
            // /product_services/priv-app、/product_services/app、
            // /product_services/priv-app
            for (int i = mDirsToScanAsSystem.size() - 1; i >= 0; i--) {
                final ScanPartition partition = mDirsToScanAsSystem.get(i);
                if (partition.getOverlayFolder() == null) {
                    continue;
                }
				// 扫描overlay包
                scanDirTracedLI(partition.getOverlayFolder(), systemParseFlags,
                        systemScanFlags | partition.scanFlag, 0,
                        packageParser, executorService);
            }

            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) {
					// 扫描priv-app路径
                    scanDirTracedLI(partition.getPrivAppFolder(), systemParseFlags,
                            systemScanFlags | SCAN_AS_PRIVILEGED | partition.scanFlag, 0,
                            packageParser, executorService);
                }
				// 扫描app路径
                scanDirTracedLI(partition.getAppFolder(), systemParseFlags,
                        systemScanFlags | partition.scanFlag, 0,
                        packageParser, executorService);
            }

            
			// 删掉不存在的package
            if (!mOnlyCore) {
                // do this first before mucking with mPackages for the "expecting better" case
                final Iterator<AndroidPackage> pkgIterator = mPackages.values().iterator();
                while (pkgIterator.hasNext()) {
                    final AndroidPackage pkg = pkgIterator.next();
                    if (pkg.isStub()) {
                        stubSystemApps.add(pkg.getPackageName());
                    }
                }

                final Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
                while (psit.hasNext()) {
                    PackageSetting ps = psit.next();
                  
                    // 如果不是系统应用,则不被允许禁用其他应用
                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
                        continue;
                    }
                    
                    // 如果应用被扫描,则不允许被擦除
                    final AndroidPackage scannedPkg = mPackages.get(ps.name);
                    if (scannedPkg != null) {
                       
                        // 如果系统应用被扫描,且存在于disable应用列表中,那它一定是通过OTA添加的
                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
                            logCriticalInfo(Log.WARN,
                                    "Expecting better updated system app for " + ps.name
                                    + "; removing system app.  Last known"
                                    + " codePath=" + ps.codePathString
                                    + ", versionCode=" + ps.versionCode
                                    + "; scanned versionCode=" + scannedPkg.getLongVersionCode());
                            removePackageLI(scannedPkg, true);
                            mExpectingBetter.put(ps.name, ps.codePath);
                        }

                        continue;
                    }

            // 删除没有关联应用的共享UID标识
            mSettings.pruneSharedUsersLPw();
            

    ......

}

4.2.5 阶段3:BOOT_PROGRESS_PMS_DATA_SCAN_START

主要工作有:对于不仅仅解析核心应用的情况下,还处理data目录的应用信息,及时更新,去除不必要的数据。

源码:

PackageManagerService.packageManagerService()

if (!mOnlyCore) {
	// 第三阶段
    EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
                        SystemClock.uptimeMillis());              

            
    // 移除通过OTA删除的更新系统应用程序的禁用package设置
    // 如果更新不存在,则完全删除该应用。否则,撤销其系统权限
    for (int i = possiblyDeletedUpdatedSystemApps.size() - 1; i >= 0; --i) {
         final String packageName = possiblyDeletedUpdatedSystemApps.get(i);
         final AndroidPackage pkg = mPackages.get(packageName);
         final String msg;

         mSettings.removeDisabledSystemPackageLPw(packageName);
        
         .....

     }

                
     // 确保期望在userdata分区上显示的所有系统应用程序实际显示了。
     // 如果从未出现过,需要回滚以恢复系统版本
     for (int i = 0; i < mExpectingBetter.size(); i++) {
         final String packageName = mExpectingBetter.keyAt(i);
         if (!mPackages.containsKey(packageName)) {
                        
             mSettings.enableSystemPackageLPw(packageName);

             try {
				  // 扫描APK
                  scanPackageTracedLI(scanFile, reparseFlags, rescanFlags, 0, null);
             } catch (PackageManagerException e) {
                  Slog.e(TAG, "Failed to parse original system package: "
                                    + e.getMessage());
             }
         }
      }

      // 解压缩并安装任何存根系统应用程序。必须最后执行此操作以确保禁用或替换所有存根
      installSystemStubPackages(stubSystemApps, scanFlags);
                
      ......

      // Resolve the storage manager.
      // 获取Storage manager包名
      mStorageManagerPackage = getStorageManagerPackageName();
            
      // 解决受保护的action过滤器。只允许setup wizard(开机向导)为这些action设置高优先级过滤器
      mSetupWizardPackage = getSetupWizardPackageNameImpl();
            
      // 更新客户端,以确保持有正确的共享库路径
      updateAllSharedLibrariesLocked(null, null, Collections.unmodifiableMap(mPackages));

      ......

      // 读取并更新要保留的package的上次使用时间
      mPackageUsage.read(mSettings.mPackages);
      mCompilerStats.read();
}

4.2.6 阶段4:BOOT_PROGRESS_PMS_SCAN_END

主要工作:

(1) sdk版本变更,更新权限;

(2) OTA升级后首次启动,清除不必要的缓存数据;

(3) 权限等默认项更新完后,清理相关数据;

(4) 更新package.xml

源码:

PackageManagerService.packageManager()

// 第四阶段
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,SystemClock.uptimeMillis());

// 如果自上次启动以来,平台SDK已改变,则需要重新授予应用程序权限以捕获出现的任何新权限
final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
if (sdkUpdated) {
   
     mPermissionManager.updateAllPermissions(StorageManager.UUID_PRIVATE_INTERNAL, sdkUpdated);
     ver.sdkVersion = mSdkVersion;
            
     // 如果这是第一次启动或这是来自Android M之前的版本升级,并且它是正常启动,
     // 那需要在所有已定义的用户初始化默认的首选应用程序
     if (!mOnlyCore && (mPromoteSystemApps || mFirstBoot)) {
          for (UserInfo user : mInjector.getUserManagerInternal().getUsers(true)) {
                mSettings.applyDefaultPreferredAppsLPw(user.id);
                primeDomainVerificationsLPw(user.id);
          }
     }
     // 在启动期间尽早为系统用户准备存储,因为像SettingsProvider和systemUI这样的核心系统应用程序无法等待用户启动
     final int storageFlags;
     if (StorageManager.isFileEncryptedNativeOrEmulated()) {
          storageFlags = StorageManager.FLAG_STORAGE_DE;
     } else {
          storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
     }
     // 如果是在OTA之后首次启动,并且正常启动,那需要清除代码缓存目录,但不清除应用程序配置文件
     if (mIsUpgrade && !mOnlyCore) {
         Slog.i(TAG, "Build fingerprint changed; clearing code caches");
         for (int i = 0; i < mSettings.mPackages.size(); i++) {
              final PackageSetting ps = mSettings.mPackages.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;
     }
     // 安装Android-Q前的非系统应用程序在Luncher中隐藏他们的图标
     if (!mOnlyCore && mIsPreQUpgrade) {
         Slog.i(TAG, "Whitelisting all existing apps to hide their icons");
         int size = mSettings.mPackages.size();
         for (int i = 0; i < size; i++) {
              final PackageSetting ps = mSettings.mPackages.valueAt(i);
              if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
                   continue;
              }
                    
              ps.disableComponentLPw(PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME,
                     UserHandle.USER_SYSTEM);
         }
     }
     // 仅在权限或其他默认配置更新后清除
     mPromoteSystemApps = false;

     // All the changes are done during package scanning.
     // 所有变化都在扫描过程中完成
     ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;

     // can downgrade to reader
     // 降级读取
     

4.2.7 阶段5:BOOT_PROGRESS_PMS_READY

主要工作有:

(1)创建PackageInstallerService对象

(2)GC回收内存

源码:

// 第五阶段
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
         SystemClock.uptimeMillis());

// PermissionController 包含磨人的授予和角色管理,所以它是一个核心系统的关键部分
mRequiredPermissionControllerPackage = getRequiredPermissionControllerLPr();
            
.......

updateInstantAppInstallerLocked(null);
           
// 阅读并更新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);
    }
} // synchronized (mLock)
} // synchronized (mInstallLock)
        
......        

// 打开应用之后,及时的回收处理
Runtime.getRuntime().gc();

4.3 dex 优化

    检查是否需要去更新Packages并进行dex优化,如果没有OTA升级、没有大版本升级、没有清楚过dalvik虚拟机的缓存,可以去更新packages。

上面我们在分析PKMS启动过程的时候说到了七个步骤,其中第五步就是dex文件优化。

这一过程的调用流程如下:

4.3.1 [PackageManagerService.java] updatePackagesIfNeeded()

说明:

检查是否需要更新Packages并进行dex优化,如果没有OTA升级,没有大版本升级、没有清除过dalvik虚拟机的缓存可以去更新Packages。

更新Packages的优先级:core app > system app > other app,调用 performDexOptUpgrade()进行更新。

源码:

    @Override
    public void updatePackagesIfNeeded() {
        // 只有system或是root用户才有权限请求 package update
        enforceSystemOrRoot("Only the system can request package update");
       
        // (1) 判断有没有进行OTA升级,我们需要在OTA后重新获取
        boolean causeUpgrade = isDeviceUpgrading();

        // (2) 是否是第一次启动或是系统大版本升级
        boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;

        // (3) 判断是否清除过Dalvik虚拟机的缓存。我们需要在删除缓存后重新提取,因为AoT-ed文件将过期
        boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
		// (4) 如果上面三个判断都没有,那么就不做任何操作
        if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
            return;
        }

        List<PackageSetting> pkgSettings;
        synchronized (mLock) {
			// 按照Package的优先级进行排序,core app > system app > other app
            pkgSettings = PackageManagerServiceUtils.getPackagesForDexopt(
                    mSettings.mPackages.values(), this);
        }

		// 记录开始的时间
        final long startTime = System.nanoTime();
		// 执行performDexOptUpgrade方法,完成dex优化
        final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
                    causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT,
                    false /* bootComplete */);

        ......
    }

4.3.2  [PackageManagerService.java] performDexOptUpgrade()

说明:判断是否需要对Package进行更新,如果需要更新那么按照优先级完成dex优化,最终调用Installer的dexopt()进行dex优化。

源码:

private int[] performDexOptUpgrade(List<AndroidPackage> pkgs, boolean showDialog,
            final int compilationReason, boolean bootComplete) {


		// 循环取出Packages,进行优化
        for (AndroidPackage pkg : pkgs) {
            numberOfPackagesVisited++;

            boolean useProfileForDexopt = false;
			// 第一次启动或是OTA升级之后并且是系统应用才会进行odex
            if ((isFirstBoot() || isDeviceUpgrading()) && pkg.isSystem()) {
                
                .......
                    
            }

            ......            

			// 最终是调用mInstaller.dexopt 完成优化的,instal的守护进程Installer安装器和Installed通信
            int primaryDexOptStaus = performDexOptTraced(new DexoptOptions(
                    pkg.getPackageName(),
                    pkgCompilationReason,
                    dexoptFlags));

            switch (primaryDexOptStaus) {
                case PackageDexOptimizer.DEX_OPT_PERFORMED:
                    numberOfPackagesOptimized++;				// odex优化完成的应用
                    break;
                case PackageDexOptimizer.DEX_OPT_SKIPPED:
                    numberOfPackagesSkipped++;					// 跳过的应用
                    break;
                case PackageDexOptimizer.DEX_OPT_FAILED:
                    numberOfPackagesFailed++;					// 失败的应用
                    break;
                default:
                    Log.e(TAG, "Unexpected dexopt return code " + primaryDexOptStaus);
                    break;
            }
        }

        return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
                numberOfPackagesFailed };
    }

4.3.3 [PackageManagerService.java] performDexOptInternal()

源码:

    // 在给定的包上执行dex优化。如果dexopt没有失败则返回true,
    // 也就是说,对于给定的过滤器,现在就可以认定位包是最新的
    private int performDexOptInternal(DexoptOptions options) {

        .....

        try {
            synchronized (mInstallLock) {
                // 执行performDexOptInternalWithDependenciesLI
                return performDexOptInternalWithDependenciesLI(p, pkgSetting, options);
            }
        } finally {
            Binder.restoreCallingIdentity(callingId);
        }
    }

在perormDexOptInternalWithDependenciesLI方法中,最终调用了PackageDexOptimizer.performDexOpt方法。

4.3.4 [PackageDexOptimizer.java] performDexOpt()

源码:

    // 在指定包的所有代码路径和库上执行dexopt
    int performDexOpt(AndroidPackage pkg, @NonNull PackageSetting pkgSetting,
            String[] instructionSets, CompilerStats.PackageStats packageStats,
            PackageDexUsage.PackageUseInfo packageUseInfo, DexoptOptions options) {

        ......       

        synchronized (mInstallLock) {
            final long acquireTime = acquireWakeLockLI(pkg.getUid());
            try {
                // 执行performDexoptLI
                return performDexOptLI(pkg, pkgSetting, instructionSets,
                        packageStats, packageUseInfo, options);
            } finally {
                releaseWakeLockLI(acquireTime);
            }
        }
    }

该方法作用就是在指定包的所有代码路径和库上执行dexopt。最终会继续调用performDexOptLI方法。

4.3.5 [PackageDexOptimizer.java] performDexOptLI()

源码:

    // 对给定包的所有路径执行dexopt
    // 假装mInstallLock已经被持有
    @GuardedBy("mInstallLock")
    private int performDexOptLI(AndroidPackage pkg, @NonNull PackageSetting pkgSetting,
            String[] targetInstructionSets, CompilerStats.PackageStats packageStats,
            PackageDexUsage.PackageUseInfo packageUseInfo, DexoptOptions options) {
        
            ......

            for (String dexCodeIsa : dexCodeInstructionSets) {
                // 执行dexoptPath方法
                int newResult = dexOptPath(pkg, pkgSetting, path, dexCodeIsa, compilerFilter,
                        profileUpdated, classLoaderContexts[i], dexoptFlags, sharedGid,
                        packageStats, options.isDowngrade(), profileName, dexMetadataPath,
                        options.getCompilationReason());
                // The end result is:
                //  - FAILED if any path failed,
                //  - PERFORMED if at least one path needed compilation,
                //  - SKIPPED when all paths are up to date
                if ((result != DEX_OPT_FAILED) && (newResult != DEX_OPT_SKIPPED)) {
                    result = newResult;
                }
            }
        }
        return result;
    }

对于dexOptPath方法,就是在属于当前包的路径上执行dexopt操作。并最终调到了Installer.dexopt()。

4.4 磁盘维护

磁盘维护是在SystemServer.startOtherServices()方法中,通过调用PKMS的performFstrimIfNeeded()方法开始的。

调用过程如下:

4.4.1 [PackageManagerService.java] performFstrimIfNeeded()

说明:主要是执行磁盘清理工作,释放磁盘空间

源码:

// 磁盘守护。主要是执行磁盘清理工作,释放磁盘空间
    @Override
    public void performFstrimIfNeeded() {
    	// 只有system或是root用户才有权限请求fstrim
        enforceSystemOrRoot("Only the system can request fstrim");
        
        // 在其他事情之前,看看我们是否需要fstrim
        try {
			// 获取StorageManager对象
            IStorageManager sm = PackageHelper.getStorageManager();
            if (sm != null) {
                boolean doTrim = false;
				// 获取执行FSTRIM时间间隔,默认是3天,可以通过setting provider更改这个时间
                final long interval = android.provider.Settings.Global.getLong(
                        mContext.getContentResolver(),
                        android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
                        DEFAULT_MANDATORY_FSTRIM_INTERVAL);
                if (interval > 0) {
                    final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
                    if (timeSinceLast > interval) {
                        doTrim = true;		// 如果时间超过了三天就进行磁盘清理
                        Slog.w(TAG, "No disk maintenance in " + timeSinceLast
                                + "; running immediately");
                    }
                }
                if (doTrim) {
                    final boolean dexOptDialogShown;
                    synchronized (mLock) {
                        dexOptDialogShown = mDexOptDialogShown;
                    }
					// 如果不是第一次启动,显示一个提示框
                    if (!isFirstBoot() && dexOptDialogShown) {
                        try {
                            ActivityManager.getService().showBootMessage(
                                    mContext.getResources().getString(
                                            R.string.android_upgrading_fstrim), true);
                        } catch (RemoteException e) {
                        }
                    }
					// 这里的sm是 StorageManagerService,发送消息H_FSTRIM给Handler,然后向vold发送fstrim命令
                    sm.runMaintenance();
                }
            } else {
                Slog.e(TAG, "storageManager service unavailable!");
            }
        } catch (RemoteException e) {
            // Can't happen; StorageManagerService is local
        }
    }

4.4.2 [StorageManagerService] runMaintenance()

源码:

@Override
public void runMaintenance() {
    enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
    runIdleMaintenance(null);
}

void runIdleMaintenance(Runnable callback) {
    mHandler.sendMessage(mHandler.obtainMessage(H_FSTRIM, callback));
}

class StorageManagerServiceHandler extends Handler {
        public StorageManagerServiceHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
               
                ......

                case H_FSTRIM: {
                
                    ......    
                    // 调用fstrim方法
                    fstrim(0, null);

                    break;
        }
    }

4.4.3 [StorageManagerService] fstrim()

源码:

    @Override
    public void fstrim(int flags, IVoldTaskListener listener) {
        

       
            // 基于块的检查点进行进行fstrim。因此,如果检查点正在进行(OTA后的第一次启动),
            // 我们跳过空闲维护,并确保最后的fstrim时间仍然更新。如果基于文件的检查点,
            // 我们将运行空闲维护(GC fstrim),而不考虑检查点的状态。
            if (!needsCheckpoint() || !supportsBlockCheckpoint()) {
                // 最终会执行到vold进程的fstrim
                mVold.fstrim(flags, new IVoldTaskListener.Stub() {
                   
                .......
        
    }

4.5 PKMS 准备就绪

[PackageManagerService.java] systemReady()

说明:systemReady主要完成的是默认授权和更新package的信息,通知在等待pms的一些组件

源码:

@Override
    public void systemReady() {
    	//只有system或是root用户才有权限 声称system已经ready
        enforceSystemOrRoot("Only the system can claim the system is ready");

        
        ContentObserver co = new ContentObserver(mHandler) {
            。。。。。。
        };
        
		// 注册一个监听
        co.onChange(true);
        
        ......

        synchronized (mLock) {
            
            ArrayList<PreferredActivity> removed = new ArrayList<>();
            for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
                PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
                removed.clear();
                for (PreferredActivity pa : pir.filterSet()) {
                    if (!mComponentResolver.isActivityDefined(pa.mPref.mComponent)) {
                        removed.add(pa);
                    }
                }
				// 移除不存在的先前用户设置保存的优先选择的activity组件
                if (removed.size() > 0) {
                    for (int r=0; r<removed.size(); r++) {
                        PreferredActivity pa = removed.get(r);
                        Slog.w(TAG, "Removing dangling preferred activity: "
                                + pa.mPref.mComponent);
                        pir.removeFilter(pa);
                    }
                    mSettings.writePackageRestrictionsLPr(
                            mSettings.mPreferredActivities.keyAt(i));		// 写入到文件中
                }
            }
        }

        mUserManager.systemReady();			// 多用户服务 systemReady

        // Now that we've scanned all packages, and granted any default
        // permissions, ensure permissions are updated. Beware of dragons if you
        // try optimizing this.
        synchronized (mLock) {
            // 更新权限信息
            mPermissionManager.updateAllPermissions(StorageManager.UUID_PRIVATE_INTERNAL, false);

            final PermissionPolicyInternal permissionPolicyInternal =
                    mInjector.getPermissionPolicyInternal();
            permissionPolicyInternal.setOnInitializedCallback(userId -> {
                // The SDK updated case is already handled when we run during the ctor.
                synchronized (mLock) {
                    mPermissionManager.updateAllPermissions(
                            StorageManager.UUID_PRIVATE_INTERNAL, false);
                }
            });
        }

        // Watch for external volumes that come and go over time
        
        //注意随时间变化的外部存储设备
        final StorageManager storage = mInjector.getStorageManager();
        storage.registerListener(mStorageListener);

        mInstallerService.systemReady();
        mPackageDexOptimizer.systemReady();

        mInjector.getStorageManagerInternal().addExternalStoragePolicy(
                new StorageManagerInternal.ExternalStorageMountPolicy() {
            @Override
            public int getMountMode(int uid, String packageName) {
                if (Process.isIsolated(uid)) {
                    return Zygote.MOUNT_EXTERNAL_NONE;
                }
                if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
                }
                if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
                    return Zygote.MOUNT_EXTERNAL_READ;
                }
                return Zygote.MOUNT_EXTERNAL_WRITE;
            }

            @Override
            public boolean hasExternalStorage(int uid, String packageName) {
                return true;
            }
        });

        // Now that we're mostly running, clean up stale users and apps
        // 清除过期的userId和app
        mUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
        reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);

        mPermissionManager.systemReady();

        if (mInstantAppResolverConnection != null) {
            mContext.registerReceiver(new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    mInstantAppResolverConnection.optimisticBind();
                    mContext.unregisterReceiver(this);
                }
            }, new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
        }

        IntentFilter overlayFilter = new IntentFilter(Intent.ACTION_OVERLAY_CHANGED);
        overlayFilter.addDataScheme("package");
        mContext.registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (intent == null) {
                    return;
                }
                Uri data = intent.getData();
                if (data == null) {
                    return;
                }
                String packageName = data.getSchemeSpecificPart();
                if (packageName == null) {
                    return;
                }
                AndroidPackage pkg = mPackages.get(packageName);
                if (pkg == null) {
                    return;
                }
                sendPackageChangedBroadcast(pkg.getPackageName(),
                        true /* dontKillApp */,
                        new ArrayList<>(Collections.singletonList(pkg.getPackageName())),
                        pkg.getUid(),
                        Intent.ACTION_OVERLAY_CHANGED);
            }
        }, overlayFilter);

        mModuleInfoProvider.systemReady();

        // Installer service might attempt to install some packages that have been staged for
        // installation on reboot. Make sure this is the last component to be call since the
        // installation might require other components to be ready.
        mInstallerService.restoreAndApplyStagedSessionIfNeeded();

        mExistingPackages = null;
    }

至此,PKMS的启动过程就分析完了。

猜你喜欢

转载自blog.csdn.net/zhourui_1021/article/details/115145032