PMS-启动过程解读

416 阅读12分钟

介绍

PackageManagerService(简称PKMS),是Android系统中核心服务之一,管理着所有跟package相关的工作,常见的有安装应用,卸载应用,应用信息查询。PKMS服务也是通过binder进行通信,IPackageManager.aidl由工具转换后自动生成binder的服务端IPackageManager.Stub和客户端IPackageManager.Stub.Proxy

image.png

Binder服务端:PackageManagerService继承于IPackageManager.Stub Binder客服端:ApplicationPackageManager(APM)是继承于PackageManager

PKMS的职责

  • 负责Android系统中Package的安装,升级,卸载
  • 对外提供统一的信息查询功能,其中包括查询系统中匹配的intent的activity,BroadCastReceiver或者Service等

PKMS启动过程

PKMS服务是在systemServer进程中启动的,它属于引导服务

private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
    ...
    t.traceBegin("StartInstaller");
    Installer installer = mSystemServiceManager.startService(Installer.class);
    t.traceEnd();
    // Activity manager runs the show.
    t.traceBegin("StartActivityManager");
    // TODO: Might need to move after migration to WM.
    ActivityTaskManagerService atm = mSystemServiceManager.startService(
            ActivityTaskManagerService.Lifecycle.class).getService();
    mActivityManagerService = ActivityManagerService.Lifecycle.startService(
            mSystemServiceManager, atm);
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    mActivityManagerService.setInstaller(installer);
    mWindowManagerGlobalLock = atm.getGlobalLock();
    t.traceEnd(); 
    // Start the package manager.
    if (!mRuntimeRestart) {
        FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
                FrameworkStatsLog
                        .BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__PACKAGE_MANAGER_INIT_START,
                SystemClock.elapsedRealtime());
    }

    t.traceBegin("StartPackageManagerService");
    try {
        Watchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain");
        mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
    } finally {
        Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain");
    }
    ...
}

进入PackageManagerService类中的main方法

public static PackageManagerService main(Context context, Installer installer,
        boolean factoryTest, boolean onlyCore) {
    ...
    PackageManagerService m = new PackageManagerService(injector, onlyCore, factoryTest);
    ...
    ServiceManager.addService("package", m);
    final PackageManagerNative pmn = m.new PackageManagerNative();
    ServiceManager.addService("package_native", pmn);
    return m;
}

main方法主要做两件事

  1. 创建PackageManagerService并向ServiceManager注册
  2. 创建PackageManagerNative并向ServiceManager注册

PackageManagerService的构造方法的代码量很大,我们大致可以把它分为几个阶段

  1. 开始阶段 BOOT_PROGRESS_PMS_START
  2. 系统扫描阶段 BOOT_PROGRESS_PMS_SYSTEM_SCAN_START
  3. Data扫描阶段 BOOT_PROGRESS_PMS_DATA_SCAN_START
  4. 扫描结束 BOOT_PROGRESS_PMS_SCAN_END
  5. 就绪阶段 BOOT_PROGRESS_PMS_READY
开始阶段 BOOT_PROGRESS_PMS_START
public PackageManagerService(Injector injector, boolean onlyCore, boolean factoryTest) {
    PackageManager.disableApplicationInfoCache();
    PackageManager.disablePackageInfoCache();
    
    PackageManager.corkPackageInfoCache();
    
    //开始阶段日志
    final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",
        Trace.TRACE_TAG_PACKAGE_MANAGER);
mPendingBroadcasts = new PendingPackageBroadcasts();

    mInjector = injector;
    mInjector.bootstrap(this);
    mLock = injector.getLock();
    mInstallLock = injector.getInstallLock();
    LockGuard.installLock(mLock, LockGuard.INDEX_PACKAGES);
    EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
        SystemClock.uptimeMillis());

    if (mSdkVersion <= 0) {
        Slog.w(TAG, "**** ro.build.version.sdk not set!");
    }

    mContext = injector.getContext();
    mFactoryTest = factoryTest;
    mOnlyCore = onlyCore;
    mMetrics = new DisplayMetrics();
    mInstaller = injector.getInstaller();

    // 创建提供服务或数据的子组件,注意创建的顺序很重要
    t.traceBegin("createSubComponents");
   
    // 暴露私有服务供系统组件调用
    mPmInternal = new PackageManagerInternalImpl();
    LocalServices.addService(PackageManagerInternal.class, mPmInternal);
    mUserManager = injector.getUserManagerService();
    mComponentResolver = injector.getComponentResolver();
    mPermissionManager = injector.getPermissionManagerServiceInternal();
    
    //settings是主要保存设置和信息的类
    mSettings = injector.getSettings();
    
    //权限管理类
    mPermissionManagerService = (IPermissionManager) ServiceManager.getService("permissionmgr");
    mIncrementalManager =
        (IncrementalManager) mContext.getSystemService(Context.INCREMENTAL_SERVICE);
    PlatformCompat platformCompat = mInjector.getCompatibility();
    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");
    mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
        ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
   ...
   
    String separateProcesses = SystemProperties.get("debug.separate_processes");
    if (separateProcesses != null && separateProcesses.length() > 0) {
        if ("*".equals(separateProcesses)) {
            mDefParseFlags = PackageParser.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优化类
    mPackageDexOptimizer = new PackageDexOptimizer(mInstaller, mInstallLock, mContext,
            "*dexopt*");
    //Dex管理类
    mDexManager =
            new DexManager(mContext, this, mPackageDexOptimizer, mInstaller, mInstallLock);
    mArtManagerService = new ArtManagerService(mContext, this, mInstaller, mInstallLock);
    mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());

    mViewCompiler = new ViewCompiler(mInstallLock, mInstaller);
   ...

    // CHECKSTYLE:OFF IndentationCheck
    synchronized (mInstallLock) {
    // writer
    synchronized (mLock) {
        //创建后台线程和handler
        mHandlerThread = new ServiceThread(TAG,
                Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
        mHandlerThread.start();
        mHandler = new PackageHandler(mHandlerThread.getLooper());
        mProcessLoggingHandler = new ProcessLoggingHandler();
        Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
        mInstantAppRegistry = new InstantAppRegistry(this);

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

        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++) {
                final SharedLibraryInfo dependency =
                    getSharedLibraryInfoLPr(entry.dependencies[j], undefinedVersion);
                if (dependency != null) {
                    getSharedLibraryInfoLPr(name, undefinedVersion).addDependency(dependency);
                }
            }
        }

        SELinuxMMAC.readInstallPolicy();

        t.traceBegin("loadFallbacks");
        FallbackCategoryProvider.loadFallbacks();
        t.traceEnd();

        t.traceBegin("read user settings");
        
        //解析系统配置文件package.xml
        mFirstBoot = !mSettings.readLPw(mInjector.getUserManagerInternal().getUsers(false));
        t.traceEnd();

        //清理代码路径不存在的包,由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);
            }
        }

        if (!mOnlyCore && mFirstBoot) {
            requestCopyPreoptedFiles();
        }
        //自定义mCustomResolverComponentName
        String customResolverActivityName = Resources.getSystem().getString(
                R.string.config_customResolverActivity);
        if (!TextUtils.isEmpty(customResolverActivityName)) {
            mCustomResolverComponentName = ComponentName.unflattenFromString(
                    customResolverActivityName);
        }
    ...
 } 

主要是对一些属性和子服务进行创建或赋值,其中比较重要的有mInstaller,mSettings,mPackageDexOptimizer等。在一起的版本中有些属性是直接new出来的,现在采用的是Injector的方法获取。另外还开启啦工作线程。

mSettings.readLPw()

boolean readLPw(@NonNull List<UserInfo> users) {
    FileInputStream str = null;
    //判断备份文件是否存在
    if (mBackupSettingsFilename.exists()) {
        try {
            str = new FileInputStream(mBackupSettingsFilename);
            mReadMessages.append("Reading from backup settings file\n");
            PackageManagerService.reportSettingsProblem(Log.INFO,
                    "Need to read from backup settings file");
            if (mSettingsFilename.exists()) {
                //如果备份文件和常规文件同时存在,则忽略常规文件(常规文件是在异常时出现,而备份文件不是)
                Slog.w(PackageManagerService.TAG, "Cleaning up settings file "
                        + mSettingsFilename);
                mSettingsFilename.delete();
            }
        } catch (java.io.IOException e) {
            // We'll try for the normal settings file.
        }
    }
    //把集合清空
    mPendingPackages.clear();
    mPastSignatures.clear();
    mKeySetRefs.clear();
    mInstallerPackages.clear();

    try {
        if (str == null) { //备份文件不存在
            if (!mSettingsFilename.exists()) {//两者都不存在
                mReadMessages.append("No settings file found\n");
                PackageManagerService.reportSettingsProblem(Log.INFO,
                        "No settings file; creating initial state");
                // It's enough to just touch version details to create them
                // with default values
                findOrCreateVersion(StorageManager.UUID_PRIVATE_INTERNAL).forceCurrent();
                findOrCreateVersion(StorageManager.UUID_PRIMARY_PHYSICAL).forceCurrent();
                return false;
            }
            str = new FileInputStream(mSettingsFilename);
        }
        XmlPullParser parser = Xml.newPullParser();
        parser.setInput(str, StandardCharsets.UTF_8.name());

        int type;
        while ((type = parser.next()) != XmlPullParser.START_TAG
                && type != XmlPullParser.END_DOCUMENT) {
            ;
        }
        //xml文件不正常
        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();
        //解析xml
        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);
            } 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);
            } else if ...
        }
        str.close();

    } catch ...
    
    ...

    return true;
}

readPackageLPw 读xml的元素和属性,获取包信息

private void readPackageLPw(XmlPullParser parser) throws XmlPullParserException, IOException {
    String name = null;
    String realName = null;
    String idStr = null;
    String sharedIdStr = null;
    String codePathStr = null;
    String resourcePathStr = null;
    String legacyCpuAbiString = null;
    String legacyNativeLibraryPathStr = null;
    String primaryCpuAbiString = null;
    String secondaryCpuAbiString = null;
    String cpuAbiOverrideString = null;
    String systemStr = null;
    String installerPackageName = null;
    String isOrphaned = null;
    String installOriginatingPackageName = null;
    String installInitiatingPackageName = null;
    String installInitiatorUninstalled = null;
    String volumeUuid = null;
    String categoryHintString = null;
    String updateAvailable = null;
    int categoryHint = ApplicationInfo.CATEGORY_UNDEFINED;
    String uidError = null;
    int pkgFlags = 0;
    int pkgPrivateFlags = 0;
    long timeStamp = 0;
    long firstInstallTime = 0;
    long lastUpdateTime = 0;
    PackageSetting packageSetting = null;
    String version = null;
    long versionCode = 0;
    String installedForceQueryable = null;
    try {
        name = parser.getAttributeValue(null, ATTR_NAME);
        realName = parser.getAttributeValue(null, "realName");
        idStr = parser.getAttributeValue(null, "userId");
        uidError = parser.getAttributeValue(null, "uidError");
        sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
        codePathStr = parser.getAttributeValue(null, "codePath");
        resourcePathStr = parser.getAttributeValue(null, "resourcePath");
        ...
        if (name == null) {
            PackageManagerService.reportSettingsProblem(Log.WARN,
                    "Error in package manager settings: <package> has no name at "
                            + parser.getPositionDescription());
        } else if (codePathStr == null) {
            PackageManagerService.reportSettingsProblem(Log.WARN,
                    "Error in package manager settings: <package> has no codePath at "
                            + parser.getPositionDescription());
        } else if (userId > 0) {
            packageSetting = addPackageLPw(name.intern(), realName, new File(codePathStr),
                    new File(resourcePathStr), legacyNativeLibraryPathStr, primaryCpuAbiString,
                    secondaryCpuAbiString, cpuAbiOverrideString, userId, versionCode, pkgFlags,
                    pkgPrivateFlags, null /*usesStaticLibraries*/,
                    null /*usesStaticLibraryVersions*/, null /*mimeGroups*/);
            if (PackageManagerService.DEBUG_SETTINGS)
                Log.i(PackageManagerService.TAG, "Reading package " + name + ": userId="
                        + userId + " pkg=" + packageSetting);
            if (packageSetting == null) {
                PackageManagerService.reportSettingsProblem(Log.ERROR, "Failure adding uid "
                        + userId + " while parsing settings at "
                        + parser.getPositionDescription());
            } else {
                packageSetting.setTimeStamp(timeStamp);
                packageSetting.firstInstallTime = firstInstallTime;
                packageSetting.lastUpdateTime = lastUpdateTime;
            }
        } else if (sharedIdStr != null) {
            if (sharedUserId > 0) {
                packageSetting = new PackageSetting(name.intern(), realName, new File(
                        codePathStr), new File(resourcePathStr), legacyNativeLibraryPathStr,
                        primaryCpuAbiString, secondaryCpuAbiString, cpuAbiOverrideString,
                        versionCode, pkgFlags, pkgPrivateFlags, sharedUserId,
                        null /*usesStaticLibraries*/,
                        null /*usesStaticLibraryVersions*/,
                        null /*mimeGroups*/);
                packageSetting.setTimeStamp(timeStamp);
                packageSetting.firstInstallTime = firstInstallTime;
                packageSetting.lastUpdateTime = lastUpdateTime;
                mPendingPackages.add(packageSetting);
                if (PackageManagerService.DEBUG_SETTINGS)
                    Log.i(PackageManagerService.TAG, "Reading package " + name
                            + ": sharedUserId=" + sharedUserId + " pkg=" + packageSetting);
            } else {
                PackageManagerService.reportSettingsProblem(Log.WARN,
                        "Error in package manager settings: package " + name
                                + " has bad sharedId " + sharedIdStr + " at "
                                + parser.getPositionDescription());
            }
        } else {
            PackageManagerService.reportSettingsProblem(Log.WARN,
                    "Error in package manager settings: package " + name + " has bad userId "
                            + idStr + " at " + parser.getPositionDescription());
        }
    } catch (NumberFormatException e) {
        PackageManagerService.reportSettingsProblem(Log.WARN,
                "Error in package manager settings: package " + name + " has bad userId "
                        + idStr + " at " + parser.getPositionDescription());
    }
    if (packageSetting != null) {
        packageSetting.uidError = "true".equals(uidError);
        InstallSource installSource = InstallSource.create(
                installInitiatingPackageName, installOriginatingPackageName,
                installerPackageName, "true".equals(isOrphaned),
                "true".equals(installInitiatorUninstalled));
        //packageSetting赋值
        packageSetting.installSource = installSource;
        packageSetting.volumeUuid = volumeUuid;
        packageSetting.categoryHint = categoryHint;
        packageSetting.legacyNativeLibraryPathString = legacyNativeLibraryPathStr;
        packageSetting.primaryCpuAbiString = primaryCpuAbiString;
        packageSetting.secondaryCpuAbiString = secondaryCpuAbiString;
        packageSetting.updateAvailable = "true".equals(updateAvailable);
        packageSetting.forceQueryableOverride = "true".equals(installedForceQueryable);
        // Handle legacy string here for single-user mode
        final String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED);
        if (enabledStr != null) {
            try {
                packageSetting.setEnabled(Integer.parseInt(enabledStr), 0 /* userId */, null);
            } catch (NumberFormatException e) {
                if (enabledStr.equalsIgnoreCase("true")) {
                    packageSetting.setEnabled(COMPONENT_ENABLED_STATE_ENABLED, 0, null);
                } else if (enabledStr.equalsIgnoreCase("false")) {
                    packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, 0, null);
                } else if (enabledStr.equalsIgnoreCase("default")) {
                    packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0, null);
                } else {
                    PackageManagerService.reportSettingsProblem(Log.WARN,
                            "Error in package manager settings: package " + name
                                    + " has bad enabled value: " + idStr + " at "
                                    + parser.getPositionDescription());
                }
            }
        } else {
            packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0, null);
        }

        addInstallerPackageNames(installSource);

        int outerDepth = parser.getDepth();
        int type;
        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();
            // Legacy
            if (tagName.equals(TAG_DISABLED_COMPONENTS)) {
                readDisabledComponentsLPw(packageSetting, parser, 0);
            } else if (tagName.equals(TAG_ENABLED_COMPONENTS)) {
                readEnabledComponentsLPw(packageSetting, parser, 0);
            } else if (tagName.equals("sigs")) {
                packageSetting.signatures.readXml(parser, mPastSignatures);
            } else if (tagName.equals(TAG_PERMISSIONS)) {
                readInstallPermissionsLPr(parser,
                        packageSetting.getPermissionsState());
                packageSetting.installPermissionsFixed = true;
            } else if (tagName.equals("proper-signing-keyset")) {
                long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
                Integer refCt = mKeySetRefs.get(id);
                if (refCt != null) {
                    mKeySetRefs.put(id, refCt + 1);
                } else {
                    mKeySetRefs.put(id, 1);
                }
                packageSetting.keySetData.setProperSigningKeySet(id);
            } else if (tagName.equals("signing-keyset")) {
                // from v1 of keysetmanagerservice - no longer used
            } else if (tagName.equals("upgrade-keyset")) {
                long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
                packageSetting.keySetData.addUpgradeKeySetById(id);
            } else if (tagName.equals("defined-keyset")) {
                long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
                String alias = parser.getAttributeValue(null, "alias");
                Integer refCt = mKeySetRefs.get(id);
                if (refCt != null) {
                    mKeySetRefs.put(id, refCt + 1);
                } else {
                    mKeySetRefs.put(id, 1);
                }
                packageSetting.keySetData.addDefinedKeySet(id, alias);
            } else if (tagName.equals("install-initiator-sigs")) {
                final PackageSignatures signatures = new PackageSignatures();
                signatures.readXml(parser, mPastSignatures);
                packageSetting.installSource =
                        packageSetting.installSource.setInitiatingPackageSignatures(signatures);
            } else if (tagName.equals(TAG_DOMAIN_VERIFICATION)) {
                readDomainVerificationLPw(parser, packageSetting);
            } else if (tagName.equals(TAG_MIME_GROUP)) {
                packageSetting.mimeGroups = readMimeGroupLPw(parser, packageSetting.mimeGroups);
            } else {
                PackageManagerService.reportSettingsProblem(Log.WARN,
                        "Unknown element under <package>: " + parser.getName());
                XmlUtils.skipCurrentTag(parser);
            }
        }
    } else {
        XmlUtils.skipCurrentTag(parser);
    }
}

进入addPackageLPw方法

PackageSetting addPackageLPw(String name, String realName, File codePath, File resourcePath,
        String legacyNativeLibraryPathString, String primaryCpuAbiString,
        String secondaryCpuAbiString, String cpuAbiOverrideString, int uid, long vc, int
        pkgFlags, int pkgPrivateFlags, String[] usesStaticLibraries,
        long[] usesStaticLibraryNames, Map<String, ArraySet<String>> mimeGroups) {
    PackageSetting p = mPackages.get(name);
    if (p != null) {
        if (p.appId == uid) {
            return p;
        }
        PackageManagerService.reportSettingsProblem(Log.ERROR,
                "Adding duplicate package, keeping first: " + name);
        return null;
    }
    p = new PackageSetting(name, realName, codePath, resourcePath,
            legacyNativeLibraryPathString, primaryCpuAbiString, secondaryCpuAbiString,
            cpuAbiOverrideString, vc, pkgFlags, pkgPrivateFlags,
            0 /*userId*/, usesStaticLibraries, usesStaticLibraryNames,
            mimeGroups);
    p.appId = uid;
    if (registerExistingAppIdLPw(uid, p, name)) {
        mPackages.put(name, p);
        return p;
    }
    return null;
}

至此,大致知道了开始阶段的主要工作

  1. 初始化PMS的各个子组件/子服务以及相关属性
  2. 解析package.xml,获取已经安装的app信息存储到settings的mPackage中
  3. 创建后台工作线程和handler
系统扫描阶段 BOOT_PROGRESS_PMS_SYSTEM_SCAN_START
public PackageManagerService(Injector injector, boolean onlyCore, boolean factoryTest) {
    ...
    //找到扫描的路径
    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);
        }
    }

    mDirsToScanAsSystem = new ArrayList<>();
    mDirsToScanAsSystem.addAll(SYSTEM_PARTITIONS);
    mDirsToScanAsSystem.addAll(scanPartitions);

    ...
    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!");
    }

    File frameworkDir = new File(Environment.getRootDirectory(), "framework");

    final VersionInfo ver = mSettings.getInternalVersion();
    mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
    if (mIsUpgrade) {
        logCriticalInfo(Log.INFO,
                "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
    }

    // 从 pre-M 升级时,将系统应用程序权限从安装提升到运行时
    mPromoteSystemApps =
            mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;

    // 从 pre-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;

    //在扫描之前保存预先存在的包的名称,以便我们可以确定哪些系统包是由于升级而全新的。
    if (isDeviceUpgrading()) {
        mExistingPackages = new ArraySet<>(mSettings.mPackages.size());
        for (PackageSetting ps : mSettings.mPackages.values()) {
            mExistingPackages.add(ps.name);
        }
    }

    mCacheDir = preparePackageParserCache();

    // 设置标志以在扫描安装目录时监控而不更改 apk 文件路径。
    int scanFlags = SCAN_BOOTING | SCAN_INITIAL;

    if (mIsUpgrade || mFirstBoot) {
        scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
    }

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

    PackageParser2 packageParser = new PackageParser2(mSeparateProcesses, mOnlyCore,
            mMetrics, mCacheDir, mPackageParserCallback);

    ExecutorService executorService = ParallelPackageParser.makeExecutorService();
    mApexManager.scanApexPackagesTraced(packageParser, executorService);
    //主要扫描代码
    for (int i = mDirsToScanAsSystem.size() - 1; i >= 0; i--) {
        final ScanPartition partition = mDirsToScanAsSystem.get(i);
        if (partition.getOverlayFolder() == null) {
            continue;
        }
        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) {
            scanDirTracedLI(partition.getPrivAppFolder(), systemParseFlags,
                    systemScanFlags | SCAN_AS_PRIVILEGED | partition.scanFlag, 0,
                    packageParser, executorService);
        }
        scanDirTracedLI(partition.getAppFolder(), systemParseFlags,
                systemScanFlags | partition.scanFlag, 0,
                packageParser, executorService);
    }

    mOverlayConfig = OverlayConfig.initializeSystemInstance(
            consumer -> mPmInternal.forEachPackage(
                    pkg -> consumer.accept(pkg, pkg.isSystem())));

    //收集可能不存在的系统app
    final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
    final List<String> stubSystemApps = new ArrayList<>();
    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();
        //比较mSetting,mpackages(package.xml读取的记录)和mPackgaes(实时扫描的记录),看看是否有变化,有变化的情况往往是通过OTA升级
        while (psit.hasNext()) {
            PackageSetting ps = psit.next();

            //非系统app跳过
            if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
                continue;
            }
            final AndroidPackage scannedPkg = mPackages.get(ps.name);
            if (scannedPkg != null) {
                
                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;
            }

            if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
                psit.remove();
                logCriticalInfo(Log.WARN, "System package " + ps.name
                        + " no longer exists; it's data will be wiped");

                mPermissionManager.updatePermissions(ps.name, null);
            } else {
                final PackageSetting disabledPs =
                        mSettings.getDisabledSystemPkgLPr(ps.name);
                if (disabledPs.codePath == null || !disabledPs.codePath.exists()
                        || disabledPs.pkg == null) {
                    possiblyDeletedUpdatedSystemApps.add(ps.name);
                } else {
                    mExpectingBetter.put(disabledPs.name, disabledPs.codePath);
                }
            }
        }
    }

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

    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
    }
    ...
}

这里主要是对系统区进行扫描,扫描顺序

OverlayFolder ->frameworkDir ->privAppFolder->appFolder

进入扫描的方法scanDirTracedLI

private void scanDirTracedLI(File scanDir, final int parseFlags, int scanFlags,
        long currentTime, PackageParser2 packageParser, ExecutorService executorService) {
    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + scanDir.getAbsolutePath() + "]");
    try {
        scanDirLI(scanDir, parseFlags, scanFlags, currentTime, packageParser, executorService);
    } finally {
        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
    }
}

进入scanDirLI方法

private void scanDirLI(File scanDir, int parseFlags, int scanFlags, long currentTime,
        PackageParser2 packageParser, ExecutorService executorService) {
    final File[] files = scanDir.listFiles();
    if (ArrayUtils.isEmpty(files)) {//空文件夹直接返回
        Log.d(TAG, "No files in app dir " + scanDir);
        return;
    }

    if (DEBUG_PACKAGE_SCANNING) {
        Log.d(TAG, "Scanning app dir " + scanDir + " scanFlags=" + scanFlags
                + " flags=0x" + Integer.toHexString(parseFlags));
    }

    //将传进来的PackageParser2和executorService封装成ParallelPackageParser对象
    ParallelPackageParser parallelPackageParser =
            new ParallelPackageParser(packageParser, executorService);

    // Submit files for parsing in parallel
    int fileCount = 0;
    for (File file : files) {
        final boolean isPackage = (isApkFile(file) || file.isDirectory())
                && !PackageInstallerService.isStageName(file.getName());
        if (!isPackage) {
            // Ignore entries which are not packages
            continue;
        }
        //解析包的关键代码
        parallelPackageParser.submit(file, parseFlags);
        fileCount++;
    }

    // 解析完成之后,取出结果进行处理
    for (; fileCount > 0; fileCount--) {
        ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
        Throwable throwable = parseResult.throwable;
        int errorCode = PackageManager.INSTALL_SUCCEEDED;

        if (throwable == null) {
            // TODO(toddke): move lower in the scan chain
            // Static shared libraries have synthetic package names
            if (parseResult.parsedPackage.isStaticSharedLibrary()) {
                renameStaticSharedLibraryPackage(parseResult.parsedPackage);
            }
            try {
                addForInitLI(parseResult.parsedPackage, parseFlags, scanFlags,
                        currentTime, null);
            } catch (PackageManagerException e) {
                errorCode = e.error;
                Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
            }
        } else if (throwable instanceof PackageParserException) {
            PackageParserException e = (PackageParserException)
                    throwable;
            errorCode = e.error;
            Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
        } else {
            throw new IllegalStateException("Unexpected exception occurred while parsing "
                    + parseResult.scanFile, throwable);
        }

        if ((scanFlags & SCAN_AS_APK_IN_APEX) != 0 && errorCode != INSTALL_SUCCEEDED) {
            mApexManager.reportErrorWithApkInApex(scanDir.getAbsolutePath());
        }

        // 删除无效的用户app
        if ((scanFlags & SCAN_AS_SYSTEM) == 0
                && errorCode != PackageManager.INSTALL_SUCCEEDED) {
            logCriticalInfo(Log.WARN,
                    "Deleting invalid package at " + parseResult.scanFile);
            removeCodePathLI(parseResult.scanFile);
        }
    }
}

主要的操作:

  1. 通过ParallelPackageParser解析扫描目录下的包
  2. 取出解析结果,执行addForInitLI
  3. 删除无效的用户app

解析的结果是Parsedpackage对象,它是一个继承自AndroidPackage的接口,实现类是PackageImpl。

进入addForInitLI方法

private AndroidPackage addForInitLI(ParsedPackage parsedPackage,
        @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
        @Nullable UserHandle user)
                throws PackageManagerException {
    ...
    //获取一个ScanResult对象
    final ScanResult scanResult = scanPackageNewLI(parsedPackage, parseFlags, scanFlags
            | SCAN_UPDATE_SIGNATURE, currentTime, user, null);
    if (scanResult.success) {
        synchronized (mLock) {
            boolean appIdCreated = false;
            try {
                final String pkgName = scanResult.pkgSetting.name;
                final Map<String, ReconciledPackage> reconcileResult = reconcilePackagesLocked(
                        new ReconcileRequest(
                                Collections.singletonMap(pkgName, scanResult),
                                mSharedLibraries,
                                mPackages,
                                Collections.singletonMap(
                                        pkgName, getSettingsVersionForPackage(parsedPackage)),
                                Collections.singletonMap(pkgName,
                                        getSharedLibLatestVersionSetting(scanResult))),
                        mSettings.mKeySetManagerService);
                appIdCreated = optimisticallyRegisterAppId(scanResult);
                
                commitReconciledScanResultLocked(
                        reconcileResult.get(pkgName), mUserManager.getUserIds());
            } catch (PackageManagerException e) {
                if (appIdCreated) {
                    cleanUpAppIdCreation(scanResult);
                }
                throw e;
            }
        }
    }

    if (shouldHideSystemApp) {
        synchronized (mLock) {
            mSettings.disableSystemPackageLPw(parsedPackage.getPackageName(), true);
        }
    }
    return scanResult.pkgSetting.pkg;
}

进入commitReconciledScanResultLocked方法

private AndroidPackage commitReconciledScanResultLocked(
        @NonNull ReconciledPackage reconciledPkg, int[] allUsers) {
    ...
    commitPackageSettings(pkg, oldPkg, pkgSetting, scanFlags,
            (parseFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/, reconciledPkg);
    ...
    return pkg;
}

进入commitPackageSettings方法

private void commitPackageSettings(AndroidPackage pkg,
        @Nullable AndroidPackage oldPkg, PackageSetting pkgSetting,
        final @ScanFlags int scanFlags, boolean chatty, ReconciledPackage reconciledPkg) {
    final String pkgName = pkg.getPackageName();
    //判断是不是自定义的ResolverComponentName
    if (mCustomResolverComponentName != null &&
            mCustomResolverComponentName.getPackageName().equals(pkg.getPackageName())) {
        setUpCustomResolverActivity(pkg, pkgSetting);
    }

    if (pkg.getPackageName().equals("android")) {
        synchronized (mLock) {
            mPlatformPackage = pkg;
            mAndroidApplication = pkg.toAppInfoWithoutState();
            mAndroidApplication.flags = PackageInfoUtils.appInfoFlags(pkg, pkgSetting);
            mAndroidApplication.privateFlags =
                    PackageInfoUtils.appInfoPrivateFlags(pkg, pkgSetting);
            mAndroidApplication.initForUser(UserHandle.USER_SYSTEM);

            if (!mResolverReplaced) {
                mResolveActivity.applicationInfo = mAndroidApplication;
                mResolveActivity.name = ResolverActivity.class.getName();
                mResolveActivity.packageName = mAndroidApplication.packageName;
                mResolveActivity.processName = "system:ui";
                mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
                mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
                mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
                mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
                mResolveActivity.exported = true;
                mResolveActivity.enabled = true;
                mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
                mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
                        | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
                        | ActivityInfo.CONFIG_SCREEN_LAYOUT
                        | ActivityInfo.CONFIG_ORIENTATION
                        | ActivityInfo.CONFIG_KEYBOARD
                        | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
                mResolveInfo.activityInfo = mResolveActivity;
                mResolveInfo.priority = 0;
                mResolveInfo.preferredOrder = 0;
                mResolveInfo.match = 0;
                mResolveComponentName = new ComponentName(
                        mAndroidApplication.packageName, mResolveActivity.name);
            }
        }
    }
    ...
    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");

    synchronized (mLock) {

        // 更新mSettings中的相关信息(包数据)
        mSettings.insertPackageSettingLPw(pkgSetting, pkg);
        // 把包信息储存到mPackages中
        mPackages.put(pkg.getPackageName(), pkg);
        if ((scanFlags & SCAN_AS_APK_IN_APEX) != 0) {
            mApexManager.registerApkInApex(pkg);
        }

        // 把KeySets添加到KeySetManagerService
        KeySetManagerService ksms = mSettings.mKeySetManagerService;
        ksms.addScannedPackageLPw(pkg);
        //向mComponentResolver注册
        mComponentResolver.addAllComponents(pkg, chatty);
        final boolean isReplace =
                reconciledPkg.prepareResult != null && reconciledPkg.prepareResult.replace;
        //向mAppsFilter注册
        mAppsFilter.addPackage(pkgSetting, isReplace);

        // 不让临时应用程序定义新的权限
        if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
            Slog.w(TAG, "Permission groups from package " + pkg.getPackageName()
                    + " ignored: instant apps cannot define new permission groups.");
        } else {
            //权限相关处理
            mPermissionManager.addAllPermissionGroups(pkg, chatty);
        }

        // 不允许临时应用程序定义新权限。
        if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
            Slog.w(TAG, "Permissions from package " + pkg.getPackageName()
                    + " ignored: instant apps cannot define new permissions.");
        } else {
            //权限相关处理
            mPermissionManager.addAllPermissions(pkg, chatty);
        }

        int collectionSize = ArrayUtils.size(pkg.getInstrumentations());
        StringBuilder r = null;
        int i;
        for (i = 0; i < collectionSize; i++) {
            ParsedInstrumentation a = pkg.getInstrumentations().get(i);
            a.setPackageName(pkg.getPackageName());
            //向mInstrumentation注册
            mInstrumentation.put(a.getComponentName(), a);
            if (chatty) {
                if (r == null) {
                    r = new StringBuilder(256);
                } else {
                    r.append(' ');
                }
                r.append(a.getName());
            }
        }
        if (r != null) {
            if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
        }

        if (!pkg.getProtectedBroadcasts().isEmpty()) {
            synchronized (mProtectedBroadcasts) {
                mProtectedBroadcasts.addAll(pkg.getProtectedBroadcasts());
            }
        }

        if (oldPkg != null) {
            final ArrayList<String> allPackageNames = new ArrayList<>(mPackages.keySet());

            AsyncTask.execute(() ->
                    mPermissionManager.revokeRuntimePermissionsIfGroupChanged(pkg, oldPkg,
                            allPackageNames));
        }
    }

    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}

把解析的结果存储到PMS的各个相关变量中。

BOOT_PROGRESS_PMS_SYSTEM_SCAN_START阶段所做的事:

  1. 扫描各个旭通分区的app
  2. 解析系统app信息
  3. 把解析结果存储起来,存在在PMS的相关属性和Msettings里
Data扫描阶段 BOOT_PROGRESS_PMS_DATA_SCAN_START
public PackageManagerService(Injector injector, boolean onlyCore, boolean factoryTest) {
    ...
    if (!mOnlyCore) {
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
                SystemClock.uptimeMillis());
        //扫描用户安装的app,/data/app目录
        scanDirTracedLI(sAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0,
                packageParser, executorService);

    }
    //关闭packageParser
    packageParser.close();

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

    if (!mOnlyCore) {
        //删除OTA升级中移除的系统app,如果ota对这个app的操作是删除,则完全删除app相关的东西,否则剥夺它系统app的身份
        for (int i = possiblyDeletedUpdatedSystemApps.size() - 1; i >= 0; --i) {
            final String packageName = possiblyDeletedUpdatedSystemApps.get(i);
            final AndroidPackage pkg = mPackages.get(packageName);
            final String msg;

           //从disabled清单删除
            mSettings.removeDisabledSystemPackageLPw(packageName);

            if (pkg == null) {
                msg = "Updated system package " + packageName
                        + " no longer exists; removing its data";
            } else {
                msg = "Updated system package " + packageName
                        + " no longer exists; rescanning package on data";
                removePackageLI(pkg, true);
                try {
                    final File codePath = new File(pkg.getCodePath());
                    scanPackageTracedLI(codePath, 0, scanFlags, 0, null);
                } catch (PackageManagerException e) {
                    Slog.e(TAG, "Failed to parse updated, ex-system package: "
                            + e.getMessage());
                }
            }
            final PackageSetting ps = mSettings.mPackages.get(packageName);
            if (ps != null && mPackages.get(packageName) == null) {
                removePackageDataLIF(ps, null, null, 0, false);

            }
            logCriticalInfo(Log.WARN, msg);
        }
        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 {
                    scanPackageTracedLI(scanFile, reparseFlags, rescanFlags, 0, null);
                } catch (PackageManagerException e) {
                    Slog.e(TAG, "Failed to parse original system package: "
                            + e.getMessage());
                }
            }
        }

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

    mStorageManagerPackage = getStorageManagerPackageName();

    mSetupWizardPackage = getSetupWizardPackageNameImpl();
    mComponentResolver.fixProtectedFilterPriorities();

    mDefaultTextClassifierPackage = getDefaultTextClassifierPackageName();
    mSystemTextClassifierPackageName = getSystemTextClassifierPackageName();
    mWellbeingPackage = getWellbeingPackageName();
    mDocumenterPackage = getDocumenterPackageName();
    mConfiguratorPackage = getDeviceConfiguratorPackageName();
    mAppPredictionServicePackage = getAppPredictionServicePackageName();
    mIncidentReportApproverPackage = getIncidentReportApproverPackageName();
    mRetailDemoPackage = getRetailDemoPackageName();

    updateAllSharedLibrariesLocked(null, null, Collections.unmodifiableMap(mPackages));

    for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
        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) {
                }
            }
        }
        setting.fixSeInfoLocked();
        setting.updateProcesses();
    }

    mPackageUsage.read(mSettings.mPackages);
    mCompilerStats.read();
    ...
}

这里主要是对/data/app进行扫描,主要工作和系统扫描app目录是一样的,除此之外还做了一下扫尾工作。

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

//如果sdk版本发生啦变化(系统升级),重新对app进行授权
final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
if (sdkUpdated) {
    Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
            + mSdkVersion + "; regranting permissions for internal storage");
}
mPermissionManager.updateAllPermissions(
        StorageManager.UUID_PRIVATE_INTERNAL, sdkUpdated);
ver.sdkVersion = mSdkVersion;

// 如果是首次启动或者从6.0以前的系统升级,初始化用户首选app
if (!mOnlyCore && (mPromoteSystemApps || mFirstBoot)) {
    for (UserInfo user : mInjector.getUserManagerInternal().getUsers(true)) {
        mSettings.applyDefaultPreferredAppsLPw(user.id);
        primeDomainVerificationsLPw(user.id);
    }
}

//为系统用户准备存储空间,因为settingsProvider和systemUi等核心系统app不可能等用户启动
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;
    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) {
            synchronized (mInstallLock) {
                prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
                        true /* maybeMigrateAppData */);
            }
            count++;
        }
    }
    traceLog.traceEnd();
    Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
}, "prepareAppData");

// 如果是升级后第一次正常启动,需要清除代码缓存,但不会清除应用的配置文件
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;
}

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;

ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;

//把更新后的mSettings的相关信息写入package.xml等对应文件中
t.traceBegin("write settings");
mSettings.writeLPr();
t.traceEnd();

这个阶段主要做的事:

  • 如果sdk版本发生了变化,重新对app进行授权
  • 为系统核心服务准备存粗空间
  • 如果是升级后的第一次正常启动,需要清除代码缓存,但不会清除应用的配置文件
  • 把更新后的信息写入对应的xml文件中
就绪阶段 BOOT_PROGRESS_PMS_READY
 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
            SystemClock.uptimeMillis());

    if (!mOnlyCore) {
        mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
        mRequiredInstallerPackage = getRequiredInstallerLPr();
        mRequiredUninstallerPackage = getRequiredUninstallerLPr();
        mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
        if (mIntentFilterVerifierComponent != null) {
            mIntentFilterVerifier = new IntentVerifierProxy(mContext,
                    mIntentFilterVerifierComponent);
        } else {
            mIntentFilterVerifier = null;
        }
        mServicesExtensionPackageName = getRequiredServicesExtensionPackageLPr();
        mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
                PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
                SharedLibraryInfo.VERSION_UNDEFINED);
    } else {
        mRequiredVerifierPackage = null;
        mRequiredInstallerPackage = null;
        mRequiredUninstallerPackage = null;
        mIntentFilterVerifierComponent = null;
        mIntentFilterVerifier = null;
        mServicesExtensionPackageName = null;
        mSharedSystemSharedLibraryPackageName = null;
    }

    mRequiredPermissionControllerPackage = getRequiredPermissionControllerLPr();

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

    final int[] userIds = UserManagerService.getInstance().getUserIds();
    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);
        }
    }
    final Supplier<PackageParser2> apexParserSupplier = () -> new PackageParser2(
            mSeparateProcesses, mOnlyCore, mMetrics, null /* cacheDir */,
            mPackageParserCallback);
    //初始化PackageInstallerService
    mInstallerService = new PackageInstallerService(mContext, this, apexParserSupplier);
    final Pair<ComponentName, String> instantAppResolverComponent =
            getInstantAppResolverLPr();
    if (instantAppResolverComponent != null) {
        if (DEBUG_INSTANT) {
            Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
        }
        mInstantAppResolverConnection = new InstantAppResolverConnection(
                mContext, instantAppResolverComponent.first,
                instantAppResolverComponent.second);
        mInstantAppResolverSettingsComponent =
                getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
    } else {
        mInstantAppResolverConnection = null;
        mInstantAppResolverSettingsComponent = null;
    }
    updateInstantAppInstallerLocked(null);

    //读取并更新dex文件的使用情况
    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)

mModuleInfoProvider = new ModuleInfoProvider(mContext, this);

PackageManager.uncorkPackageInfoCache();

t.traceBegin("GC");
Runtime.getRuntime().gc();
t.traceEnd();

mInstaller.setWarnIfHeld(mLock);

PackageParser.readConfigUseRoundIcon(mContext.getResources());

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

这个阶段也是对应一些属性进行赋值,最重要的是初始化了mInstallerService。

小结

image.png

获取PKMS

image.png

启动过程涉及到的核心文件

文件功能
/data/data/App数据目录
/data/user/App数据目录
/data/app/App安装目录
/data/system/packages.xml所有安装App信息
/data/system/packages-stopped.xml所有强制停止app信息
/data/system/packages.list所有安装app信息

Android系统有很多目录可以存放app

目录App类别
/vendor/overlay系统app
/system/framework系统app
/system/priv-app系统app
/system/app系统app
/vendor/priv-app系统app
/vendor/app系统app
/oem/app系统app
/data/app普通app
/data/app-private普通app

关于apk的安装原理,卸载,还有apk打包相关的,准备放在下一篇博客,敬请期待