IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> PackageManagerService原理之启动篇 -> 正文阅读

[移动开发]PackageManagerService原理之启动篇

PackageManagerService属于Android framework中很重要的一个模块,应用安装、卸载、Intent的匹配、package的解析等都和它有关。下面从PackageManagerService的启动和在Context中获取PackageManager对象理一理整个过程。

?本文是基于Android10源码分析,其他版本可能有细微的差异,但是总体流程相差无几。涉及到的类有:

frameworks/base/services/java/com/android/server/SystemServer.java
frameworks/base/core/java/android/content/pm/IPackageManager.aidl
frameworks/base/core/java/android/content/pm/PakcageManager.java
frameworks/base/core/java/android/app/ApplicationPakcageManager.java
frameworks/base/services/core/java/com/android/server/pm/PakcageManagerservice.java
frameworks/base/core/java/android/os/ServiceManagerNative.java

文章目录结构如下:

PackageManagerService 启动

?PackageManagerService(后面我们简称为PMS)是在SystemServer进程启动过程中被拉起的,具体时序如下:
在这里插入图片描述

//frameworks/base/services/java/com/android/server/SystemServer.java
private void startBootstrapServices() {
     // 省略部分代码
     Installer installer = mSystemServiceManager.startService(Installer.class);
     //省略部分代码......
     //调用PackageManagerService.main()方法,创建PackageManagerService对象
     mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
             mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
     mFirstBoot = mPackageManagerService.isFirstBoot();
     mPackageManager = mSystemContext.getPackageManager();
     if (!mRuntimeRestart && !isFirstBootOrUpgrade()) {
         MetricsLogger.histogram(null, "boot_package_manager_init_ready",
                 (int) SystemClock.elapsedRealtime());
     }
     // Manages A/B OTA dexopting. This is a bootstrap service as we need it to rename
     // A/B artifacts after boot, before anything else might touch/need them.
     // Note: this isn't needed during decryption (we don't have /data anyways).
     if (!mOnlyCore) {
         boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt",false);
         if (!disableOtaDexopt) {
             traceBeginAndSlog("StartOtaDexOptService");
             try {
                 OtaDexoptService.main(mSystemContext, mPackageManagerService);
             } catch (Throwable e) {
                 reportWtf("starting OtaDexOptService", e);
             } finally {
                 traceEnd();
             }
         }
     }
 }

?可以看到PackageManagerService对象是在SystemServer.startBootstrapServices()方法中创建的,我们看下PackageManagerService.main()方法。

//frameworks/base/services/core/java/com/android/server/pm/PakcageManagerservice.java
public static PackageManagerService main(Context context, Installer installer,
        boolean factoryTest, boolean onlyCore) {
    //检测pm.dexopt.xxx类型的系统属性是否被设置以及值是否合法
    PackageManagerServiceCompilerMapping.checkProperties();
    //创建PackageManagerService对象
    PackageManagerService m = new PackageManagerService(context, installer,
            factoryTest, onlyCore);
    m.enableSystemUserPackages();
    ServiceManager.addService("package", m);
    //创建PackageManagerNative对象
    final PackageManagerNative pmn = m.new PackageManagerNative();
    ServiceManager.addService("package_native", pmn);
    return m;
}

在了解PackageManagerService对象初始化之前,我们先看下PackageManagerService相关的类关系图

在这里插入图片描述

  • IPackageManager: AIDL接口,定义了PackageManagerService提供的方法。
  • PackageManagerService:IPackageManager接口的实现类,实现了IPackageManager.aidl中定义的方法。
  • Installer:系统服务,实际上是installd的客户端,用于提供应用安装、卸载等接口。
  • PackageManager:PackageManagerService对应用层提供接口的抽象类,应用通过Context的getPackageManager()抽象方法获取PackageManager对象;而最终实现是在ContextImpl的getPackageManager()方法中返回了ApplicationPackageManager对象。
  • ApplicationPackageManager:PackageManager的子类,依赖PakcageManagerService。所实现的抽象方法的功能都是通过PackageManagerService实现的。这样ApplicationPackageManager就把应用层接口PackageManager和PackageManagerService关联了起来。
  • PackageManagerInternal:为本地系统服务提供的PackageManagerService接口
  • IPackageManagerNative:定义了PackageManager中需要暴露给native层的方法,这些方法要和PackageManager.java中的方法对应上。
  • PackageManagerNative:IPackageManagerNative接口实现类。

PackageManagerService对象初始化

PackageManagerService的构造方法很长,根据EventLogTags中的定义可分为五个阶段,用伪代码表示为

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

BOOT_PROGRESS_PMS_START

这个阶段主要做了以下内容的工作

  • 将PMS对象封装成PackageManagerInternal对象,保存在LocalService中以便同一进程可以访问;
  • 创建UserManagerService对象;
  • 创建ComponentResolver对象,该对象用于解析Android四大组件。
  • 创建PermissionManagerService对象;
  • 创建Settings对象,注意该对象并不是Settings Provider,而是com.android.server.pm.Settings;用于保存动态设置的信息,比如应用权限、签名信息。
  • 为不同的SharedUserId添加不同的权限;
  • 加载应用的签名文件mac_permissions.xml
  • 创建PackageDexOptimizer、DexManager、ArtManagerService对象;
  • 创建SystemConfig实例,获取系统配置信息,配置共享lib库和权限配置信息
  • 创建不同用途的HandlerThread和Handler对象

这个过程总结起来就是使劲造,造什么?造对象呗。

public PackageManagerService(Context context, Installer installer,
           boolean factoryTest, boolean onlyCore) {
       LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
       Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
       EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
               SystemClock.uptimeMillis());

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

       mContext = context;

       mFactoryTest = factoryTest;
       mOnlyCore = onlyCore;
       mMetrics = new DisplayMetrics();
       mInstaller = installer;

       // Create sub-components that provide services / data. Order here is important.
       synchronized (mInstallLock) {
       synchronized (mPackages) {
           //将PackageManagerService封装成PackageManagerInternal对象,然后保存在LocalService中,LocalService中的对象只能在同一进程中被访问。
           LocalServices.addService(
                   PackageManagerInternal.class, new PackageManagerInternalImpl());
           sUserManager = new UserManagerService(context, this,
                   new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
           mComponentResolver = new ComponentResolver(sUserManager,
                   LocalServices.getService(PackageManagerInternal.class),
                   mPackages);
           mPermissionManager = PermissionManagerService.create(context,
                   mPackages /*externalLock*/);
           mDefaultPermissionPolicy = mPermissionManager.getDefaultPermissionGrantPolicy();
           mSettings = new Settings(Environment.getDataDirectory(),
                   mPermissionManager.getPermissionSettings(), mPackages);
       }
       }
		//为不同的SharedUserId添加不同的权限;
       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);

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

       mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
               "*dexopt*");
       mDexManager = new DexManager(mContext, this, mPackageDexOptimizer, installer, mInstallLock);
       mArtManagerService = new ArtManagerService(mContext, this, installer, mInstallLock);
       mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());

       mViewCompiler = new ViewCompiler(mInstallLock, mInstaller);

       mOnPermissionChangeListeners = new OnPermissionChangeListeners(
               FgThread.get().getLooper());

       getDefaultDisplayMetrics(context, mMetrics);

       Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
       //解析设备根目录、vendor、odm、oem以及product目录下的etc/sysconfig和etc/permissions中的配置和权限文件。
       SystemConfig systemConfig = SystemConfig.getInstance();
       mAvailableFeatures = systemConfig.getAvailableFeatures();
       Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);

       mProtectedPackages = new ProtectedPackages(mContext);

       mApexManager = new ApexManager(context);
       synchronized (mInstallLock) {
       // writer
       synchronized (mPackages) {
           //创建HandlerThread对象。
           mHandlerThread = new ServiceThread(TAG,
                   Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
           mHandlerThread.start();
           //创建PackageHandler对象,Handler在子线程中处理Message。
           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);
           }

           // Now that we have added all the libraries, iterate again to add dependency
           // information IFF their dependencies are added.
           long undefinedVersion = SharedLibraryInfo.VERSION_UNDEFINED;
           for (int i = 0; i < builtInLibCount; i++) {
               String name = libConfig.keyAt(i);
               SystemConfig.SharedLibraryEntry entry = libConfig.valueAt(i);
               final int dependencyCount = entry.dependencies.length;
               for (int j = 0; j < dependencyCount; j++) {
                   final SharedLibraryInfo dependency =
                       getSharedLibraryInfoLPr(entry.dependencies[j], undefinedVersion);
                   if (dependency != null) {
                       getSharedLibraryInfoLPr(name, undefinedVersion).addDependency(dependency);
                   }
               }
           }
           //加载应用签名文件 mac_permissions.xml 文件
           SELinuxMMAC.readInstallPolicy();

           Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
           FallbackCategoryProvider.loadFallbacks();
           Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);

           Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
           mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
           Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);

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

           if (!mOnlyCore && mFirstBoot) {
               requestCopyPreoptedFiles();
           }

           String customResolverActivityName = Resources.getSystem().getString(
                   R.string.config_customResolverActivity);
           if (!TextUtils.isEmpty(customResolverActivityName)) {
               mCustomResolverComponentName = ComponentName.unflattenFromString(
                       customResolverActivityName);
           }
}

在这个过程中,我们主要看下两个对象分别是Settings、SystemConfig对象。

Settings对象

//frameworks/base/ervices/core/java/com/android/server/pm/Settings.java
Settings(File dataDir, PermissionSettings permission,
        Object lock) {
    mLock = lock;
    mPermissions = permission;
    mRuntimePermissionsPersistence = new RuntimePermissionPersistence(mLock);

    mSystemDir = new File(dataDir, "system");
    //创建/data/system文件夹
    mSystemDir.mkdirs();
    FileUtils.setPermissions(mSystemDir.toString(),
            FileUtils.S_IRWXU|FileUtils.S_IRWXG
            |FileUtils.S_IROTH|FileUtils.S_IXOTH,
            -1, -1);
    //创建/data/system/packages.xml等文件实例
    mSettingsFilename = new File(mSystemDir, "packages.xml");
    mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml");
    mPackageListFilename = new File(mSystemDir, "packages.list");
    FileUtils.setPermissions(mPackageListFilename, 0640, SYSTEM_UID, PACKAGE_INFO_GID);

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

    
    mStoppedPackagesFilename = new File(mSystemDir, "packages-stopped.xml");
    mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml");
}

SystemConfig对象

SystemConfig() {
    // Read configuration from system
    readPermissions(Environment.buildPath(
            Environment.getRootDirectory(), "etc", "sysconfig"), ALLOW_ALL);

    // Read configuration from the old permissions dir
    readPermissions(Environment.buildPath(
            Environment.getRootDirectory(), "etc", "permissions"), ALLOW_ALL);

    // Vendors are only allowed to customize these
    int vendorPermissionFlag = ALLOW_LIBS | ALLOW_FEATURES | ALLOW_PRIVAPP_PERMISSIONS
            | ALLOW_ASSOCIATIONS;
    if (Build.VERSION.FIRST_SDK_INT <= Build.VERSION_CODES.O_MR1) {
        // For backward compatibility
        vendorPermissionFlag |= (ALLOW_PERMISSIONS | ALLOW_APP_CONFIGS);
    }
    readPermissions(Environment.buildPath(
            Environment.getVendorDirectory(), "etc", "sysconfig"), vendorPermissionFlag);
    readPermissions(Environment.buildPath(
            Environment.getVendorDirectory(), "etc", "permissions"), vendorPermissionFlag);

    // Allow ODM to customize system configs as much as Vendor, because /odm is another
    // vendor partition other than /vendor.
    int odmPermissionFlag = vendorPermissionFlag;
    readPermissions(Environment.buildPath(
            Environment.getOdmDirectory(), "etc", "sysconfig"), odmPermissionFlag);
    readPermissions(Environment.buildPath(
            Environment.getOdmDirectory(), "etc", "permissions"), odmPermissionFlag);

    String skuProperty = SystemProperties.get(SKU_PROPERTY, "");
    if (!skuProperty.isEmpty()) {
        String skuDir = "sku_" + skuProperty;

        readPermissions(Environment.buildPath(
                Environment.getOdmDirectory(), "etc", "sysconfig", skuDir), odmPermissionFlag);
        readPermissions(Environment.buildPath(
                Environment.getOdmDirectory(), "etc", "permissions", skuDir),
                odmPermissionFlag);
    }

    // Allow OEM to customize these
    int oemPermissionFlag = ALLOW_FEATURES | ALLOW_OEM_PERMISSIONS | ALLOW_ASSOCIATIONS;
    readPermissions(Environment.buildPath(
            Environment.getOemDirectory(), "etc", "sysconfig"), oemPermissionFlag);
    readPermissions(Environment.buildPath(
            Environment.getOemDirectory(), "etc", "permissions"), oemPermissionFlag);

    // Allow Product to customize all system configs
    readPermissions(Environment.buildPath(
            Environment.getProductDirectory(), "etc", "sysconfig"), ALLOW_ALL);
    readPermissions(Environment.buildPath(
            Environment.getProductDirectory(), "etc", "permissions"), ALLOW_ALL);

    // Allow /product_services to customize all system configs
    readPermissions(Environment.buildPath(
            Environment.getProductServicesDirectory(), "etc", "sysconfig"), ALLOW_ALL);
    readPermissions(Environment.buildPath(
            Environment.getProductServicesDirectory(), "etc", "permissions"), ALLOW_ALL);
}

在SystemConfig构造方法中,通过readPermissions()方法解析不同路径下的系统配置和权限信息。readPermissions()方法名有点误导人,实际上该方法会读取sysconfig和permissions文件夹下的xml文件,并解析这些文件,然后根据不同的tag将解析到的属性缓存起来。

void readPermissions(File libraryDir, int permissionFlag) {
    // Read permissions from given directory.
    if (!libraryDir.exists() || !libraryDir.isDirectory()) {
        if (permissionFlag == ALLOW_ALL) {
            Slog.w(TAG, "No directory " + libraryDir + ", skipping");
        }
        return;
    }
    if (!libraryDir.canRead()) {
        Slog.w(TAG, "Directory " + libraryDir + " cannot be read");
        return;
    }

    // Iterate over the files in the directory and scan .xml files
    File platformFile = null;
    for (File f : libraryDir.listFiles()) {
        if (!f.isFile()) {
            continue;
        }

        // We'll read platform.xml last
        if (f.getPath().endsWith("etc/permissions/platform.xml")) {
            platformFile = f;
            continue;
        }

        if (!f.getPath().endsWith(".xml")) {
            Slog.i(TAG, "Non-xml file " + f + " in " + libraryDir + " directory, ignoring");
            continue;
        }
        if (!f.canRead()) {
            Slog.w(TAG, "Permissions library file " + f + " cannot be read");
            continue;
        }
        //解析xml文件。
        readPermissionsFromXml(f, permissionFlag);
    }

    //最后解析etc/permissions/platform.xml文件
    if (platformFile != null) {
        readPermissionsFromXml(platformFile, permissionFlag);
    }
}

BOOT_PROGRESS_PMS_SYSTEM_SCAN_START

  • 读取环境变量BOOTCLASSPATH和SYSTEMSERVERCLASSPATH;
  • 对于旧版本升级的情况,将安装时获取权限变更为运行时申请权限;
  • 扫描/vendor、/product、/product_services、/odm下的overlay、priv-app、app目录下的应用以及/system/priv-app、/system/app、/system/framework下的应用并解析(我们在这把这些app称为系统app)。
  • 清除临时文件和清除没有关联app的SharedUserId信息
    synchronized (mPackages) {
	    //省略部分代码......
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
                startTime);
        //读取BOOTCLASSPATH和SYSTEMSERVERCLASSPATH环境变量,可以通过env命令查看当前设备的所有环境变量值
        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);
        }
        // 从Android M之前的版本升级过来时,将系统应用程序权限从安装提升到运行时
        mPromoteSystemApps =
                mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
        // When upgrading from pre-N, we need to handle package extraction like first boot,
        // as there is no profiling data available.
        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;
        int preUpgradeSdkVersion = ver.sdkVersion;
        // save off the names of pre-existing system packages prior to scanning; we don't
        // want to automatically grant runtime permissions for new system apps
        if (mPromoteSystemApps) {
            Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
            while (pkgSettingIter.hasNext()) {
                PackageSetting ps = pkgSettingIter.next();
                if (isSystemApp(ps)) {
                    mExistingSystemPackages.add(ps.name);
                }
            }
        }
        mCacheDir = preparePackageParserCache();
        // Set flag to monitor and not change apk file paths when
        // scanning install directories.
        int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
        if (mIsUpgrade || mFirstBoot) {
            scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
        }
        // 扫描/vendor、/product、/product_services、/odm下的overlay、priv-app、app目录下的应用
        // 以及/system/priv-app、/system/app、/system/framework下的应用并解析。
        scanDirTracedLI(new File(VENDOR_OVERLAY_DIR),
                mDefParseFlags
                | PackageParser.PARSE_IS_SYSTEM_DIR,
                scanFlags
                | SCAN_AS_SYSTEM
                | SCAN_AS_VENDOR,
                0);
        //省略部分代码.....
        // Prune any system packages that no longer exist.
        final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
        // Stub packages must either be replaced with full versions in the /data
        // partition or be disabled.
        final List<String> stubSystemApps = new ArrayList<>();
        if (!mOnlyCore) {
            // do this first before mucking with mPackages for the "expecting better" case
            final Iterator<PackageParser.Package> pkgIterator = mPackages.values().iterator();
            while (pkgIterator.hasNext()) {
                final PackageParser.Package pkg = pkgIterator.next();
                if (pkg.isStub) {
                    stubSystemApps.add(pkg.packageName);
                }
            }
            final Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
            while (psit.hasNext()) {
                PackageSetting ps = psit.next();
                /*
                 * If this is not a system app, it can't be a
                 * disable system app.
                 */
                if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
                    continue;
                }
                /*
                 * If the package is scanned, it's not erased.
                 */
                final PackageParser.Package scannedPkg = mPackages.get(ps.name);
                if (scannedPkg != null) {
                    /*
                     * If the system app is both scanned and in the
                     * disabled packages list, then it must have been
                     * added via OTA. Remove it from the currently
                     * scanned package so the previously user-installed
                     * application can be scanned.
                     */
                    if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
                        logCriticalInfo(Log.WARN,
                                "Expecting better updated system app for " + ps.name
                                + "; removing system app.  Last known"
                                + " codePath=" + ps.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");
                    // Actual deletion of code and data will be handled by later
                    // reconciliation step
                } else {
                    // we still have a disabled system package, but, it still might have
                    // been removed. check the code path still exists and check there's
                    // still a package. the latter can happen if an OTA keeps the same
                    // code path, but, changes the package name.
                    final PackageSetting disabledPs =
                            mSettings.getDisabledSystemPkgLPr(ps.name);
                    if (disabledPs.codePath == null || !disabledPs.codePath.exists()
                            || disabledPs.pkg == null) {
                        possiblyDeletedUpdatedSystemApps.add(ps.name);
                    } else {
                        // We're expecting that the system app should remain disabled, but add
                        // it to expecting better to recover in case the data version cannot
                        // be scanned.
                        mExpectingBetter.put(disabledPs.name, disabledPs.codePath);
                    }
                }
            }
        }
        //delete tmp files
        deleteTempPackageFiles();
        final int cachedSystemApps = PackageParser.sCachedPackageReadCount.get();
        // Remove any shared userIDs that have no associated packages
        mSettings.pruneSharedUsersLPw();
        final long systemScanTime = SystemClock.uptimeMillis() - startTime;
        final int systemPackagesCount = mPackages.size();
        Slog.i(TAG, "Finished scanning system apps. Time: " + systemScanTime
                + " ms, packageCount: " + systemPackagesCount
                + " , timePerPackage: "
                + (systemPackagesCount == 0 ? 0 : systemScanTime / systemPackagesCount)
                + " , cached: " + cachedSystemApps);
        if (mIsUpgrade && systemPackagesCount > 0) {
            MetricsLogger.histogram(null, "ota_package_manager_system_app_avg_scan_time",
                    ((int) systemScanTime) / systemPackagesCount);
        }
		//省略部分代码......
    }
        

在这个过程中有两个重要的功能:一是处理从Android M之前的版本升级到M及之后的版本时,更新APP的运行时权限。二是扫描系统中的app,然后解析为ParellelPackageParser.ParseResult对象。我们看下系统app解析的过程:

//frameworks/base/services/core/java/com/android/server/pm/PakcageManagerservice.java
private void scanDirTracedLI(File scanDir, final int parseFlags, int scanFlags, long currentTime) {
    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + scanDir.getAbsolutePath() + "]");
    try {
        scanDirLI(scanDir, parseFlags, scanFlags, currentTime);
    } finally {
        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
    }
}

private void scanDirLI(File scanDir, int parseFlags, int scanFlags, long currentTime) {
    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));
    }
    //创建并发解析类,通过'try()'的方式会在代码块结束时自动调用parallelPackageParser.close()方法
    try (ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
            mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir,
            mParallelPackageParserCallback)) {
        // 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.ParseResult存入阻塞队列。
            parallelPackageParser.submit(file, parseFlags);
            fileCount++;
        }

        // Process results one by one
        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.pkg.applicationInfo.isStaticSharedLibrary()) {
                    renameStaticSharedLibraryPackage(parseResult.pkg);
                }
                try {
                    scanPackageChildLI(parseResult.pkg, parseFlags, scanFlags,
                            currentTime, null);
                } catch (PackageManagerException e) {
                    errorCode = e.error;
                    Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
                }
            } else if (throwable instanceof PackageParser.PackageParserException) {
                PackageParser.PackageParserException e = (PackageParser.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);
            }

            // Delete invalid userdata apps
            if ((scanFlags & SCAN_AS_SYSTEM) == 0 &&
                    errorCode != PackageManager.INSTALL_SUCCEEDED) {
                logCriticalInfo(Log.WARN,
                        "Deleting invalid package at " + parseResult.scanFile);
                removeCodePathLI(parseResult.scanFile);
            }
        }
    }
}

整个解析过程是先向线程池提交解析任务,然后从保存解析结果的阻塞队列中获取解析结果。

apk文件解析实现如下,通过向线程池提交解析apk文件的任务;apk的解析由android.content.pm.PackageParser.parsePackage()完成;最后解析结果存在阻塞队列mQueue中。

//frameworks/base/services/core/java/com/android/server/pm/ParallelPackageParser.java
public void submit(File scanFile, int parseFlags) {
    mService.submit(() -> {
        ParseResult pr = new ParseResult();
        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parallel parsePackage [" + scanFile + "]");
        try {
            PackageParser pp = new PackageParser();
            pp.setSeparateProcesses(mSeparateProcesses);
            pp.setOnlyCoreApps(mOnlyCore);
            pp.setDisplayMetrics(mMetrics);
            pp.setCacheDir(mCacheDir);
            pp.setCallback(mPackageParserCallback);
            pr.scanFile = scanFile;
            pr.pkg = parsePackage(pp, scanFile, parseFlags);
        } catch (Throwable e) {
            pr.throwable = e;
        } finally {
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
        }
        try {
            //解析完成后将结果添加到阻塞队列mQueue
            mQueue.put(pr);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            // Propagate result to callers of take().
            // This is helpful to prevent main thread from getting stuck waiting on
            // ParallelPackageParser to finish in case of interruption
            mInterruptedInThread = Thread.currentThread().getName();
        }
    });
}

@VisibleForTesting
protected PackageParser.Package parsePackage(PackageParser packageParser, File scanFile,
        int parseFlags) throws PackageParser.PackageParserException {
    //通过PackageParser.parsePackage解析apk文件,这里主要是解析AndroidManifest.xml文件,得到文件中的信息
    return packageParser.parsePackage(scanFile, parseFlags, true /* useCaches */);
}

BOOT_PROGRESS_PMS_DATA_SCAN_START

? 这个阶段主要做了以下内容的工作:

  • 扫描/data/app下的apk文件并解析,得到Package信息。
  • 删除通过OTA升级已经不存在的app的权限配置信息;删除已经不存在的APP。
  • 更新App共享库路径信息
    

   //省略部分代码......
	
    if (!mOnlyCore) {
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
                SystemClock.uptimeMillis());
        //扫描并解析data/app目录下的apk文件并解析
        scanDirTracedLI(sAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
        
        for (int i = possiblyDeletedUpdatedSystemApps.size() - 1; i >= 0; --i) {
            final String packageName = possiblyDeletedUpdatedSystemApps.get(i);
            final PackageParser.Package pkg = mPackages.get(packageName);
            final String msg;
            //删除通过OTA升级已经不存在的app的权限配置信息;
            mSettings.removeDisabledSystemPackageLPw(packageName);
            if (pkg == null) {
                // should have found an update, but, we didn't; remove everything
                msg = "Updated system package " + packageName
                        + " no longer exists; removing its data";
                // Actual deletion of code and data will be handled by later
                // reconciliation step
            } else {
                // found an update; revoke system privileges
                msg = "Updated system package " + packageName
                        + " no longer exists; rescanning package on data";
                // NOTE: We don't do anything special if a stub is removed from the
                // system image. But, if we were [like removing the uncompressed
                // version from the /data partition], this is where it'd be done.
                // remove the package from the system and re-scan it without any
                // special privileges
                removePackageLI(pkg, true);
                try {
                    final File codePath = new File(pkg.applicationInfo.getCodePath());
                    scanPackageTracedLI(codePath, 0, scanFlags, 0, null);
                } catch (PackageManagerException e) {
                    Slog.e(TAG, "Failed to parse updated, ex-system package: "
                            + e.getMessage());
                }
            }
            // one final check. if we still have a package setting [ie. it was
            // previously scanned and known to the system], but, we don't have
            // a package [ie. there was an error scanning it from the /data
            // partition], completely remove the package data.
            final PackageSetting ps = mSettings.mPackages.get(packageName);
            if (ps != null && mPackages.get(packageName) == null) {
                removePackageDataLIF(ps, null, null, 0, false);
            }
            logCriticalInfo(Log.WARN, msg);
        }
        /*
         * Make sure all system apps that we expected to appear on
         * the userdata partition actually showed up. If they never
         * appeared, crawl back and revive the system version.
         */
        for (int i = 0; i < mExpectingBetter.size(); i++) {
            final String packageName = mExpectingBetter.keyAt(i);
            if (!mPackages.containsKey(packageName)) {
                final File scanFile = mExpectingBetter.valueAt(i);
                logCriticalInfo(Log.WARN, "Expected better " + packageName
                        + " but never showed up; reverting to system");
                final @ParseFlags int reparseFlags;
                final @ScanFlags int rescanFlags;
                if (FileUtils.contains(privilegedAppDir, scanFile)) {
                    reparseFlags =
                            mDefParseFlags |
                            PackageParser.PARSE_IS_SYSTEM_DIR;
                    rescanFlags =
                            scanFlags
                            | SCAN_AS_SYSTEM
                            | SCAN_AS_PRIVILEGED;
                } else if (FileUtils.contains(systemAppDir, scanFile)) {
                    reparseFlags =
                            mDefParseFlags |
                            PackageParser.PARSE_IS_SYSTEM_DIR;
                    rescanFlags =
                            scanFlags
                            | SCAN_AS_SYSTEM;
                } else if (FileUtils.contains(privilegedVendorAppDir, scanFile)
                        || FileUtils.contains(privilegedOdmAppDir, scanFile)) {
                    reparseFlags =
                            mDefParseFlags |
                            PackageParser.PARSE_IS_SYSTEM_DIR;
                    rescanFlags =
                            scanFlags
                            | SCAN_AS_SYSTEM
                            | SCAN_AS_VENDOR
                            | SCAN_AS_PRIVILEGED;
                } else if (FileUtils.contains(vendorAppDir, scanFile)
                        || FileUtils.contains(odmAppDir, scanFile)) {
                    reparseFlags =
                            mDefParseFlags |
                            PackageParser.PARSE_IS_SYSTEM_DIR;
                    rescanFlags =
                            scanFlags
                            | SCAN_AS_SYSTEM
                            | SCAN_AS_VENDOR;
                } else if (FileUtils.contains(oemAppDir, scanFile)) {
                    reparseFlags =
                            mDefParseFlags |
                            PackageParser.PARSE_IS_SYSTEM_DIR;
                    rescanFlags =
                            scanFlags
                            | SCAN_AS_SYSTEM
                            | SCAN_AS_OEM;
                } else if (FileUtils.contains(privilegedProductAppDir, scanFile)) {
                    reparseFlags =
                            mDefParseFlags |
                            PackageParser.PARSE_IS_SYSTEM_DIR;
                    rescanFlags =
                            scanFlags
                            | SCAN_AS_SYSTEM
                            | SCAN_AS_PRODUCT
                            | SCAN_AS_PRIVILEGED;
                } else if (FileUtils.contains(productAppDir, scanFile)) {
                    reparseFlags =
                            mDefParseFlags |
                            PackageParser.PARSE_IS_SYSTEM_DIR;
                    rescanFlags =
                            scanFlags
                            | SCAN_AS_SYSTEM
                            | SCAN_AS_PRODUCT;
                } else if (FileUtils.contains(privilegedProductServicesAppDir, scanFile)) {
                    reparseFlags =
                            mDefParseFlags |
                            PackageParser.PARSE_IS_SYSTEM_DIR;
                    rescanFlags =
                            scanFlags
                            | SCAN_AS_SYSTEM
                            | SCAN_AS_PRODUCT_SERVICES
                            | SCAN_AS_PRIVILEGED;
                } else if (FileUtils.contains(productServicesAppDir, scanFile)) {
                    reparseFlags =
                            mDefParseFlags |
                            PackageParser.PARSE_IS_SYSTEM_DIR;
                    rescanFlags =
                            scanFlags
                            | SCAN_AS_SYSTEM
                            | SCAN_AS_PRODUCT_SERVICES;
                } else {
                    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());
                }
            }
        }
        // Uncompress and install any stubbed system applications.
        // This must be done last to ensure all stubs are replaced or disabled.
        installSystemStubPackages(stubSystemApps, scanFlags);
        final int cachedNonSystemApps = PackageParser.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) {
            MetricsLogger.histogram(null, "ota_package_manager_data_app_avg_scan_time",
                    ((int) dataScanTime) / dataPackagesCount);
        }
    }
    mExpectingBetter.clear();
    // Resolve the storage manager.
    mStorageManagerPackage = getStorageManagerPackageName();
    // Resolve protected action filters. Only the setup wizard is allowed to
    // have a high priority filter for these actions.
    mSetupWizardPackage = getSetupWizardPackageName();
    mComponentResolver.fixProtectedFilterPriorities();
    mSystemTextClassifierPackage = getSystemTextClassifierPackageName();
    mWellbeingPackage = getWellbeingPackageName();
    mDocumenterPackage = getDocumenterPackageName();
    mConfiguratorPackage =
            mContext.getString(R.string.config_deviceConfiguratorPackageName);
    mAppPredictionServicePackage = getAppPredictionServicePackageName();
    mIncidentReportApproverPackage = getIncidentReportApproverPackageName();
    //更新应用共享库信息
    updateAllSharedLibrariesLocked(null, Collections.unmodifiableMap(mPackages));
    for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
        // NOTE: We ignore potential failures here during a system scan (like
        // the rest of the commands above) because there's precious little we
        // can do about it. A settings error is reported, though.
        final List<String> changedAbiCodePath =
                adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
        if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
            for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
                final String codePathString = changedAbiCodePath.get(i);
                try {
                    mInstaller.rmdex(codePathString,
                            getDexCodeInstructionSet(getPreferredInstructionSet()));
                } catch (InstallerException ignored) {
                }
            }
        }
        // Adjust seInfo to ensure apps which share a sharedUserId are placed in the same
        // SELinux domain.
        setting.fixSeInfoLocked();
    }
    // Now that we know all the packages we are keeping,
    // read and update their last usage times.
    mPackageUsage.read(mPackages);
    mCompilerStats.read();
    
	//省略部分代码......

BOOT_PROGRESS_PMS_SCAN_END

? 这个阶段主要做了以下内容的工作:

  • 如果sdk版本发生变化,则更新权限
  • OTA升级后首次启动,清除不必要的缓存数据
  • 权限等默认更新后,清理相关数据
  • 更新/data/system/packages.xml
           //省略部分代码
            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
                    SystemClock.uptimeMillis());
            Slog.i(TAG, "Time to scan packages: "
                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
                    + " seconds");

            // If the platform SDK has changed since the last time we booted,
            // we need to re-grant app permission to catch any new ones that
            // appear.  This is really a hack, and means that apps can in some
            // cases get permissions that the user didn't initially explicitly
            // allow...  it would be nice to have some better way to handle
            // this situation.
            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, mPackages.values(),
                    mPermissionCallback);
            ver.sdkVersion = mSdkVersion;

            
            //如果是第一次启动或者从M之前的版本升级过来,需要初始化/etc/preferred-apps路径下的xml配置文件
            if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
                for (UserInfo user : sUserManager.getUsers(true)) {
                    mSettings.applyDefaultPreferredAppsLPw(user.id);
                    primeDomainVerificationsLPw(user.id);
                }
            }

            // Prepare storage for system user really early during boot,
            // since core system apps like SettingsProvider and SystemUI
            // can't wait for user to start
            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.get().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) {
                    PackageParser.Package pkg = null;
                    synchronized (mPackages) {
                        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");

            
            //OTA升级后首次开机,清除缓存目录。
            if (mIsUpgrade && !onlyCore) {
                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);
                    }
                }
                ver.fingerprint = Build.FINGERPRINT;
            }

            // Grandfather existing (installed before Q) non-system apps to hide
            // their icons in launcher.
            if (!onlyCore && 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);
                }
            }

            // clear only after permissions and other defaults have been updated
            mExistingSystemPackages.clear();
            mPromoteSystemApps = false;

            // All the changes are done during package scanning.
            ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;

            // can downgrade to reader
            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
            //更新设置信息到/data/system/packages.xml文件中
            mSettings.writeLPr();
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);

BOOT_PROGRESS_PMS_READY

? 这个阶段主要做了以下内容的工作:

  • 创建PackageInstallerService对
  • GC回收内存
            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;
                }
                mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
                        PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
                        SharedLibraryInfo.VERSION_UNDEFINED);
                mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
                        PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
                        SharedLibraryInfo.VERSION_UNDEFINED);
            } else {
                mRequiredVerifierPackage = null;
                mRequiredInstallerPackage = null;
                mRequiredUninstallerPackage = null;
                mIntentFilterVerifierComponent = null;
                mIntentFilterVerifier = null;
                mServicesSystemSharedLibraryPackageName = null;
                mSharedSystemSharedLibraryPackageName = null;
            }
            // PermissionController hosts default permission granting and role management, so it's a
            // critical part of the core system.
            mRequiredPermissionControllerPackage = getRequiredPermissionControllerLPr();

            // Initialize InstantAppRegistry's Instant App list for all users.
            final int[] userIds = UserManagerService.getInstance().getUserIds();
            for (PackageParser.Package pkg : mPackages.values()) {
                if (pkg.isSystem()) {
                    continue;
                }
                for (int userId : userIds) {
                    final PackageSetting ps = (PackageSetting) pkg.mExtras;
                    if (ps == null || !ps.getInstantApp(userId) || !ps.getInstalled(userId)) {
                        continue;
                    }
                    mInstantAppRegistry.addInstantAppLPw(userId, ps.appId);
                }
            }
            //创建PackageInstallerService对象,该对象负责实现安装、卸载应用功能。
            mInstallerService = new PackageInstallerService(context, this, mApexManager);
            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);

            // Read and update the usage of dex files.
            // Do this at the end of PM init so that all the packages have their
            // data directory reconciled.
            // At this point we know the code paths of the packages, so we can validate
            // the disk file and build the internal cache.
            // The usage file is expected to be small so loading and verifying it
            // should take a fairly small time compare to the other activities (e.g. package
            // scanning).
            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) {
                MetricsLogger.histogram(null, "ota_package_manager_init_time",
                        (int) (SystemClock.uptimeMillis() - startTime));
            }
        } // synchronized (mPackages)
        } // synchronized (mInstallLock)

        mModuleInfoProvider = new ModuleInfoProvider(mContext, this);

        // Now after opening every single application zip, make sure they
        // are all flushed.  Not really needed, but keeps things nice and
        // tidy.
        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");
        //GC回收堆内存。
        Runtime.getRuntime().gc();
        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);

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

        PackageParser.readConfigUseRoundIcon(mContext.getResources());

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

        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);

总结

? PackageManagerService是Android系统中重要系统服务之一,应用安装、卸载、解析、权限管理等都跟它有关;PackageManagerService是由SystemServer启动的;PackageManagerService对象创建按EventLogTags分为五个阶段,分别是: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。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-03-03 16:26:11  更:2022-03-03 16:28:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 16:55:06-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码