Source code analysis - start process of PackageManagerService(1)

Posted by joeman3429 on Sun, 05 Apr 2020 01:16:39 +0200

I. overview

  1. background

    During application installation, it also includes the use of package manager service (PMS);
    This paper mainly analyzes the initialization process of PackageManagerService;

  2. Edition

    system Edition
    Android 23
  3. Start process of PackageManagerService:

    Zygote --> SystemServer --> PackageManagerService(PMS)

  4. For system server startup, refer to:
    Source code analysis - system server startup

2, PMS initialization

2.1 PMS initialization sequence diagram

2.2 PMS source code

Class SystemServer

public static void main(String[] args) {
   new SystemServer().run();
}

private void run() {
    // ... omit large code
    startBootstrapServices();
}

private void startBootstrapServices() {
     /* 
      * Create an ActivityManagerService instance
      * Note: the mpactivitymanagerservice is added to the system service manager for maintenance
      */
     mActivityManagerService = mSystemServiceManager.startService(
             ActivityManagerService.Lifecycle.class).getService();

     /*
      * Create PackageManagerService instance
      * Note: PackageManagerService is not maintained by SystemServiceManager;
      * Thinking: who has defended it?
      */
     mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
             mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);     
}

Class PackageManagerService

public static PackageManagerService main(Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {
    // Self-check for initial settings.
    PackageManagerServiceCompilerMapping.checkProperties();

    PackageManagerService m = new PackageManagerService(context, installer,
            factoryTest, onlyCore);
    m.enableSystemUserPackages();

    // Add PackageManagerService instance to ServiceManager here
    ServiceManager.addService("package", m);
    return m;
}

public PackageManagerService(Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {



                        try {
                            scanPackageLI(scanFile, reparseFlags, scanFlags, 0, null);
                        } catch (PackageManagerException e) {
                            Slog.e(TAG, "Failed to parse original system package: "
                                    + e.getMessage());
                        }
                    }
                }
            }
            mExpectingBetter.clear();

            // Now that we know all of the shared libraries, update all clients to have
            // the correct library paths.
            updateAllSharedLibrariesLPw();

            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.
                adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */,
                        false /* force dexopt */, false /* defer dexopt */);
            }

            // Now that we know all the packages we are keeping,
            // read and update their last usage times.
            mPackageUsage.readLP();

            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.
            int updateFlags = UPDATE_PERMISSIONS_ALL;
            if (ver.sdkVersion != mSdkVersion) {
                Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
                        + mSdkVersion + "; regranting permissions for internal storage");
                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
            }
            updatePermissionsLPw(null, null, updateFlags);
            ver.sdkVersion = mSdkVersion;
            // clear only after permissions have been updated
            mExistingSystemPackages.clear();
            mPromoteSystemApps = false;

            // If this is the first boot, and it is a normal boot, then
            // we need to initialize the default preferred apps.
            if (!mRestoredSettings && !onlyCore) {
                mSettings.applyDefaultPreferredAppsLPw(this, UserHandle.USER_OWNER);
                applyFactoryDefaultBrowserLPw(UserHandle.USER_OWNER);
                primeDomainVerificationsLPw(UserHandle.USER_OWNER);
            }

            // If this is first boot after an OTA, and a normal boot, then
            // we need to clear code cache directories.
            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)) {
                        deleteCodeCacheDirsLI(ps.volumeUuid, ps.name);
                    }
                }
                ver.fingerprint = Build.FINGERPRINT;
            }

            checkDefaultBrowser();

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

            // can downgrade to reader
            mSettings.writeLPr();

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

            mRequiredVerifierPackage = getRequiredVerifierLPr();
            mRequiredInstallerPackage = getRequiredInstallerLPr();

            mInstallerService = new PackageInstallerService(context, this);

            mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
            mIntentFilterVerifier = new IntentVerifierProxy(mContext,
                    mIntentFilterVerifierComponent);

        } // synchronized (mPackages)
        } // synchronized (mInstallLock)

        // Now after opening every single application zip, make sure they
        // are all flushed.  Not really needed, but keeps things nice and
        // tidy.
        Runtime.getRuntime().gc();

        // Expose private service for system components to use.
        LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
    }

Summary

  1. PackageManagerService instance is stored by ServiceManager;
  2. The ActivityManagerService instance is stored by SystemServiceManager;
  3. 3.

Reference resources

  1. The first stage of source code analysis of PackageManagerService (2)

Topics: Android REST SDK