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
- A Zygote split SystemServer process that creates PMS during initialization
- Scan pacages.xml, just like the Windows registry, which contains package names, permissions, etc., and updates it as APK is uninstalled and installed
- 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
- When we click on an apk actually opened the packages/app/PackageInstaller PackageInstallerActivity
- 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)