/** * Keep track of all those APKs everywhere. * <p> * Internally there are two important locks: * <ul> * <li>{@link #mPackages} is used to guard all in-memory parsed package details * and other related state. It is a fine-grained lock that should only be held * momentarily, as it's one of the most contended locks in the system. * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose * operations typically involve heavy lifting of application data on disk. Since * {@code installd} is single-threaded, and it's operations can often be slow, * this lock should never be acquired while already holding {@link #mPackages}. * Conversely, it's safe to acquire {@link #mPackages} momentarily while already * holding {@link #mInstallLock}. * </ul> * Many internal methods rely on the caller to hold the appropriate locks, and * this contract is expressed through method name suffixes: * <ul> * <li>fooLI(): the caller must hold {@link #mInstallLock} * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package * being modified must be frozen * <li>fooLPr(): the caller must hold {@link #mPackages} for reading * <li>fooLPw(): the caller must hold {@link #mPackages} for writing * </ul> * <p> * Because this class is very central to the platform's security; please run all * CTS and unit tests whenever making modifications: * * <pre> * $ runtest -c android.content.pm.PackageManagerTests frameworks-core * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases * </pre> */
/** * Starts the small tangle of critical services that are needed to get * the system off the ground. These services have complex mutual dependencies * which is why we initialize them all in one place here. Unless your service * is also entwined in these dependencies, it should be initialized in one of * the other functions. */ privatevoidstartBootstrapServices() {//Bootstrap:引导,启动引导服务 //…… // Wait for installd to finish starting up so that it has a chance to // create critical directories such as /data/user with the appropriate // permissions. We need this to complete before we initialize other services. traceBeginAndSlog("StartInstaller"); Installerinstaller= mSystemServiceManager.startService(Installer.class); traceEnd(); //…… // Only run "core" apps if we're encrypting the device. StringcryptState= SystemProperties.get("vold.decrypt"); if (ENCRYPTING_STATE.equals(cryptState)) { Slog.w(TAG, "Detected encryption in progress - only parsing core apps"); mOnlyCore = true; } elseif (ENCRYPTED_STATE.equals(cryptState)) { Slog.w(TAG, "Device encrypted - only parsing core apps"); mOnlyCore = true; }
finalVersionInfover= mSettings.getInternalVersion(); mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint); //…… // Set flag to monitor and not change apk file paths when // scanning install directories. intscanFlags= SCAN_BOOTING | SCAN_INITIAL;
// Collect vendor overlay packages. (Do this before scanning any apps.) // For security and version matching reason, only consider // overlay packages if they reside in the right directory. scanDirTracedLI(newFile(VENDOR_OVERLAY_DIR), mDefParseFlags | PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
// Prune any system packages that no longer exist. final List<String> possiblyDeletedUpdatedSystemApps = newArrayList<>(); // Stub packages must either be replaced with full versions in the /data // partition or be disabled. final List<String> stubSystemApps = newArrayList<>(); 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.Packagepkg= pkgIterator.next(); if (pkg.isStub) { stubSystemApps.add(pkg.packageName); } }
final Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); while (psit.hasNext()) { PackageSettingps= psit.next();
/* * If this is not a system app, it can't be a * disable system app.OTA的升级只涉及到系统app。 */ if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { continue; }
/* * If the package is scanned, it's not erased. */ final PackageParser.PackagescannedPkg= 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)) { 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. finalPackageSettingdisabledPs= mSettings.getDisabledSystemPkgLPr(ps.name); if (disabledPs.codePath == null || !disabledPs.codePath.exists() || disabledPs.pkg == null) { possiblyDeletedUpdatedSystemApps.add(ps.name); } } } }
//look for any incomplete package installations //删除未完成安装的package ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr(); for (inti=0; i < deletePkgsList.size(); i++) { // Actual deletion of code and data will be handled by later // reconciliation step finalStringpackageName= deletePkgsList.get(i).name; logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName); synchronized (mPackages) { mSettings.removePackageLPw(packageName); } }
// Remove disable package settings for updated system apps that were // removed via an OTA. If the update is no longer present, remove the // app completely. Otherwise, revoke their system privileges. for (String deletedAppName : possiblyDeletedUpdatedSystemApps) { PackageParser.PackagedeletedPkg= mPackages.get(deletedAppName); mSettings.removeDisabledSystemPackageLPw(deletedAppName);
final String msg; if (deletedPkg == null) { // should have found an update, but, we didn't; remove everything msg = "Updated system package " + deletedAppName + " 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 + " + deletedAppName + " no longer exists; revoking system privileges";
// Don't do anything if a stub is removed from the system image. If // we were to remove the uncompressed version from the /data partition, // this is where it'd be done.
/* * 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 (inti=0; i < mExpectingBetter.size(); i++) { finalStringpackageName= mExpectingBetter.keyAt(i); if (!mPackages.containsKey(packageName)) { finalFilescanFile= mExpectingBetter.valueAt(i);
logCriticalInfo(Log.WARN, "Expected better " + packageName + " but never showed up; reverting to system");
try { scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 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. decompressSystemApplications(stubSystemApps, scanFlags);
// 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(); if (mProtectedFilters.size() > 0) { if (DEBUG_FILTERS && mSetupWizardPackage == null) { Slog.i(TAG, "No setup wizard;" + " All protected intents capped to priority 0"); } for (ActivityIntentInfo filter : mProtectedFilters) { if (filter.activity.info.packageName.equals(mSetupWizardPackage)) { if (DEBUG_FILTERS) { Slog.i(TAG, "Found setup wizard;" + " allow priority " + filter.getPriority() + ";" + " package: " + filter.activity.info.packageName + " activity: " + filter.activity.className + " priority: " + filter.getPriority()); } // skip setup wizard; allow it to keep the high priority filter continue; } if (DEBUG_FILTERS) { Slog.i(TAG, "Protected action; cap priority to 0;" + " package: " + filter.activity.info.packageName + " activity: " + filter.activity.className + " origPrio: " + filter.getPriority()); } filter.setPriority(0); } } mDeferProtectedFilters = false; mProtectedFilters.clear();
// Now that we know all of the shared libraries, update all clients to have // the correct library paths. updateAllSharedLibrariesLPw(null);
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/*scannedPackage*/); }
// Now that we know all the packages we are keeping, // read and update their last usage times. mPackageUsage.read(mPackages); mCompilerStats.read();
// 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. intupdateFlags= 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; } //当sdk版本不一致时,,更新相关信息,并给需要使用权限的apk分配相应的权限 updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags); ver.sdkVersion = mSdkVersion;
// If this is the first boot or an update from pre-M, and it is a normal // boot, then we need to initialize the default preferred apps across // all defined users. //当这是ota后的首次启动,正常启动则需要清除目录的缓存代码 if (!onlyCore && (mPromoteSystemApps || !mRestoredSettings)) { for (UserInfo user : sUserManager.getUsers(true)) { mSettings.applyDefaultPreferredAppsLPw(this, user.id); applyFactoryDefaultBrowserLPw(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 finalint storageFlags; if (StorageManager.isFileEncryptedNativeOrEmulated()) { storageFlags = StorageManager.FLAG_STORAGE_DE; } else { storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; } reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL, UserHandle.USER_SYSTEM, storageFlags);
// If this is first boot after an OTA, and a normal boot, then // we need to clear code cache directories. // Note that we do *not* clear the application profiles. These remain valid // across OTAs and are used to drive profile verification (post OTA) and // profile compilation (without waiting to collect a fresh set of profiles). if (mIsUpgrade && !onlyCore) { Slog.i(TAG, "Build fingerprint changed; clearing code caches"); for (inti=0; i < mSettings.mPackages.size(); i++) { finalPackageSettingps= 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, StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); } } ver.fingerprint = Build.FINGERPRINT; }
checkDefaultBrowser();
// 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 //信息写回packages.xml文件 mSettings.writeLPr();
// Perform dexopt on all apps that mark themselves as coreApps. We do this pretty // early on (before the package manager declares itself as early) because other // components in the system server might ask for package contexts for these apps. // // Note that "onlyCore" in this context means the system is encrypted or encrypting // (i.e, that the data partition is unavailable). if ((isFirstBoot() || isUpgrade() || VMRuntime.didPruneDalvikCache()) && !onlyCore) { longstart= System.nanoTime(); List<PackageParser.Package> coreApps = newArrayList<>(); for (PackageParser.Package pkg : mPackages.values()) { if (pkg.coreApp) { coreApps.add(pkg); } }
// 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();
// 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);
// Expose private service for system components to use. LocalServices.addService(PackageManagerInternal.class, newPackageManagerInternalImpl());
// Disable any carrier apps. We do this very early in boot to prevent the apps from being // disabled after already being started. CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this, mContext.getContentResolver(), UserHandle.USER_SYSTEM);
// Read the compatibilty setting when the system is ready. booleancompatibilityModeEnabled= android.provider.Settings.Global.getInt( mContext.getContentResolver(), android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1; PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); if (DEBUG_SETTINGS) { Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); }
int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
synchronized (mPackages) { // Verify that all of the preferred activity components actually // exist. It is possible for applications to be updated and at // that point remove a previously declared activity component that // had been set as a preferred activity. We try to clean this up // the next time we encounter that preferred activity, but it is // possible for the user flow to never be able to return to that // situation so here we do a sanity check to make sure we haven't // left any junk around. ArrayList<PreferredActivity> removed = newArrayList<PreferredActivity>(); for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { PreferredIntentResolverpir= mSettings.mPreferredActivities.valueAt(i); removed.clear(); for (PreferredActivity pa : pir.filterSet()) { if (mActivities.mActivities.get(pa.mPref.mComponent) == null) { removed.add(pa); } } if (removed.size() > 0) { for (int r=0; r<removed.size(); r++) { PreferredActivitypa= removed.get(r); Slog.w(TAG, "Removing dangling preferred activity: " + pa.mPref.mComponent); pir.removeFilter(pa); } mSettings.writePackageRestrictionsLPr( mSettings.mPreferredActivities.keyAt(i)); } }
for (int userId : UserManagerService.getInstance().getUserIds()) { if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) { grantPermissionsUserIds = ArrayUtils.appendInt( grantPermissionsUserIds, userId); } } } sUserManager.systemReady();
// If we upgraded grant all default permissions before kicking off. for (int userId : grantPermissionsUserIds) { mDefaultPermissionPolicy.grantDefaultPermissions(userId); }
// If we did not grant default permissions, we preload from this the // default permission exceptions lazily to ensure we don't hit the // disk on a new user creation. if (grantPermissionsUserIds == EMPTY_INT_ARRAY) { mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions(); }
// Kick off any messages waiting for system ready if (mPostSystemReadyMessages != null) { for (Message msg : mPostSystemReadyMessages) { msg.sendToTarget(); } mPostSystemReadyMessages = null; }
// Watch for external volumes that come and go over time finalStorageManagerstorage= mContext.getSystemService(StorageManager.class); storage.registerListener(mStorageListener);
// Now that we're mostly running, clean up stale users and apps sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL); reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
if (mPrivappPermissionsViolations != null) { Slog.wtf(TAG,"Signature|privileged permissions not in " + "privapp-permissions whitelist: " + mPrivappPermissionsViolations); mPrivappPermissionsViolations = null; } }