PackageManagerService分析之二
2017-03-12 08:49
281 查看
3, 扫描Package
第二个阶段的工作主要是扫描系统中的APK,由于需要逐个扫描apk文件,因此手机上安装的程序越多,PKM的工作量越大,系统启动速度越慢,也就是开机时间越长
3.1 系统库的dex优化
以下的代码主要是对系统库BOOTCLASSPATH指定,或platform.xml定义,或者/system/frameworks目录下的jar和apk包进行一次检查,该dex优化的优化.dex优化后会在相应的目录生成.odex文件.
这里扫描所有的/system/framework下面除framework-res以外的apk和jar包(因为framework-res只有 resource文件),
然后依次对它们做Dex优化。在上面如果有对文件做过Dex优化,就要去删除dalvi-cache下面所有的dex文件,
以防 止cache文件和现在的文件不相符。
File frameworkDir = new File(Environment.getRootDirectory(), "framework");
// Gross hack for now: we know this file doesn't contain any
// code, so don't dexopt it to avoid the resulting log spew.
alreadyDexOpted.add(frameworkDir.getPath() + "/framework-res.apk");
// Gross hack for now: we know this file is only part of
// the boot class path for art, so don't dexopt it to
// avoid the resulting log spew.
alreadyDexOpted.add(frameworkDir.getPath() + "/core-libart.jar");
/**
* There are a number of commands implemented in Java, which
* we currently need to do the dexopt on so that they can be
* run from a non-root shell.
*/
String[] frameworkFiles = frameworkDir.list();
3.2 扫描apk
调用scanDirLI去扫描文件夹/vendor/overlay
/system/priv-app /system/app
/vendor/app
File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR); scanDirLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0); // Find base frameworks (resource packages without code). scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR | PackageParser.PARSE_IS_PRIVILEGED, scanFlags | SCAN_NO_DEX, 0); // Collected privileged system packages. final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app"); scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0); // Collect ordinary system packages. final File systemAppDir = new File(Environment.getRootDirectory(), "app"); scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); // Collect all vendor packages. File vendorAppDir = new File("/vendor/app"); try { vendorAppDir = vendorAppDir.getCanonicalFile(); } catch (IOException e) { // failed to look up canonical path, continue with original one } scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); // Collect all OEM packages. final File oemAppDir = new File(Environment.getOemDirectory(), "app"); scanDirLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); // Collect all Regionalization packages form Carrier's res packages. if (RegionalizationEnvironment.isSupported()) { Log.d(TAG, "Load Regionalization vendor apks"); final List<File> RegionalizationDirs = RegionalizationEnvironment.getAllPackageDirectories(); for (File f : RegionalizationDirs) { File RegionalizationSystemDir = new File(f, "system"); // Collect packages in <Package>/system/priv-app scanDirLI(new File(RegionalizationSystemDir, "priv-app"), PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0); // Collect packages in <Package>/system/app scanDirLI(new File(RegionalizationSystemDir, "app"), PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); // Collect overlay in <Package>/system/vendor scanDirLI(new File(RegionalizationSystemDir, "vendor/overlay"), PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0); } }
3.2.1 parsePackage
scanPackageLI首先调用PackageParser的parsePackage去解析扫描的文件,注意这里有两个parsePackage函数,但它们的参数不同. 流程图如下,
PackageParser pp = new PackageParser(); pp.setSeparateProcesses(mSeparateProcesses); pp.setOnlyCoreApps(mOnlyCore); pp.setDisplayMetrics(mMetrics); if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) { parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY; } final PackageParser.Package pkg; try { pkg = pp.parsePackage(scanFile, parseFlags); } catch (PackageParserException e) { throw PackageManagerException.from(e); }
parseBaseApk方法虽然很长,但是逻辑很简单,解析apk的AndroidManifest文件,
int outerDepth = parser.getDepth(); while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { continue; } String tagName = parser.getName(); if (tagName.equals("application")) { if (foundApp) { if (RIGID_PARSER) { outError[0] = "<manifest> has more than one <application>"; mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED; return null; } else { Slog.w(TAG, "<manifest> has more than one <application>"); XmlUtils.skipCurrentTag(parser); continue; } } foundApp = true; if (!parseBaseApplication(pkg, res, parser, attrs, flags, outError)) { return null; } } else if (tagName.equals("overlay")) { pkg.mTrustedOverlay = trustedOverlay; sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.AndroidManifestResourceOverlay); pkg.mOverlayTarget = sa.getString( com.android.internal.R.styleable.AndroidManifestResourceOverlay_targetPackage); pkg.mOverlayPriority = sa.getInt( com.android.internal.R.styleable.AndroidManifestResourceOverlay_priority, -1); sa.recycle(); if (pkg.mOverlayTarget == null) { outError[0] = "<overlay> does not specify a target package"; mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED; return null; } if (pkg.mOverlayPriority < 0 || pkg.mOverlayPriority > 9999) { outError[0] = "<overlay> priority must be between 0 and 9999"; mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED; return null; } XmlUtils.skipCurrentTag(parser); } else if (tagName.equals("key-sets")) { if (!parseKeySets(pkg, res, parser, attrs, outError)) { return null; } } else if (tagName.equals("permission-group")) { if (parsePermissionGroup(pkg, flags, res, parser, attrs, outError) == null) { return null; } } else if (tagName.equals("permission")) { if (parsePermission(pkg, res, parser, attrs, outError) == null) { return null; } } else if (tagName.equals("permission-tree")) { if (parsePermissionTree(pkg, res, parser, attrs, outError) == null) { return null; } } else if (tagName.equals("uses-permission")) { if (!parseUsesPermission(pkg, res, parser, attrs)) { return null; } } else if (tagName.equals("uses-permission-sdk-m") || tagName.equals("uses-permission-sdk-23")) { if (!parseUsesPermission(pkg, res, parser, attrs)) { return null; } } •••
parseBaseApplication方法会解析Application中的内容,包括四大组件,并且receiver被当成activity来解析
int type; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) { if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { continue; } String tagName = parser.getName(); if (tagName.equals("activity")) { Activity a = parseActivity(owner, res, parser, attrs, flags, outError, false, owner.baseHardwareAccelerated); if (a == null) { mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED; return false; } owner.activities.add(a); } else if (tagName.equals("receiver")) { Activity a = parseActivity(owner, res, parser, attrs, flags, outError, true, false); if (a == null) { mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED; return false; } owner.receivers.add(a); } else if (tagName.equals("service")) { Service s = parseService(owner, res, parser, attrs, flags, outError); if (s == null) { mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED; return false; } owner.services.add(s); } else if (tagName.equals("provider")) { Provider p = parseProvider(owner, res, parser, attrs, flags, outError); if (p == null) { mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED; return false; } owner.providers.add(p); } else if (tagName.equals("activity-alias")) { Activity a = parseActivityAlias(owner, res, parser, attrs, flags, outError); if (a == null) { mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED; return false; } owner.activities.add(a); } •••
最后解析的相关参数的都存放在PackageParser的内部类Package的数组中,
public final ApplicationInfo applicationInfo = new ApplicationInfo(); public final ArrayList<Permission> permissions = new ArrayList<Permission>(0); public final ArrayList<PermissionGroup> permissionGroups = new ArrayList<PermissionGroup>(0); public final ArrayList<Activity> activities = new ArrayList<Activity>(0); public final ArrayList<Activity> receivers = new ArrayList<Activity>(0); public final ArrayList<Provider> providers = new ArrayList<Provider>(0); public final ArrayList<Service> services = new ArrayList<Service>(0); public final ArrayList<Instrumentation> instrumentation = new ArrayList<Instrumentation>(0);
3.2.2 scanPackageLI
scanPackageLI调用流程图如下,scanPackageDirtyLI会取出PackageParser四大组件,然后分别调用其内部类完成添加到数组。
这四个内部类都继承自IntentResolver。添加activity的方法如下,
N = pkg.activities.size(); r = null; for (i=0; i<N; i++) { PackageParser.Activity a = pkg.activities.get(i); a.info.processName = fixProcessName(pkg.applicationInfo.processName, a.info.processName, pkg.applicationInfo.uid); mActivities.addActivity(a, "activity"); if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { if (r == null) { r = new StringBuilder(256); } else { r.append(' '); } r.append(a.info.name); } }
ActivityIntentResolver的addActivity方法如下,
public final void addActivity(PackageParser.Activity a, String type) { final boolean systemApp = a.info.applicationInfo.isSystemApp(); mActivities.put(a.getComponentName(), a); if (DEBUG_SHOW_INFO) Log.v( TAG, " " + type + " " + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":"); if (DEBUG_SHOW_INFO) Log.v(TAG, " Class=" + a.info.name); final int NI = a.intents.size(); for (int j=0; j<NI; j++) { PackageParser.ActivityIntentInfo intent = a.intents.get(j); if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) { intent.setPriority(0); Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity " + a.className + " with priority > 0, forcing to 0"); } if (DEBUG_SHOW_INFO) { Log.v(TAG, " IntentFilter:"); intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); } if (!intent.debugCheck()) { Log.w(TAG, "==> For Activity " + a.info.name); } addFilter(intent); } }
addFilter方法以后启动activity的时候再详细论述。
4, 扫描Package
PMS将前面收集的信息再整理一次,将已安装的apk信息写到package.xml、pacakage.list和package-stopped.xml中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. if (!onlyCore && (mPromoteSystemApps || !mRestoredSettings)) { for (UserInfo user : sUserManager.getUsers(true)) { mSettings.applyDefaultPreferredAppsLPw(this, user.id); applyFactoryDefaultBrowserLPw(user.id); primeDomainVerificationsLPw(user.id); } } // 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(); // 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 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);
packages.xml:系统对程序安装,卸载和更新等操作时会更新该文件,PMS扫描完目标文件夹后创建该文件,保存了Package相关的信息。
packages.list:保存着系统中所有的非系统自带的APK信息,程序安装,卸载和更新会更新该文件。
packages-stoped.xml:保存系统中被用户强制停止的Package的信息。
相关文章推荐
- Android源码之“应用程序界面“分析二(PackageManager和PackageManagerService)
- PackageManagerService的启动过程分析
- android包管理服务(PackageManagerService)源码分析
- Android PackageManagerService分析三:卸载APK
- Android PackageManagerService详细分析
- Android PackageManagerService详细分析
- Android PackageManagerService详细分析
- Android PackageManagerService详细分析
- Android Framework 之PackageManagerService详细分析
- Android PackageManagerService详细分析
- Android PackageManagerService启动流程分析
- Android PackageManagerService详细分析
- Android服务之PackageManagerService启动源码分析
- Android的软件包管理服务PackageManagerService源码分析
- Android PackageManagerService详细分析 .
- PackageManagerService 分析及执行流程
- Android L-preview PackageManagerService启动、安装和卸载分析