This article source code is Android29, 10.0 code

An overview of

PackageManagerService is also a core system service, which manages APK installation, uninstallation, information query and permission management, etc. Manages the main functions related to package:

  • Parse the AndroidNanifest. XML manifest file
  • Scan. Apk files, install system applications, install local applications, etc
  • Manage local applications, including installation, uninstallation, and application information query (such as permissions)

The second start

When the system boots up, that is, when it is turned on. Start the PackageManagerService main method by calling startBootstrapServices in SystemServer’s main method.

private void startBootstrapServices(a) {
	// omit the codemPackageManagerService = PackageManagerService.main(mSystemContext, installer, mFactoryTestMode ! = FactoryTest.FACTORY_TEST_OFF, mOnlyCore); }private void startOtherServices(a) {
   // omit the code
   
   / / dex optimization
   mPackageManagerService.updatePackagesIfNeeded();
   // Disk maintenance
   mPackageManagerService.performFstrimIfNeeded();
   // Things that need to be processed when ready, such as processing all messages waiting for the system to be ready
   mPackageManagerService.systemReady();
}
Copy the code

Three Startup summary

  1. A Zygote split SystemServer process that creates PMS during initialization
  2. Scan pacages.xml, just like the Windows registry, which contains package names, permissions, etc., and updates it as APK is uninstalled and installed
  3. Scan all apK, system/app,data/app (user), the more the user installs the program, the longer the scan time, the general cost of boot here (also is to start various services in SystemServer). PackageParser parses androidmanifest.xml in the APK file

Save it. That’s where the desktop gets the data

Install the apk

  1. When we click on an apk actually opened the packages/app/PackageInstaller PackageInstallerActivity
  2. And then when we hit OK, we open the InstallAppProgress Activity, which is the transfer chrysanthemum page,

Register the PackageInstallObserver to listen for the setup callback and then call the PackageInstallerService, 4. Install apK to data/app, create path of data/data/ package name, so library lib, file, cache, database and other folders, update Settings information. It has teses.xml, something like a registry 6. When the app is installed, broadcast Intent.action_package_added to Laucher, complete

The main PackageManagerService

The main() method does the following:

  • Checking System Properties
  • Initialize PackageManagerService
  • Example Initialize some application services, which are mainly used in multi-user scenarios
  • Register the Package service with the ServiceManager
  • Registering the Package_native service with the ServiceManager is primarily for native code calls
public static PackageManagerService main(Context context, Installer installer,
        boolean factoryTest, boolean onlyCore) {
    // Check system properties
    PackageManagerServiceCompilerMapping.checkProperties();

	// Initialize the PackageManagerService
    PackageManagerService m = new PackageManagerService(context, installer,
            factoryTest, onlyCore);
    // Enable some applications to serve multi-user scenarios
    m.enableSystemUserPackages();
    // Register the Package service with the ServiceManager
    ServiceManager.addService("package", m);
    final PackageManagerNative pmn = m.new PackageManagerNative(a);
     // Register the Package_native service with the ServiceManager, mainly for native code calls
    ServiceManager.addService("package_native", pmn);
    return m;
}
Copy the code

PackageManagerService constructor

I’m going to omit unnecessary code

public PackageManagerService(Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {
    // Screen width, height, resolution, etc
    mMetrics = new DisplayMetrics();
    // Installer object, initialized in SystemServer, apK installation and uninstallation are finally implemented by calling installd
    mInstaller = installer;   
    synchronized (mInstallLock) {
    synchronized (mPackages) {
        // Expose private service for system components to use.
        LocalServices.addService(
                PackageManagerInternal.class, new PackageManagerInternalImpl());
        //UserManager is a new feature in Android 4.0, that is, a mobile phone can have multiple users, multiple configurations,
        // So far, I haven't found his app yet
        sUserManager = new UserManagerService(context, this.new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
        // Parse Activities, Services, providers and Receivers
        mComponentResolver = new ComponentResolver(sUserManager,
                LocalServices.getService(PackageManagerInternal.class),
                mPackages);
         // Permission management
        mPermissionManager = PermissionManagerService.create(context,
                mPackages /*externalLock*/);
        mDefaultPermissionPolicy = mPermissionManager.getDefaultPermissionGrantPolicy();
        // Create a Settings object that contains important file management such as packs.xml and packs.list
        mSettings = new Settings(Environment.getDataDirectory(),
                mPermissionManager.getPermissionSettings(), mPackages);
         
        // Optimization of dex
       mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
                "*dexopt*");
        / / dex management
        mDexManager = new DexManager(mContext, this, mPackageDexOptimizer, installer, mInstallLock);
        //ART VM management
        mArtManagerService = new ArtManagerService(mContext, this, installer, mInstallLock);
        
        // Permission listener
      mOnPermissionChangeListeners = new OnPermissionChangeListeners(
                FgThread.get().getLooper());

		// Get the default DisplayMetrics
        getDefaultDisplayMetrics(context, mMetrics);
		//
        SystemConfig systemConfig = SystemConfig.getInstance();
        
        synchronized (mPackages) {
        	// PMS thread, rotation training, app installation and uninstallation
            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);

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

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

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

            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
            // Read and parse XML files under file /data/system
            // Packages. XML and packages-backup. XML package information and permissions
            // This file is updated during uninstallation and update operations. This file holds some information about the package in the system
            // It is equivalent to a registry
            // packages.list 
            / / packages - stopped. XML and packages - stopped - backup. XMLmFirstBoot = ! mSettings.readLPw(sUserManager.getUsers(false));
           / /...

			// Prepare to parse Package
            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;
            }
			// The following packages are scanned in the corresponding directory and parsed into PackageParser instance classes
			// Scan apK under /vendor/overlay
            scanDirTracedLI(new File(VENDOR_OVERLAY_DIR),
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_VENDOR,
                    0);
            scanDirTracedLI(new File(PRODUCT_OVERLAY_DIR),
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_PRODUCT,
                    0);
            scanDirTracedLI(new File(PRODUCT_SERVICES_OVERLAY_DIR),
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_PRODUCT_SERVICES,
                    0);
            scanDirTracedLI(new File(ODM_OVERLAY_DIR),
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_ODM,
                    0);
            scanDirTracedLI(new File(OEM_OVERLAY_DIR),
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_OEM,
                    0);

            mParallelPackageParserCallback.findStaticOverlayPackages();

            // Find base frameworks (resource packages without code).
            scanDirTracedLI(frameworkDir,
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_NO_DEX
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_PRIVILEGED,
                    0);
            if(! mPackages.containsKey("android")) {
                throw new IllegalStateException(
                        "Failed to load frameworks package; check log for warnings");
            }

            // Collect privileged system packages.
            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
            scanDirTracedLI(privilegedAppDir,
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_PRIVILEGED,
                    0);

            // Collect ordinary system packages.
            final File systemAppDir = new File(Environment.getRootDirectory(), "app");
            scanDirTracedLI(systemAppDir,
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM,
                    0);

            // Collect privileged vendor packages.
            File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");
            try {
                privilegedVendorAppDir = privilegedVendorAppDir.getCanonicalFile();
            } catch (IOException e) {
                // failed to look up canonical path, continue with original one
            }
            scanDirTracedLI(privilegedVendorAppDir,
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_VENDOR
                    | SCAN_AS_PRIVILEGED,
                    0);

            // Collect ordinary vendor packages.
            File vendorAppDir = new File(Environment.getVendorDirectory(), "app");
            try {
                vendorAppDir = vendorAppDir.getCanonicalFile();
            } catch (IOException e) {
                // failed to look up canonical path, continue with original one
            }
            scanDirTracedLI(vendorAppDir,
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_VENDOR,
                    0);

            // Collect privileged odm packages. /odm is another vendor partition
            // other than /vendor.
            File privilegedOdmAppDir = new File(Environment.getOdmDirectory(),
                        "priv-app");
            try {
                privilegedOdmAppDir = privilegedOdmAppDir.getCanonicalFile();
            } catch (IOException e) {
                // failed to look up canonical path, continue with original one
            }
            scanDirTracedLI(privilegedOdmAppDir,
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_VENDOR
                    | SCAN_AS_PRIVILEGED,
                    0);

            // Collect ordinary odm packages. /odm is another vendor partition
            // other than /vendor.
            File odmAppDir = new File(Environment.getOdmDirectory(), "app");
            try {
                odmAppDir = odmAppDir.getCanonicalFile();
            } catch (IOException e) {
                // failed to look up canonical path, continue with original one
            }
            scanDirTracedLI(odmAppDir,
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_VENDOR,
                    0);

            // Collect all OEM packages.
            final File oemAppDir = new File(Environment.getOemDirectory(), "app");
            scanDirTracedLI(oemAppDir,
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_OEM,
                    0);

            // Collected privileged /product packages.
            File privilegedProductAppDir = new File(Environment.getProductDirectory(), "priv-app");
            try {
                privilegedProductAppDir = privilegedProductAppDir.getCanonicalFile();
            } catch (IOException e) {
                // failed to look up canonical path, continue with original one
            }
            scanDirTracedLI(privilegedProductAppDir,
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_PRODUCT
                    | SCAN_AS_PRIVILEGED,
                    0);

            // Collect ordinary /product packages.
            File productAppDir = new File(Environment.getProductDirectory(), "app");
            try {
                productAppDir = productAppDir.getCanonicalFile();
            } catch (IOException e) {
                // failed to look up canonical path, continue with original one
            }
            scanDirTracedLI(productAppDir,
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_PRODUCT,
                    0);

           // The back is not moving
          
    
 }
Copy the code

reference

Android 10.0 PackageManagerService (1)