// 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); //记录AndroidManifest文件的android:isStatic为true的package mParallelPackageParserCallback.findStaticOverlayPackages();
// Find base frameworks (resource packages without code). scanDirTracedLI(frameworkDir, mDefParseFlags | PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR | PackageParser.PARSE_IS_PRIVILEGED, scanFlags | SCAN_NO_DEX, 0);
privatevoidscanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) { final File[] files = dir.listFiles(); if (ArrayUtils.isEmpty(files)) { Log.d(TAG, "No files in app dir " + dir); return; }
if (DEBUG_PACKAGE_SCANNING) { Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags + " flags=0x" + Integer.toHexString(parseFlags)); } ParallelPackageParserparallelPackageParser=newParallelPackageParser( mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir, mParallelPackageParserCallback);
// Submit files for parsing in parallel intfileCount=0; for (File file : files) { finalbooleanisPackage= (isApkFile(file) || file.isDirectory()) && !PackageInstallerService.isStageName(file.getName()); if (!isPackage) { // Ignore entries which are not packages continue; } parallelPackageParser.submit(file, parseFlags); fileCount++; }
// Process results one by one for (; fileCount > 0; fileCount--) { ParallelPackageParser.ParseResultparseResult= parallelPackageParser.take(); Throwablethrowable= parseResult.throwable; interrorCode= PackageManager.INSTALL_SUCCEEDED;
private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile, finalint policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user) throws PackageManagerException { // If the package has children and this is the first dive in the function // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all // packages (parent and children) would be successfully scanned before the // actual scan since scanning mutates internal state and we want to atomically // install the package and its children. if ((scanFlags & SCAN_CHECK_ONLY) == 0) { if (pkg.childPackages != null && pkg.childPackages.size() > 0) { scanFlags |= SCAN_CHECK_ONLY; } } else { scanFlags &= ~SCAN_CHECK_ONLY; }
/** * Applies policy to the parsed package based upon the given policy flags. * Ensures the package is in a good state. * <p> * Implementation detail: This method must NOT have any side effect. It would * ideally be static, but, it requires locks to read system state. */ privatevoidapplyPolicy(PackageParser.Package pkg, int policyFlags) { if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; if (pkg.applicationInfo.isDirectBootAware()) {//加密时不输入密码即可访问 // we're direct boot aware; set for all components for (PackageParser.Service s : pkg.services) { s.info.encryptionAware = s.info.directBootAware = true; } for (PackageParser.Provider p : pkg.providers) { p.info.encryptionAware = p.info.directBootAware = true; } for (PackageParser.Activity a : pkg.activities) { a.info.encryptionAware = a.info.directBootAware = true; } for (PackageParser.Activity r : pkg.receivers) { r.info.encryptionAware = r.info.directBootAware = true; } } if (compressedFileExists(pkg.codePath)) { pkg.isStub = true; } } else { // Only allow system apps to be flagged as core apps. pkg.coreApp = false;//也就是说不是systemapp设置了coreApp的属性也是没用的 // clear flags not applicable to regular apps pkg.applicationInfo.privateFlags &= ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE; pkg.applicationInfo.privateFlags &= ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE; } //表示/vendor/overlay下的app pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0;
if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) { pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; }
if (!isSystemApp(pkg)) { // Only system apps can use these features. pkg.mOriginalPackages = null;//关于origin-package可以参考另一个 pkg.mRealPackage = null; pkg.mAdoptPermissions = null; } }
// Getting the package setting may have a side-effect, so if we // are only checking if scan would succeed, stash a copy of the // old setting to restore at the end. PackageSettingnonMutatedPs=null;
// We keep references to the derived CPU Abis from settings in oder to reuse // them in the case where we're not upgrading or booting for the first time. StringprimaryCpuAbiFromSettings=null; StringsecondaryCpuAbiFromSettings=null;
synchronized (mPackages) { if (pkg.mSharedUserId != null) { // SIDE EFFECTS; may potentially allocate a new shared user // 根据pkg中信息生成新的uid,不存在则创建一个 suid = mSettings.getSharedUserLPw( pkg.mSharedUserId, 0/*pkgFlags*/, 0/*pkgPrivateFlags*/, true/*create*/); }
// ……origin-package相关内容,该部分摘出去,单独了解
// See comments in nonMutatedPs declaration if ((scanFlags & SCAN_CHECK_ONLY) != 0) { PackageSettingfoundPs= mSettings.getPackageLPr(pkg.packageName); if (foundPs != null) { nonMutatedPs = newPackageSetting(foundPs); } } // 如不是第一次启动或者升级,则直接从Settings中读取ABI信息 if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) == 0) { PackageSettingfoundPs= mSettings.getPackageLPr(pkg.packageName); if (foundPs != null) { primaryCpuAbiFromSettings = foundPs.primaryCpuAbiString; secondaryCpuAbiFromSettings = foundPs.secondaryCpuAbiString; } }
String[] usesStaticLibraries = null; if (pkg.usesStaticLibraries != null) { usesStaticLibraries = newString[pkg.usesStaticLibraries.size()]; pkg.usesStaticLibraries.toArray(usesStaticLibraries); } //package的信息不存在(第一次扫描到该应用)或者uid发生改变 if (pkgSetting == null) { finalStringparentPackageName= (pkg.parentPackage != null) ? pkg.parentPackage.packageName : null; finalbooleaninstantApp= (scanFlags & SCAN_AS_INSTANT_APP) != 0; finalbooleanvirtualPreload= (scanFlags & SCAN_AS_VIRTUAL_PRELOAD) != 0; // REMOVE SharedUserSetting from method; update in a separate call pkgSetting = Settings.createNewSetting(pkg.packageName, origPackage, disabledPkgSetting, realName, suid, destCodeFile, destResourceFile, pkg.applicationInfo.nativeLibraryRootDir, pkg.applicationInfo.primaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi, pkg.mVersionCode, pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, user, true/*allowInstall*/, instantApp, virtualPreload, parentPackageName, pkg.getChildPackageNames(), UserManagerService.getInstance(), usesStaticLibraries, pkg.usesStaticLibrariesVersions); // SIDE EFFECTS; updates system state; move elsewhere if (origPackage != null) { mSettings.addRenamedPackageLPw(pkg.packageName, origPackage.name); } mSettings.addUserToSettingLPw(pkgSetting); } else { // REMOVE SharedUserSetting from method; update in a separate call. // // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi, // secondaryCpuAbi are not known at this point so we always update them // to null here, only to reset them at a later point. Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, suid, destCodeFile, pkg.applicationInfo.nativeLibraryDir, pkg.applicationInfo.primaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi, pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, pkg.getChildPackageNames(), UserManagerService.getInstance(), usesStaticLibraries, pkg.usesStaticLibrariesVersions); } // SIDE EFFECTS; persists system state to files on disk; move elsewhere // 写入信息到/data/system/users/下的文件 mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting); //更新PackageSetting信息}} // SIDE EFFECTS; modifies system state; move elsewhere if (pkgSetting.origPackage != null) { pkg.setPackageName(origPackage.name); // File a report about this. Stringmsg="New package " + pkgSetting.realName + " renamed to replace old package " + pkgSetting.name; reportSettingsProblem(Log.WARN, msg); // Make a note of it. if ((scanFlags & SCAN_CHECK_ONLY) == 0) { mTransferedPackages.add(origPackage.name); } // No longer need to retain this. pkgSetting.origPackage = null; }
// SIDE EFFECTS; modifies system state; move elsewhere if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) { // Make a note of it. mTransferedPackages.add(pkg.packageName); }
if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) { pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; }
if ((scanFlags & SCAN_BOOTING) == 0 && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { // Check all shared libraries and map to their actual file path. // We only do this here for apps not on a system dir, because those // are the only ones that can fail an install due to this. We // will take care of the system apps by updating all of their // library paths after the scan is done. Also during the initial // scan don't update any libs as we do this wholesale after all // apps are scanned to avoid dependency based scanning. updateSharedLibrariesLPr(pkg, null); }
//获取签名信息(代码细节未了解)BEGIN // Static shared libs have same package with different versions where // we internally use a synthetic package name to allow multiple versions // of the same package, therefore we need to compare signatures against // the package setting for the latest library version. PackageSettingsignatureCheckPs= pkgSetting; if (pkg.applicationInfo.isStaticSharedLibrary()) { SharedLibraryEntrylibraryEntry= getLatestSharedLibraVersionLPr(pkg); if (libraryEntry != null) { signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk); } }
if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) { if (checkUpgradeKeySetLP(signatureCheckPs, pkg)) { // We just determined the app is signed correctly, so bring // over the latest parsed certs. pkgSetting.signatures.mSignatures = pkg.mSignatures; } else { if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { thrownewPackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " + pkg.packageName + " upgrade keys do not match the " + "previously installed version"); } else { pkgSetting.signatures.mSignatures = pkg.mSignatures; Stringmsg="System package " + pkg.packageName + " signature changed; retaining data."; reportSettingsProblem(Log.WARN, msg); } } } else { try { // SIDE EFFECTS; compareSignaturesCompat() changes KeysetManagerService verifySignaturesLP(signatureCheckPs, pkg); // We just determined the app is signed correctly, so bring // over the latest parsed certs. pkgSetting.signatures.mSignatures = pkg.mSignatures; } catch (PackageManagerException e) { if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { throw e; } // The signature has changed, but this package is in the system // image... let's recover! pkgSetting.signatures.mSignatures = pkg.mSignatures; // However... if this package is part of a shared user, but it // doesn't match the signature of the shared user, let's fail. // What this means is that you can't change the signatures // associated with an overall shared user, which doesn't seem all // that unreasonable. if (signatureCheckPs.sharedUser != null) { if (compareSignatures(signatureCheckPs.sharedUser.signatures.mSignatures, pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { thrownewPackageManagerException( INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, "Signature mismatch for shared user: " + pkgSetting.sharedUser); } } // File a report about this. Stringmsg="System package " + pkg.packageName + " signature changed; retaining data."; reportSettingsProblem(Log.WARN, msg); } } //获取签名信息END //更新权限的所有者,更新mSettings中的权限信息 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) { // This package wants to adopt ownership of permissions from // another package. for (inti= pkg.mAdoptPermissions.size() - 1; i >= 0; i--) { finalStringorigName= pkg.mAdoptPermissions.get(i); finalPackageSettingorig= mSettings.getPackageLPr(origName); if (orig != null) { if (verifyPackageUpdateLPr(orig, pkg)) { Slog.i(TAG, "Adopting permissions from " + origName + " to " + pkg.packageName); // SIDE EFFECTS; updates permissions system state; move elsewhere mSettings.transferPermissionsLPw(origName, pkg.packageName); } } } } }
// Some system apps still use directory structure for native libraries // in which case we might end up not detecting abi solely based on apk // structure. Try to detect abi based on directory structure. if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() && pkg.applicationInfo.primaryCpuAbi == null) { setBundledAppAbisAndRoots(pkg, pkgSetting); setNativeLibraryPaths(pkg, mAppLib32InstallDir); } } else { // This is not a first boot or an upgrade, don't bother deriving the // ABI during the scan. Instead, trust the value that was stored in the // package setting. pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings; pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
setNativeLibraryPaths(pkg, mAppLib32InstallDir);
if (DEBUG_ABI_SELECTION) { Slog.i(TAG, "Using ABIS and native lib paths from settings : " + pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " + pkg.applicationInfo.secondaryCpuAbi); } } } else { if ((scanFlags & SCAN_MOVE) != 0) { // We haven't run dex-opt for this move (since we've moved the compiled output too) // but we already have this packages package info in the PackageSetting. We just // use that and derive the native library path based on the new codepath. pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString; pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString; }
// Set native library paths again. For moves, the path will be updated based on the // ABIs we've determined above. For non-moves, the path will be updated based on the // ABIs we determined during compilation, but the path will depend on the final // package path (after the rename away from the stage path). setNativeLibraryPaths(pkg, mAppLib32InstallDir); }
// This is a special case for the "system" package, where the ABI is // dictated by the zygote configuration (and init.rc). We should keep track // of this ABI so that we can deal with "normal" applications that run under // the same UID correctly. if (mPlatformPackage == pkg) { pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ? Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; }
// If there's a mismatch between the abi-override in the package setting // and the abiOverride specified for the install. Warn about this because we // would've already compiled the app without taking the package setting into // account. if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) { if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) { Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride + " for package " + pkg.packageName); } }
// Copy the derived override back to the parsed package, so that we can // update the package settings accordingly. pkg.cpuAbiOverride = cpuAbiOverride;
if (DEBUG_ABI_SELECTION) { Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa=" + pkg.applicationInfo.nativeLibraryRootRequiresIsa); }
// Push the derived path down into PackageSettings so we know what to // clean up at uninstall time. pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
// SIDE EFFECTS; removes DEX files from disk; move elsewhere if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) { // We don't do this here during boot because we can do it all // at once after scanning all existing packages. // // We also do this *before* we perform dexopt on this package, so that // we can avoid redundant dexopts, and also to make sure we've got the // code and package path correct. adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg); }
if (mFactoryTest && pkg.requestedPermissions.contains( android.Manifest.permission.FACTORY_TEST)) { pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST; }
if (isSystemApp(pkg)) { pkgSetting.isOrphaned = true; }
// Take care of first install / last update times. finallongscanFileTime= getLastModifiedTime(pkg, scanFile); if (currentTime != 0) { if (pkgSetting.firstInstallTime == 0) { pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime; } elseif ((scanFlags & SCAN_UPDATE_TIME) != 0) { pkgSetting.lastUpdateTime = currentTime; } } elseif (pkgSetting.firstInstallTime == 0) { // We need *something*. Take time time stamp of the file. pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime; } elseif ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) { if (scanFileTime != pkgSetting.timeStamp) { // A package on the system image has changed; consider this // to be an update. pkgSetting.lastUpdateTime = scanFileTime; } } pkgSetting.setTimeStamp(scanFileTime);
设置第一次安装时间/上次更新时间,以及时间戳。
提交Package信息到Settings中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
if ((scanFlags & SCAN_CHECK_ONLY) != 0) { if (nonMutatedPs != null) {//仅用于检测扫描是否能成功 synchronized (mPackages) { mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs); } } } else { finalintuserId= user == null ? 0 : user.getIdentifier(); // Modify state for the given package setting commitPackageSettings(pkg, pkgSetting, user, scanFlags, (policyFlags & PackageParser.PARSE_CHATTY) != 0/*chatty*/); if (pkgSetting.getInstantApp(userId)) {//Instant app以后专门了解下 mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId); } }
/** * Adds a scanned package to the system. When this method is finished, the package will * be available for query, resolution, etc... */ privatevoidcommitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting, UserHandle user, int scanFlags, boolean chatty)throws PackageManagerException { finalStringpkgName= pkg.packageName; //自定义的ResolverActivity,可以在xml资源中配置 if (mCustomResolverComponentName != null && mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) { setUpCustomResolverActivity(pkg); }
// Any app can add new static shared libraries if (pkg.staticSharedLibName != null) { // Static shared libs don't allow renaming as they have synthetic package // names to allow install of multiple versions, so use name from manifest. if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName, pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC, pkg.manifestPackageName, pkg.mVersionCode)) { hasStaticSharedLibs = true; } else { Slog.w(TAG, "Package " + pkg.packageName + " library " + pkg.staticSharedLibName + " already exists; skipping"); } // Static shared libs cannot be updated once installed since they // use synthetic package name which includes the version code, so // not need to update other packages's shared lib dependencies. }
if (!hasStaticSharedLibs && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { // Only system apps can add new dynamic shared libraries. if (pkg.libraryNames != null) { for (inti=0; i < pkg.libraryNames.size(); i++) { Stringname= pkg.libraryNames.get(i); booleanallowed=false; if (pkg.isUpdatedSystemApp()) { // New library entries can only be added through the // system image. This is important to get rid of a lot // of nasty edge cases: for example if we allowed a non- // system update of the app to add a library, then uninstalling // the update would make the library go away, and assumptions // we made such as through app install filtering would now // have allowed apps on the device which aren't compatible // with it. Better to just have the restriction here, be // conservative, and create many fewer cases that can negatively // impact the user experience. finalPackageSettingsysPs= mSettings .getDisabledSystemPkgLPr(pkg.packageName); if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) { for (intj=0; j < sysPs.pkg.libraryNames.size(); j++) { if (name.equals(sysPs.pkg.libraryNames.get(j))) { allowed = true; break; } } } } else { allowed = true; } if (allowed) { if (!addSharedLibraryLPw(null, pkg.packageName, name, SharedLibraryInfo.VERSION_UNDEFINED, SharedLibraryInfo.TYPE_DYNAMIC, pkg.packageName, pkg.mVersionCode)) { Slog.w(TAG, "Package " + pkg.packageName + " library " + name + " already exists; skipping"); } } else { Slog.w(TAG, "Package " + pkg.packageName + " declares lib " + name + " that is not declared on system image; skipping"); } }
if ((scanFlags & SCAN_BOOTING) == 0) { // If we are not booting, we need to update any applications // that are clients of our shared library. If we are booting, // this will all be done once the scan is complete. clientLibPkgs = updateAllSharedLibrariesLPw(pkg); } } } }
if ((scanFlags & SCAN_BOOTING) != 0) { // No apps can run during boot scan, so they don't need to be frozen } elseif ((scanFlags & SCAN_DONT_KILL_APP) != 0) { // Caller asked to not kill app, so it's probably not frozen } elseif ((scanFlags & SCAN_IGNORE_FROZEN) != 0) { // Caller asked us to ignore frozen check for some reason; they // probably didn't know the package name } else { // We're doing major surgery on this package, so it better be frozen // right now to keep it from launching checkPackageFrozen(pkgName); }
// Also need to kill any apps that are dependent on the library. if (clientLibPkgs != null) { for (int i=0; i<clientLibPkgs.size(); i++) { PackageParser.PackageclientPkg= clientLibPkgs.get(i); killApplication(clientPkg.applicationInfo.packageName, clientPkg.applicationInfo.uid, "update lib"); } }
synchronized (mPackages) { // We don't expect installation to fail beyond this point
// Add the new setting to mSettings mSettings.insertPackageSettingLPw(pkgSetting, pkg); // Add the new setting to mPackages mPackages.put(pkg.applicationInfo.packageName, pkg); // Make sure we don't accidentally delete its data. final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator(); while (iter.hasNext()) { PackageCleanItemitem= iter.next(); if (pkgName.equals(item.packageName)) { iter.remove(); } }
// Add the package's KeySets to the global KeySetManagerService KeySetManagerServiceksms= mSettings.mKeySetManagerService; ksms.addScannedPackageLPw(pkg);
intN= pkg.providers.size(); StringBuilderr=null; int i; for (i=0; i<N; i++) { PackageParser.Providerp= pkg.providers.get(i); p.info.processName = fixProcessName(pkg.applicationInfo.processName, p.info.processName); mProviders.addProvider(p); p.syncable = p.info.isSyncable; if (p.info.authority != null) { String names[] = p.info.authority.split(";"); p.info.authority = null; for (intj=0; j < names.length; j++) { if (j == 1 && p.syncable) { // We only want the first authority for a provider to possibly be // syncable, so if we already added this provider using a different // authority clear the syncable flag. We copy the provider before // changing it because the mProviders object contains a reference // to a provider that we don't want to change. // Only do this for the second authority since the resulting provider // object can be the same for all future authorities for this provider. p = newPackageParser.Provider(p); p.syncable = false; } if (!mProvidersByAuthority.containsKey(names[j])) { mProvidersByAuthority.put(names[j], p); if (p.info.authority == null) { p.info.authority = names[j]; } else { p.info.authority = p.info.authority + ";" + names[j]; } if (DEBUG_PACKAGE_SCANNING) { if (chatty) Log.d(TAG, "Registered content provider: " + names[j] + ", className = " + p.info.name + ", isSyncable = " + p.info.isSyncable); } } else { PackageParser.Providerother= mProvidersByAuthority.get(names[j]); Slog.w(TAG, "Skipping provider name " + names[j] + " (in package " + pkg.applicationInfo.packageName + "): name already used by " + ((other != null && other.getComponentName() != null) ? other.getComponentName().getPackageName() : "?")); } } } if (chatty) { if (r == null) { r = newStringBuilder(256); } else { r.append(' '); } r.append(p.info.name); } } if (r != null) { if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r); }
N = pkg.services.size(); r = null; for (i=0; i<N; i++) { PackageParser.Services= pkg.services.get(i); s.info.processName = fixProcessName(pkg.applicationInfo.processName, s.info.processName); mServices.addService(s); if (chatty) { if (r == null) { r = newStringBuilder(256); } else { r.append(' '); } r.append(s.info.name); } } if (r != null) { if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r); }
N = pkg.receivers.size(); r = null; for (i=0; i<N; i++) { PackageParser.Activitya= pkg.receivers.get(i); a.info.processName = fixProcessName(pkg.applicationInfo.processName, a.info.processName); mReceivers.addActivity(a, "receiver"); if (chatty) { if (r == null) { r = newStringBuilder(256); } else { r.append(' '); } r.append(a.info.name); } } if (r != null) { if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r); }
N = pkg.activities.size(); r = null; for (i=0; i<N; i++) { PackageParser.Activitya= pkg.activities.get(i); a.info.processName = fixProcessName(pkg.applicationInfo.processName, a.info.processName); mActivities.addActivity(a, "activity"); if (chatty) { if (r == null) { r = newStringBuilder(256); } else { r.append(' '); } r.append(a.info.name); } } if (r != null) { if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r); }
N = pkg.permissionGroups.size(); r = null; for (i=0; i<N; i++) { PackageParser.PermissionGrouppg= pkg.permissionGroups.get(i); PackageParser.PermissionGroupcur= mPermissionGroups.get(pg.info.name); finalStringcurPackageName= cur == null ? null : cur.info.packageName; // Dont allow ephemeral apps to define new permission groups. if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) { Slog.w(TAG, "Permission group " + pg.info.name + " from package " + pg.info.packageName + " ignored: instant apps cannot define new permission groups."); continue; } finalbooleanisPackageUpdate= pg.info.packageName.equals(curPackageName); if (cur == null || isPackageUpdate) { mPermissionGroups.put(pg.info.name, pg); if (chatty) { if (r == null) { r = newStringBuilder(256); } else { r.append(' '); } if (isPackageUpdate) { r.append("UPD:"); } r.append(pg.info.name); } } else { Slog.w(TAG, "Permission group " + pg.info.name + " from package " + pg.info.packageName + " ignored: original from " + cur.info.packageName); if (chatty) { if (r == null) { r = newStringBuilder(256); } else { r.append(' '); } r.append("DUP:"); r.append(pg.info.name); } } } if (r != null) { if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r); }
N = pkg.permissions.size(); r = null; for (i=0; i<N; i++) { PackageParser.Permissionp= pkg.permissions.get(i);
// Dont allow ephemeral apps to define new permissions. if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) { Slog.w(TAG, "Permission " + p.info.name + " from package " + p.info.packageName + " ignored: instant apps cannot define new permissions."); continue; }
// Assume by default that we did not install this permission into the system. p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
// Now that permission groups have a special meaning, we ignore permission // groups for legacy apps to prevent unexpected behavior. In particular, // permissions for one app being granted to someone just because they happen // to be in a group defined by another app (before this had no implications). if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) { p.group = mPermissionGroups.get(p.info.group); // Warn for a permission in an unknown group. if (DEBUG_PERMISSIONS && p.info.group != null && p.group == null) { Slog.i(TAG, "Permission " + p.info.name + " from package " + p.info.packageName + " in an unknown group " + p.info.group); } }
if (pkg.protectedBroadcasts != null) { N = pkg.protectedBroadcasts.size(); synchronized (mProtectedBroadcasts) { for (i = 0; i < N; i++) { mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i)); } } } }
Add the new setting to mSettings:mSettings.insertPackageSettingLPw(pkgSetting, pkg);
Add the new setting to mPackages: mPackages.put(pkg.applicationInfo.packageName, pkg);
往下面四个解析器中添加解析后的组件:
1 2 3 4 5 6 7 8 9 10 11 12 13
// All available activities, for your resolving pleasure. finalActivityIntentResolvermActivities= newActivityIntentResolver();
// All available receivers, for your resolving pleasure. finalActivityIntentResolvermReceivers= newActivityIntentResolver();
// All available services, for your resolving pleasure. finalServiceIntentResolvermServices=newServiceIntentResolver();
// All available providers, for your resolving pleasure. finalProviderIntentResolvermProviders=newProviderIntentResolver();
从名字上就可以看出来四大组件的解析肯定和这四个Resolver有关。组件解析过程之后再做了解。
更新权限信息;
更新mInstrumentation,Instrumentation印象中是用来调试的,暂不了解;
填充mProtectedBroadcasts:
1 2 3
// Broadcast actions that are only available to the system. @GuardedBy("mProtectedBroadcasts") final ArraySet<String> mProtectedBroadcasts = newArraySet<>();
privatevoidprepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags, boolean maybeMigrateAppData) { prepareAppDataLIF(pkg, userId, flags);
if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) { // We may have just shuffled around app data directories, so // prepare them one more time prepareAppDataLIF(pkg, userId, flags); } }
/** * Thread pool used during initialization of system server. * <p>System services can {@link #submit(Runnable)} tasks for execution during boot. * The pool will be shut down after {@link SystemService#PHASE_BOOT_COMPLETED}. * New tasks <em>should not</em> be submitted afterwards. * * @hide */