文件清单

framework\base\services\core\java\com\android\server\pm\PackageManagerService.java

PackageManagerService.rar (已经带有文字注释的文件)

下面截取部分介绍

1 PMS初始化

     public static final IPackageManager main(Context context, boolean factoryTest) {
PackageManagerService m = new PackageManagerService(context, factoryTest);
ServiceManager.addService("package", m);
return m;
}

2 构造函数

 public PackageManagerService(Context context, boolean factoryTest) {
EventLog.writeEvent(LOG_BOOT_PROGRESS_PMS_START,
SystemClock.uptimeMillis()); if (mSdkVersion <= 0) {
Log.w(TAG, "**** ro.build.version.sdk not set!");
} mContext = context;
mFactoryTest = factoryTest;
mNoDexOpt = "eng".equals(SystemProperties.get("ro.build.type"));
mMetrics = new DisplayMetrics();
mSettings = new Settings();
mSettings.addSharedUserLP("android.uid.system",
Process.SYSTEM_UID, ApplicationInfo.FLAG_SYSTEM);
mSettings.addSharedUserLP("android.uid.phone",
MULTIPLE_APPLICATION_UIDS
? RADIO_UID : FIRST_APPLICATION_UID,
ApplicationInfo.FLAG_SYSTEM); String separateProcesses = SystemProperties.get("debug.separate_processes");
if (separateProcesses != null && separateProcesses.length() > 0) {
if ("*".equals(separateProcesses)) {
mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
mSeparateProcesses = null;
Log.w(TAG, "Running with debug.separate_processes: * (ALL)");
} else {
mDefParseFlags = 0;
mSeparateProcesses = separateProcesses.split(",");
Log.w(TAG, "Running with debug.separate_processes: "
+ separateProcesses);
}
} else {
mDefParseFlags = 0;
mSeparateProcesses = null;
} Installer installer = new Installer();
// Little hacky thing to check if installd is here, to determine
// whether we are running on the simulator and thus need to take
// care of building the /data file structure ourself.
// (apparently the sim now has a working installer)
if (installer.ping() && Process.supportsProcesses()) {
mInstaller = installer;
} else {
mInstaller = null;
} WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
Display d = wm.getDefaultDisplay();
d.getMetrics(mMetrics); synchronized (mInstallLock) {
synchronized (mPackages) {
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper()); // data目录
File dataDir = Environment.getDataDirectory();
// 目录:data/data
mAppDataDir = new File(dataDir, "data");
// 目录:data/app-private
mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); if (mInstaller == null) {
// Make sure these dirs exist, when we are running in
// the simulator.
// Make a wide-open directory for random misc stuff.
File miscDir = new File(dataDir, "misc");
miscDir.mkdirs();
mAppDataDir.mkdirs();
mDrmAppPrivateInstallDir.mkdirs();
} // 读:system/etc/permissions/platform.xml 等xml文件
readPermissions(); mRestoredSettings = mSettings.readLP();
long startTime = SystemClock.uptimeMillis(); EventLog.writeEvent(LOG_BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
startTime); int scanMode = SCAN_MONITOR;
if (mNoDexOpt) {
Log.w(TAG, "Running ENG build: no pre-dexopt!");
scanMode |= SCAN_NO_DEX;
} final HashSet<String> libFiles = new HashSet<String>(); // 目录:system/framework
mFrameworkDir = new File(Environment.getRootDirectory(), "framework"); if (mInstaller != null) {
/**
* Out of paranoia, ensure that everything in the boot class
* path has been dexed.
*/
String bootClassPath = System.getProperty("java.boot.class.path");
if (bootClassPath != null) {
String[] paths = splitString(bootClassPath, ':');
for (int i=0; i<paths.length; i++) {
try {
if (dalvik.system.DexFile.isDexOptNeeded(paths[i])) {
libFiles.add(paths[i]);
// 执行 dexopt 命令
mInstaller.dexopt(paths[i], Process.SYSTEM_UID, true);
}
} catch (FileNotFoundException e) {
Log.w(TAG, "Boot class path not found: " + paths[i]);
} catch (IOException e) {
Log.w(TAG, "Exception reading boot class path: " + paths[i], e);
}
}
} else {
Log.w(TAG, "No BOOTCLASSPATH found!");
} /**
* Also ensure all external libraries have had dexopt run on them.
*/
if (mSharedLibraries.size() > 0) {
Iterator<String> libs = mSharedLibraries.values().iterator();
while (libs.hasNext()) {
String lib = libs.next();
try {
if (dalvik.system.DexFile.isDexOptNeeded(lib)) {
libFiles.add(lib);
// 执行 dexopt 命令
mInstaller.dexopt(lib, Process.SYSTEM_UID, true);
}
} catch (FileNotFoundException e) {
Log.w(TAG, "Library not found: " + lib);
} catch (IOException e) {
Log.w(TAG, "Exception reading library: " + lib, e);
}
}
} // 目录:system/framework/framework-res.apk
// Gross hack for now: we know this file doesn't contain any
// code, so don't dexopt it to avoid the resulting log spew.
libFiles.add(mFrameworkDir.getPath() + "/framework-res.apk"); /**
* And 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 = mFrameworkDir.list(); // 列出 framework目录下所有文件
if (frameworkFiles != null && mInstaller != null) {
for (int i=0; i<frameworkFiles.length; i++) {
File libPath = new File(mFrameworkDir, frameworkFiles[i]);
String path = libPath.getPath();
// Skip the file if we alrady did it.
if (libFiles.contains(path)) {
continue;
}
// Skip the file if it is not a type we want to dexopt.
if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
continue;
}
try {
if (dalvik.system.DexFile.isDexOptNeeded(path)) {
// 执行 dexopt命令 apk & jar
mInstaller.dexopt(path, Process.SYSTEM_UID, true);
}
} catch (FileNotFoundException e) {
Log.w(TAG, "Jar not found: " + path);
} catch (IOException e) {
Log.w(TAG, "Exception reading jar: " + path, e);
}
}
}
} mFrameworkInstallObserver = new AppDirObserver(
mFrameworkDir.getPath(), OBSERVER_EVENTS, true);
mFrameworkInstallObserver.startWatching();
// 扫描 system/framework 目录
scanDirLI(mFrameworkDir, PackageParser.PARSE_IS_SYSTEM,
scanMode | SCAN_NO_DEX);
mSystemAppDir = new File(Environment.getRootDirectory(), "app");
mSystemInstallObserver = new AppDirObserver(
mSystemAppDir.getPath(), OBSERVER_EVENTS, true);
mSystemInstallObserver.startWatching();
// 扫描 system/app 目录
scanDirLI(mSystemAppDir, PackageParser.PARSE_IS_SYSTEM, scanMode);
// data/app 目录
mAppInstallDir = new File(dataDir, "app");
if (mInstaller == null) {
// Make sure these dirs exist, when we are running in
// the simulator.
mAppInstallDir.mkdirs(); // scanDirLI() assumes this dir exists // 创建 data/app目录
}
// 搜索未安装完成的程序包
//look for any incomplete package installations
ArrayList<String> deletePkgsList = mSettings.getListOfIncompleteInstallPackages();
//clean up list
for(int i = 0; i < deletePkgsList.size(); i++) {
//clean up here
cleanupInstallFailedPackage(deletePkgsList.get(i)); // 清理安装失败的包
}
//delete tmp files
deleteTempPackageFiles(); EventLog.writeEvent(LOG_BOOT_PROGRESS_PMS_DATA_SCAN_START,
SystemClock.uptimeMillis());
mAppInstallObserver = new AppDirObserver(
mAppInstallDir.getPath(), OBSERVER_EVENTS, false);
mAppInstallObserver.startWatching();
// 扫描 data/app 目录
scanDirLI(mAppInstallDir, 0, scanMode); mDrmAppInstallObserver = new AppDirObserver(
mDrmAppPrivateInstallDir.getPath(), OBSERVER_EVENTS, false);
mDrmAppInstallObserver.startWatching();
// 扫描 data/app-private 目录
scanDirLI(mDrmAppPrivateInstallDir, 0, scanMode | SCAN_FORWARD_LOCKED); EventLog.writeEvent(LOG_BOOT_PROGRESS_PMS_SCAN_END,
SystemClock.uptimeMillis());
Log.i(TAG, "Time to scan packages: "
+ ((SystemClock.uptimeMillis()-startTime)/1000f)
+ " seconds"); updatePermissionsLP(); // 初始化后
mSettings.writeLP(); EventLog.writeEvent(LOG_BOOT_PROGRESS_PMS_READY,
SystemClock.uptimeMillis()); // 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();
} // synchronized (mPackages)
} // synchronized (mInstallLock)
}

2.1 readPermissions()

 void readPermissions() {
// Read permissions from .../etc/permission directory.
File libraryDir = new File(Environment.getRootDirectory(), "etc/permissions");
if (!libraryDir.exists() || !libraryDir.isDirectory()) {
Log.w(TAG, "No directory " + libraryDir + ", skipping");
return;
}
if (!libraryDir.canRead()) {
Log.w(TAG, "Directory " + libraryDir + " cannot be read");
return;
} // Iterate over the files in the directory and scan .xml files
for (File f : libraryDir.listFiles()) {
// We'll read platform.xml last
if (f.getPath().endsWith("etc/permissions/platform.xml")) {
continue;
} if (!f.getPath().endsWith(".xml")) {
Log.i(TAG, "Non-xml file " + f + " in " + libraryDir + " directory, ignoring");
continue;
}
if (!f.canRead()) {
Log.w(TAG, "Permissions library file " + f + " cannot be read");
continue;
} readPermissionsFromXml(f);
} // 目录:system/etc/permissions/platform.xml
// Read permissions from .../etc/permissions/platform.xml last so it will take precedence
final File permFile = new File(Environment.getRootDirectory(),
"etc/permissions/platform.xml");
readPermissionsFromXml(permFile);
}

2.1.1 readPermissionsFromXml

  private void readPermissionsFromXml(File permFile) {
FileReader permReader = null;
try {
permReader = new FileReader(permFile);
} catch (FileNotFoundException e) {
Log.w(TAG, "Couldn't find or open permissions file " + permFile);
return;
} try {
XmlPullParser parser = Xml.newPullParser();
parser.setInput(permReader); XmlUtils.beginDocument(parser, "permissions"); while (true) {
XmlUtils.nextElement(parser);
if (parser.getEventType() == XmlPullParser.END_DOCUMENT) {
break;
} String name = parser.getName();
if ("group".equals(name)) {
String gidStr = parser.getAttributeValue(null, "gid");
if (gidStr != null) {
int gid = Integer.parseInt(gidStr);
mGlobalGids = appendInt(mGlobalGids, gid);
} else {
Log.w(TAG, "<group> without gid at "
+ parser.getPositionDescription());
} XmlUtils.skipCurrentTag(parser);
continue;
} else if ("permission".equals(name)) {
String perm = parser.getAttributeValue(null, "name");
if (perm == null) {
Log.w(TAG, "<permission> without name at "
+ parser.getPositionDescription());
XmlUtils.skipCurrentTag(parser);
continue;
}
perm = perm.intern();
readPermission(parser, perm); } else if ("assign-permission".equals(name)) {
String perm = parser.getAttributeValue(null, "name");
if (perm == null) {
Log.w(TAG, "<assign-permission> without name at "
+ parser.getPositionDescription());
XmlUtils.skipCurrentTag(parser);
continue;
}
String uidStr = parser.getAttributeValue(null, "uid");
if (uidStr == null) {
Log.w(TAG, "<assign-permission> without uid at "
+ parser.getPositionDescription());
XmlUtils.skipCurrentTag(parser);
continue;
}
int uid = Process.getUidForName(uidStr);
if (uid < 0) {
Log.w(TAG, "<assign-permission> with unknown uid \""
+ uidStr + "\" at "
+ parser.getPositionDescription());
XmlUtils.skipCurrentTag(parser);
continue;
}
perm = perm.intern();
HashSet<String> perms = mSystemPermissions.get(uid);
if (perms == null) {
perms = new HashSet<String>();
mSystemPermissions.put(uid, perms);
}
perms.add(perm);
XmlUtils.skipCurrentTag(parser); } else if ("library".equals(name)) {
String lname = parser.getAttributeValue(null, "name");
String lfile = parser.getAttributeValue(null, "file");
if (lname == null) {
Log.w(TAG, "<library> without name at "
+ parser.getPositionDescription());
} else if (lfile == null) {
Log.w(TAG, "<library> without file at "
+ parser.getPositionDescription());
} else {
Log.i(TAG, "Got library " + lname + " in " + lfile);
this.mSharedLibraries.put(lname, lfile);
}
XmlUtils.skipCurrentTag(parser);
continue; } else {
XmlUtils.skipCurrentTag(parser);
continue;
} }
} catch (XmlPullParserException e) {
Log.w(TAG, "Got execption parsing permissions.", e);
} catch (IOException e) {
Log.w(TAG, "Got execption parsing permissions.", e);
}
}

2.2 mSettings.readLP()

 boolean readLP() {
FileInputStream str = null;
// 如果 data/system/packages-backup.xml 文件存在,则继续
if (mBackupSettingsFilename.exists()) {
try {
//文件:data/system/packages-backup.xml
str = new FileInputStream(mBackupSettingsFilename);
mReadMessages.append("Reading from backup settings file\n");
Log.i(TAG, "Reading from backup settings file!");
} catch (java.io.IOException e) {
// We'll try for the normal settings file.
}
} // 清除 mPastSignatures 列表
mPastSignatures.clear(); try {
// 如果 "data/system/packages-backup.xml" 文件不存在
if (str == null) {
// 如果 data/system/packages.xml 也不存在
if (!mSettingsFilename.exists()) {
mReadMessages.append("No settings file found\n");
Log.i(TAG, "No current settings file!");
return false; // 直接返回了
}
// 如果存在,则创建 data/system/packages.xml 文件流
str = new FileInputStream(mSettingsFilename);
}
//若packages-backup.xml存在,则解析,否则 解析 packages.xml 文件
XmlPullParser parser = Xml.newPullParser();
parser.setInput(str, null); int type;
while ((type=parser.next()) != XmlPullParser.START_TAG
&& type != XmlPullParser.END_DOCUMENT) {
;
} if (type != XmlPullParser.START_TAG) {
mReadMessages.append("No start tag found in settings file\n");
Log.e(TAG, "No start tag found in package manager settings");
return false;
} 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();
// 解析 packages.xml 文件中的 "package"
if (tagName.equals("package")) {
readPackageLP(parser); //解析 package 标签
} else if (tagName.equals("permissions")) { //解析 permissions 标签
readPermissionsLP(mPermissions, parser);
} else if (tagName.equals("permission-trees")) {
readPermissionsLP(mPermissionTrees, parser);
} else if (tagName.equals("shared-user")) { // 解析 shared-user 标签
readSharedUserLP(parser);
} else if (tagName.equals("preferred-packages")) {
readPreferredPackagesLP(parser);
} else if (tagName.equals("preferred-activities")) {
readPreferredActivitiesLP(parser);
} else if(tagName.equals("updated-package")) { //解析 updated-package 标签
readDisabledSysPackageLP(parser);
} else {
Log.w(TAG, "Unknown element under <packages>: "
+ parser.getName());
XmlUtils.skipCurrentTag(parser);
}
} str.close(); } catch(XmlPullParserException e) {
mReadMessages.append("Error reading: " + e.toString());
Log.e(TAG, "Error reading package manager settings", e); } catch(java.io.IOException e) {
mReadMessages.append("Error reading: " + e.toString());
Log.e(TAG, "Error reading package manager settings", e); } int N = mPendingPackages.size();
for (int i=0; i<N; i++) {
final PendingPackage pp = mPendingPackages.get(i);
Object idObj = getUserIdLP(pp.sharedId);
if (idObj != null && idObj instanceof SharedUserSetting) {
PackageSetting p = getPackageLP(pp.name,
(SharedUserSetting)idObj, pp.codePath, pp.resourcePath,
pp.versionCode, pp.pkgFlags, true, true);
if (p == null) {
Log.w(TAG, "Unable to create application package for "
+ pp.name);
continue;
}
p.copyFrom(pp);
} else if (idObj != null) {
String msg = "Bad package setting: package " + pp.name
+ " has shared uid " + pp.sharedId
+ " that is not a shared uid\n";
mReadMessages.append(msg);
Log.e(TAG, msg);
} else {
String msg = "Bad package setting: package " + pp.name
+ " has shared uid " + pp.sharedId
+ " that is not defined\n";
mReadMessages.append(msg);
Log.e(TAG, msg);
}
}
mPendingPackages.clear(); N = mPendingPreferredPackages.size();
mPreferredPackages.clear();
for (int i=0; i<N; i++) {
final String name = mPendingPreferredPackages.get(i);
final PackageSetting p = mPackages.get(name);
if (p != null) {
mPreferredPackages.add(p);
} else {
Log.w(TAG, "Unknown preferred package: " + name);
}
}
mPendingPreferredPackages.clear(); mReadMessages.append("Read completed successfully: "
+ mPackages.size() + " packages, "
+ mSharedUsers.size() + " shared uids\n"); return true;
}

2.2.1 readPackageLP

 // 解析 data/system/packages.xml 文件中的 "package"标签
private void readPackageLP(XmlPullParser parser)
throws XmlPullParserException, IOException {
String name = null;
String idStr = null;
String sharedIdStr = null;
String codePathStr = null;
String resourcePathStr = null;
String systemStr = null;
String installerPackageName = null;
int pkgFlags = 0;
String timeStampStr;
long timeStamp = 0;
PackageSettingBase packageSetting = null;
String version = null;
int versionCode = 0;
try {
// name:包名
name = parser.getAttributeValue(null, "name");
idStr = parser.getAttributeValue(null, "userId");
sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
codePathStr = parser.getAttributeValue(null, "codePath");
resourcePathStr = parser.getAttributeValue(null, "resourcePath");
version = parser.getAttributeValue(null, "version");
if (version != null) {
try {
versionCode = Integer.parseInt(version);
} catch (NumberFormatException e) {
}
}
systemStr = parser.getAttributeValue(null, "system");
// installer的值: com.google.android.packageinstaller or com.android.vending etc.
installerPackageName = parser.getAttributeValue(null, "installer");
if (systemStr != null) {
if ("true".equals(systemStr)) {
pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
}
} else {
// Old settings that don't specify system... just treat
// them as system, good enough.
pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
}
timeStampStr = parser.getAttributeValue(null, "ts"); // 解析时间戳
if (timeStampStr != null) {
try {
timeStamp = Long.parseLong(timeStampStr);
} catch (NumberFormatException e) {
}
}
if (DEBUG_SETTINGS) Log.v(TAG, "Reading package: " + name
+ " userId=" + idStr + " sharedUserId=" + sharedIdStr);
int userId = idStr != null ? Integer.parseInt(idStr) : 0;
if (resourcePathStr == null) {
// 若没有 resourcePath 属性,则赋值为 codePath 属性的值
resourcePathStr = codePathStr;
}
if (name == null) { // 没有包名
reportSettingsProblem(Log.WARN,
"Error in package manager settings: <package> has no name at "
+ parser.getPositionDescription());
} else if (codePathStr == null) { // 没有 codePath 属性值
reportSettingsProblem(Log.WARN,
"Error in package manager settings: <package> has no codePath at "
+ parser.getPositionDescription());
} else if (userId > 0) {
// 有包名、有codePathStr的值,且userId大于0
// 根据上述解析的信息,创建 PackageSettingBase 对象
packageSetting = addPackageLP(name.intern(), new File(codePathStr),
new File(resourcePathStr), userId, versionCode, pkgFlags);
if (DEBUG_SETTINGS) Log.i(TAG, "Reading package " + name
+ ": userId=" + userId + " pkg=" + packageSetting);
if (packageSetting == null) {
reportSettingsProblem(Log.ERROR,
"Failure adding uid " + userId
+ " while parsing settings at "
+ parser.getPositionDescription());
} else {
// 设置时间戳
packageSetting.setTimeStamp(timeStamp, timeStampStr);
}
} else if (sharedIdStr != null) { // 存在 sharedUserId 的值
// 将 sharedUserId 的值赋值给 userId
userId = sharedIdStr != null
? Integer.parseInt(sharedIdStr) : 0;
if (userId > 0) {
// 存在 sharedUserId的值 ,且 sharedUserId 大于0,创建 PendingPackage 对象
packageSetting = new PendingPackage(name.intern(), new File(codePathStr),
new File(resourcePathStr), userId, versionCode, pkgFlags);
packageSetting.setTimeStamp(timeStamp, timeStampStr);
// mPendingPackages 装入的是 存在 sharedUserId 值的 package 标签
mPendingPackages.add((PendingPackage) packageSetting);
if (DEBUG_SETTINGS) Log.i(TAG, "Reading package " + name
+ ": sharedUserId=" + userId + " pkg="
+ packageSetting);
} else { // sharedUserId 小于0,报告错误
reportSettingsProblem(Log.WARN,
"Error in package manager settings: package "
+ name + " has bad sharedId " + sharedIdStr
+ " at " + parser.getPositionDescription());
}
} else { // userId 的值不符合,报告错误
reportSettingsProblem(Log.WARN,
"Error in package manager settings: package "
+ name + " has bad userId " + idStr + " at "
+ parser.getPositionDescription());
}
} catch (NumberFormatException e) {
reportSettingsProblem(Log.WARN,
"Error in package manager settings: package "
+ name + " has bad userId " + idStr + " at "
+ parser.getPositionDescription());
}
if (packageSetting != null) { // 针对存在userId 或 sharedUserId 属性的 package标签
packageSetting.installerPackageName = installerPackageName;
final String enabledStr = parser.getAttributeValue(null, "enabled");
if (enabledStr != null) { // 有 enabled 属性值
if (enabledStr.equalsIgnoreCase("true")) {
packageSetting.enabled = COMPONENT_ENABLED_STATE_ENABLED;
} else if (enabledStr.equalsIgnoreCase("false")) {
packageSetting.enabled = COMPONENT_ENABLED_STATE_DISABLED;
} else if (enabledStr.equalsIgnoreCase("default")) {
packageSetting.enabled = COMPONENT_ENABLED_STATE_DEFAULT;
} else {
reportSettingsProblem(Log.WARN,
"Error in package manager settings: package "
+ name + " has bad enabled value: " + idStr
+ " at " + parser.getPositionDescription());
}
} else { // 无 enabled 属性
packageSetting.enabled = COMPONENT_ENABLED_STATE_DEFAULT;
}
final String installStatusStr = parser.getAttributeValue(null, "installStatus");
if (installStatusStr != null) { // 有 installStatus 属性值
if (installStatusStr.equalsIgnoreCase("false")) {
packageSetting.installStatus = PKG_INSTALL_INCOMPLETE;
} else {
packageSetting.installStatus = PKG_INSTALL_COMPLETE;
}
} int outerDepth = parser.getDepth();
int type;
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();
// 解析 package 标签下 的子标签
if (tagName.equals("disabled-components")) { // 解析子标签 disabled-components
readDisabledComponentsLP(packageSetting, parser);
} else if (tagName.equals("enabled-components")) {
readEnabledComponentsLP(packageSetting, parser); // 解析子标签 enabled-components
} else if (tagName.equals("sigs")) { // 解析子标签 sigs
packageSetting.signatures.readXml(parser, mPastSignatures);
} else if (tagName.equals("perms")) { // 解析子标签 perms
// 把解析的"权限名称"装入 packageSetting.loadedPermissions 集合中
readGrantedPermissionsLP(parser,
packageSetting.loadedPermissions);
packageSetting.permissionsFixed = true;
} else { // 报告错误
reportSettingsProblem(Log.WARN,
"Unknown element under <package>: "
+ parser.getName());
XmlUtils.skipCurrentTag(parser);
}
}
} else {
XmlUtils.skipCurrentTag(parser);
}
}

2.2.1.1 readDisabledComponentsLP

         // 解析"data/system/package.xml"文件中的 package 标签下的子标签 "disabled-components"
private void readDisabledComponentsLP(PackageSettingBase packageSetting,
XmlPullParser parser)
throws IOException, XmlPullParserException {
int outerDepth = parser.getDepth();
int type;
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("item")) { // 解析子标签"item"
// 获取name属性值
String name = parser.getAttributeValue(null, "name");
if (name != null) {
// 装入到 disabledComponents 集合中
packageSetting.disabledComponents.add(name.intern());
} else {
reportSettingsProblem(Log.WARN,
"Error in package manager settings: <disabled-components> has"
+ " no name at " + parser.getPositionDescription());
}
} else {
reportSettingsProblem(Log.WARN,
"Unknown element under <disabled-components>: "
+ parser.getName());
}
XmlUtils.skipCurrentTag(parser);
}
}

2.2.1.2 readEnabledComponentsLP

         // 解析"data/system/package.xml"文件中的 package 标签下的子标签 "enabled-components"
private void readEnabledComponentsLP(PackageSettingBase packageSetting,
XmlPullParser parser)
throws IOException, XmlPullParserException {
int outerDepth = parser.getDepth();
int type;
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("item")) {
String name = parser.getAttributeValue(null, "name");
if (name != null) {
packageSetting.enabledComponents.add(name.intern());
} else {
reportSettingsProblem(Log.WARN,
"Error in package manager settings: <enabled-components> has"
+ " no name at " + parser.getPositionDescription());
}
} else {
reportSettingsProblem(Log.WARN,
"Unknown element under <enabled-components>: "
+ parser.getName());
}
XmlUtils.skipCurrentTag(parser);
}
}

2.2.1.3 readGrantedPermissionsLP

         // 解析标签 "perms"的值
private void readGrantedPermissionsLP(XmlPullParser parser,
HashSet<String> outPerms) throws IOException, XmlPullParserException {
int outerDepth = parser.getDepth();
int type;
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("item")) { // 解析子标签 item
// name:权限名称
String name = parser.getAttributeValue(null, "name");
if (name != null) {
// 解析"权限名称"后装入 outPerms 中
outPerms.add(name.intern());
} else {
reportSettingsProblem(Log.WARN,
"Error in package manager settings: <perms> has"
+ " no name at " + parser.getPositionDescription());
}
} else {
reportSettingsProblem(Log.WARN,
"Unknown element under <perms>: "
+ parser.getName());
}
XmlUtils.skipCurrentTag(parser);
}
}

2.2.2 readPermissionsLP

 // 解析 data/system/packages.xml 文件中的  permissions 标签和 permission-trees 标签
private void readPermissionsLP(HashMap<String, BasePermission> out,
XmlPullParser parser)
throws IOException, XmlPullParserException {
int outerDepth = parser.getDepth();
int type;
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("item")) {
String name = parser.getAttributeValue(null, "name");
String sourcePackage = parser.getAttributeValue(null, "package");
String ptype = parser.getAttributeValue(null, "type");
if (name != null && sourcePackage != null) {
boolean dynamic = "dynamic".equals(ptype);
BasePermission bp = new BasePermission(name, sourcePackage,
dynamic
? BasePermission.TYPE_DYNAMIC
: BasePermission.TYPE_NORMAL);
if (dynamic) {
PermissionInfo pi = new PermissionInfo();
pi.packageName = sourcePackage.intern();
pi.name = name.intern();
pi.icon = readInt(parser, null, "icon", 0);
pi.nonLocalizedLabel = parser.getAttributeValue(
null, "label");
pi.protectionLevel = readInt(parser, null, "protection",
PermissionInfo.PROTECTION_NORMAL);
bp.pendingInfo = pi;
}
out.put(bp.name, bp);
} else {
reportSettingsProblem(Log.WARN,
"Error in package manager settings: permissions has"
+ " no name at " + parser.getPositionDescription());
}
} else {
reportSettingsProblem(Log.WARN,
"Unknown element reading permissions: "
+ parser.getName() + " at "
+ parser.getPositionDescription());
}
XmlUtils.skipCurrentTag(parser);
}
}

2.2.3 readSharedUserLP

 // 解析"data/system/package.xml"文件中的 shared-user 标签
private void readSharedUserLP(XmlPullParser parser)
throws XmlPullParserException, IOException {
String name = null;
String idStr = null;
int pkgFlags = 0;
SharedUserSetting su = null;
try {
name = parser.getAttributeValue(null, "name");// 解析name属性值
idStr = parser.getAttributeValue(null, "userId");// 解析 userId 属性值
int userId = idStr != null ? Integer.parseInt(idStr) : 0;
if ("true".equals(parser.getAttributeValue(null, "system"))) {
pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
}
if (name == null) {
reportSettingsProblem(Log.WARN,
"Error in package manager settings: <shared-user> has no name at "
+ parser.getPositionDescription());
} else if (userId == 0) {
reportSettingsProblem(Log.WARN,
"Error in package manager settings: shared-user "
+ name + " has bad userId " + idStr + " at "
+ parser.getPositionDescription());
} else {
if ((su=addSharedUserLP(name.intern(), userId, pkgFlags)) == null) {
reportSettingsProblem(Log.ERROR,
"Occurred while parsing settings at "
+ parser.getPositionDescription());
}
}
} catch (NumberFormatException e) {
reportSettingsProblem(Log.WARN,
"Error in package manager settings: package "
+ name + " has bad userId " + idStr + " at "
+ parser.getPositionDescription());
}; if (su != null) {
int outerDepth = parser.getDepth();
int type;
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("sigs")) { // 解析 sigs 子标签
su.signatures.readXml(parser, mPastSignatures);
} else if (tagName.equals("perms")) { // 解析 perms 标签
readGrantedPermissionsLP(parser, su.loadedPermissions);
} else {
reportSettingsProblem(Log.WARN,
"Unknown element under <shared-user>: "
+ parser.getName());
XmlUtils.skipCurrentTag(parser);
}
} } else {
XmlUtils.skipCurrentTag(parser);
}
}

2.2.4 readDisabledSysPackageLP

 // 解析 packages.xml 文件中的 updated-package 标签值
private void readDisabledSysPackageLP(XmlPullParser parser)
throws XmlPullParserException, IOException {
String name = parser.getAttributeValue(null, "name");
String codePathStr = parser.getAttributeValue(null, "codePath");
String resourcePathStr = parser.getAttributeValue(null, "resourcePath");
// 如果 resourcePathStr 没有值
if(resourcePathStr == null) {
// 则赋值为 codePath的值
resourcePathStr = codePathStr;
}
String version = parser.getAttributeValue(null, "version");
int versionCode = 0;
// 如果有 version 的值
if (version != null) {
try {
// 则解析version的值
versionCode = Integer.parseInt(version);
} catch (NumberFormatException e) {
}
} int pkgFlags = 0;
pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
// 根据上述 解析的信息,创建 PackageSetting 对象
// name:包名
// codePathStr:com.google.android.gms
PackageSetting ps = new PackageSetting(name,
new File(codePathStr),
new File(resourcePathStr), versionCode, pkgFlags);
String timeStampStr = parser.getAttributeValue(null, "ts");
if (timeStampStr != null) {
try {
// 如果有时间戳信息,则解析时间戳
long timeStamp = Long.parseLong(timeStampStr);
// 设置时间戳
ps.setTimeStamp(timeStamp, timeStampStr);
} catch (NumberFormatException e) {
}
}
// 解析 userId的值
String idStr = parser.getAttributeValue(null, "userId");
ps.userId = idStr != null ? Integer.parseInt(idStr) : 0; // 设置 userId
if(ps.userId <= 0) {
// 如果 userId 小于0,则取值于 sharedUserId 的值
String sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
ps.userId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
}
int outerDepth = parser.getDepth();
int type;
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();
// 解析 updated-package 标签内的子标签"perms"
if (tagName.equals("perms")) {
// ps.grantedPermissions 内装入的是子标签"perms"中声明的"权限名称"
readGrantedPermissionsLP(parser,
ps.grantedPermissions);
} else {
reportSettingsProblem(Log.WARN,
"Unknown element under <updated-package>: "
+ parser.getName());
XmlUtils.skipCurrentTag(parser);
}
}
// name:包名,根据包名转入 PackageSetting对象
mDisabledSysPackages.put(name, ps);
}

2.3 scanDirLI

     // 扫描:system/app目录、system/framework目录、data/app目录、data/app-private目录
private void scanDirLI(File dir, int flags, int scanMode) {
Log.d(TAG, "Scanning app dir " + dir); String[] files = dir.list(); int i;
for (i=0; i<files.length; i++) {
File file = new File(dir, files[i]);
File resFile = file;
// Pick up the resource path from settings for fwd locked apps
if ((scanMode & SCAN_FORWARD_LOCKED) != 0) { // data/app-private目录 ?
resFile = null;
}
// 第1个参数、第2个参数和第3个参数,大多时候同一个值
PackageParser.Package pkg = scanPackageLI(file, file, resFile,
flags|PackageParser.PARSE_MUST_BE_APK, scanMode);
}
}

2.3.1 scanPackageLI

 /*
* Scan a package and return the newly parsed package.
* Returns null in case of errors and the error code is stored in mLastScanError
*/
private PackageParser.Package scanPackageLI(File scanFile,
File destCodeFile, File destResourceFile, int parseFlags,
int scanMode) {
mLastScanError = PackageManager.INSTALL_SUCCEEDED;
parseFlags |= mDefParseFlags;
PackageParser pp = new PackageParser(scanFile.getPath());
pp.setSeparateProcesses(mSeparateProcesses);
pp.setSdkVersion(mSdkVersion, mSdkCodename);
// 解析包,主要是解析 AndroidManifest.xml 文件
final PackageParser.Package pkg = pp.parsePackage(scanFile,
destCodeFile.getAbsolutePath(), mMetrics, parseFlags);
if (pkg == null) { // 解析异常,直接返回
mLastScanError = pp.getParseError();
return null;
}
PackageSetting ps;
PackageSetting updatedPkg;
synchronized (mPackages) {
ps = mSettings.peekPackageLP(pkg.packageName);
updatedPkg = mSettings.mDisabledSysPackages.get(pkg.packageName);
}
///// 首先验证APK签名信息,如果验证出现问题,则直接返回
// Verify certificates first
if (!collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags)) {
Log.i(TAG, "Failed verifying certificates for package:" + pkg.packageName);
return null;
}
if (updatedPkg != null) {
// An updated system app will not have the PARSE_IS_SYSTEM flag set initially
parseFlags |= PackageParser.PARSE_IS_SYSTEM;
}
if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
// Check for updated system applications here
if (updatedPkg != null) {
if ((ps != null) && (!ps.codePath.getPath().equals(scanFile.getPath()))) {
if (pkg.mVersionCode <= ps.versionCode) { // 版本号对比:和 mSettings 集合中搜索出来的包进行对比
// The system package has been updated and the code path does not match
// Ignore entry. Just return
Log.w(TAG, "Package:" + pkg.packageName +
" has been updated. Ignoring the one from path:"+scanFile);
mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
return null;
} else {
// Delete the older apk pointed to by ps
// At this point, its safely assumed that package installation for
// apps in system partition will go through. If not there won't be a working
// version of the app
synchronized (mPackages) {
// Just remove the loaded entries from package lists.
mPackages.remove(ps.name);
}
// 删除资源包
deletePackageResourcesLI(ps.name, ps.codePathString, ps.resourcePathString);
mSettings.enableSystemPackageLP(ps.name);
}
}
}
}
// The apk is forward locked (not public) if its code and resources
// are kept in different files.
if (ps != null && !ps.codePath.equals(ps.resourcePath)) { // code 路径和 resourcePath 路径保存位置不同
scanMode |= SCAN_FORWARD_LOCKED;
}
File resFile = destResourceFile;
if ((scanMode & SCAN_FORWARD_LOCKED) != 0) {
resFile = getFwdLockedResource(ps.name);
}
// Note that we invoke the following method only if we are about to unpack an application
return scanPackageLI(scanFile, destCodeFile, resFile,
pkg, parseFlags, scanMode | SCAN_UPDATE_SIGNATURE);
}

# PackageParser.java

2.3.1.1 parsePackage

 public Package parsePackage(File sourceFile, String destFileName,
DisplayMetrics metrics, int flags) {
// 默认值:安装成功
mParseError = PackageManager.INSTALL_SUCCEEDED; // 拿到文件路径
mArchiveSourcePath = sourceFile.getPath();
if (!sourceFile.isFile()) {// 过滤出目录
Log.w(TAG, "Skipping dir: " + mArchiveSourcePath);
mParseError = PackageManager.INSTALL_PARSE_FAILED_NOT_APK;
return null;
}
// 判断是否是APK文件,如果不是apk文件,则直接返回
if (!isPackageFilename(sourceFile.getName())
&& (flags&PARSE_MUST_BE_APK) != 0) {
if ((flags&PARSE_IS_SYSTEM) == 0) {
// We expect to have non-.apk files in the system dir,
// so don't warn about them.
Log.w(TAG, "Skipping non-package file: " + mArchiveSourcePath);
}
mParseError = PackageManager.INSTALL_PARSE_FAILED_NOT_APK;
return null;
} if ((flags&PARSE_CHATTY) != 0 && Config.LOGD) Log.d(
TAG, "Scanning package: " + mArchiveSourcePath); XmlResourceParser parser = null;
AssetManager assmgr = null;
boolean assetError = true;
try {
assmgr = new AssetManager();
// 将apk文件加入装入
int cookie = assmgr.addAssetPath(mArchiveSourcePath);
if(cookie != 0) {// 文件装入OK
parser = assmgr.openXmlResourceParser(cookie, "AndroidManifest.xml");// 打开 AndroidManifest.xml 文件
assetError = false;
} else {
Log.w(TAG, "Failed adding asset path:"+mArchiveSourcePath);
}
} catch (Exception e) {
Log.w(TAG, "Unable to read AndroidManifest.xml of "
+ mArchiveSourcePath, e);
}
if(assetError) { // 打开 AndroidManifest.xml 出现错误,直接返回
if (assmgr != null) assmgr.close();
mParseError = PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST;
return null;
}
String[] errorText = new String[1];
Package pkg = null;
Exception errorException = null;
try {
// XXXX todo: need to figure out correct configuration.
Resources res = new Resources(assmgr, metrics, null);
////////// 解析 AndroidManifest.xml 文件
pkg = parsePackage(res, parser, flags, errorText);
} catch (Exception e) {
errorException = e;
mParseError = PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION;
} // 解析包出错,释放资源,直接返回
if (pkg == null) {
if (errorException != null) {
Log.w(TAG, mArchiveSourcePath, errorException);
} else {
Log.w(TAG, mArchiveSourcePath + " (at "
+ parser.getPositionDescription()
+ "): " + errorText[0]);
}
parser.close();
assmgr.close();
if (mParseError == PackageManager.INSTALL_SUCCEEDED) {
mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
}
return null;
} parser.close();
assmgr.close(); // 赋值 sourceDir 和 publicSourceDir
pkg.applicationInfo.sourceDir = destFileName;
pkg.applicationInfo.publicSourceDir = destFileName;
pkg.mSignatures = null; return pkg;
}

2.3.1.1.1  parsePackage

  // 解析 AndroidManifest.xml 文件
private Package parsePackage(
Resources res, XmlResourceParser parser, int flags, String[] outError)
throws XmlPullParserException, IOException {
AttributeSet attrs = parser; mParseInstrumentationArgs = null;
mParseActivityArgs = null;
mParseServiceArgs = null;
mParseProviderArgs = null; // 从 AndroidManifest.xml 文件中解析包名
String pkgName = parsePackageName(parser, attrs, flags, outError);
if (pkgName == null) { // 没有拿到包名
mParseError = PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME;
return null;
}
int type; // 根据 “包名” 新建 Package 对象
final Package pkg = new Package(pkgName);
boolean foundApp = false; TypedArray sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.AndroidManifest);
// 获取 versionCode 属性值
pkg.mVersionCode = sa.getInteger(
com.android.internal.R.styleable.AndroidManifest_versionCode, 0);
// 获取 versionName 属性值
pkg.mVersionName = sa.getNonResourceString(
com.android.internal.R.styleable.AndroidManifest_versionName);
if (pkg.mVersionName != null) {
pkg.mVersionName = pkg.mVersionName.intern();
}
// 获取 sharedUserId 属性值
String str = sa.getNonResourceString(
com.android.internal.R.styleable.AndroidManifest_sharedUserId);
if (str != null) {// 如果存在 sharedUserId 属性值
String nameError = validateName(str, true);
if (nameError != null && !"android".equals(pkgName)) {
outError[0] = "<manifest> specifies bad sharedUserId name \""
+ str + "\": " + nameError;
mParseError = PackageManager.INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID;
return null;
}
// 将 sharedUserId 的值赋值给 Package 对象
pkg.mSharedUserId = str.intern();
// 获取 sharedUserLabel 属性值
pkg.mSharedUserLabel = sa.getResourceId(
com.android.internal.R.styleable.AndroidManifest_sharedUserLabel, 0);
}
sa.recycle(); // TypedArray资源回收 // Resource boolean are -1, so 1 means we don't know the value.
int supportsSmallScreens = 1;
int supportsNormalScreens = 1;
int supportsLargeScreens = 1;
int resizeable = 1;
int anyDensity = 1; int outerDepth = parser.getDepth();
while ((type=parser.next()) != parser.END_DOCUMENT
&& (type != parser.END_TAG || parser.getDepth() > outerDepth)) {
if (type == parser.END_TAG || type == parser.TEXT) {
continue;
} String tagName = parser.getName();
// 从 AndroidManifest.xml 文件中解析 application 标签
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 {
Log.w(TAG, "<manifest> has more than one <application>");
XmlUtils.skipCurrentTag(parser);
continue;
}
} foundApp = true;
// 解析 application 标签
if (!parseApplication(pkg, res, parser, attrs, flags, outError)) {
return null;
}
// 解析 permission-group 标签
} else if (tagName.equals("permission-group")) {
if (parsePermissionGroup(pkg, res, parser, attrs, outError) == null) {
return null;
}
// 解析 permission 标签
} else if (tagName.equals("permission")) {
if (parsePermission(pkg, res, parser, attrs, outError) == null) {
return null;
}
// 解析 permission-tree 标签
} else if (tagName.equals("permission-tree")) {
if (parsePermissionTree(pkg, res, parser, attrs, outError) == null) {
return null;
}
// 解析 uses-permission 标签
} else if (tagName.equals("uses-permission")) {
sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.AndroidManifestUsesPermission); String name = sa.getNonResourceString(
com.android.internal.R.styleable.AndroidManifestUsesPermission_name); sa.recycle(); if (name != null && !pkg.requestedPermissions.contains(name)) {
pkg.requestedPermissions.add(name.intern());
} XmlUtils.skipCurrentTag(parser); // 解析 uses-configuration 标签
} else if (tagName.equals("uses-configuration")) {
ConfigurationInfo cPref = new ConfigurationInfo();
sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.AndroidManifestUsesConfiguration);
cPref.reqTouchScreen = sa.getInt(
com.android.internal.R.styleable.AndroidManifestUsesConfiguration_reqTouchScreen,
Configuration.TOUCHSCREEN_UNDEFINED);
cPref.reqKeyboardType = sa.getInt(
com.android.internal.R.styleable.AndroidManifestUsesConfiguration_reqKeyboardType,
Configuration.KEYBOARD_UNDEFINED);
if (sa.getBoolean(
com.android.internal.R.styleable.AndroidManifestUsesConfiguration_reqHardKeyboard,
false)) {
cPref.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
}
cPref.reqNavigation = sa.getInt(
com.android.internal.R.styleable.AndroidManifestUsesConfiguration_reqNavigation,
Configuration.NAVIGATION_UNDEFINED);
if (sa.getBoolean(
com.android.internal.R.styleable.AndroidManifestUsesConfiguration_reqFiveWayNav,
false)) {
cPref.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
}
sa.recycle();
pkg.configPreferences.add(cPref); XmlUtils.skipCurrentTag(parser);
// 解析 uses-feature 标签
} else if (tagName.equals("uses-feature")) {
ConfigurationInfo cPref = new ConfigurationInfo();
sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.AndroidManifestUsesFeature);
cPref.reqGlEsVersion = sa.getInt(
com.android.internal.R.styleable.AndroidManifestUsesFeature_glEsVersion,
ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
sa.recycle();
pkg.configPreferences.add(cPref); XmlUtils.skipCurrentTag(parser); // 解析 uses-sdk 标签
} else if (tagName.equals("uses-sdk")) {
if (mSdkVersion > 0) {
sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.AndroidManifestUsesSdk); int minVers = 0;
String minCode = null;
int targetVers = 0;
String targetCode = null; // 解析 minSdkVersion 属性值
TypedValue val = sa.peekValue(
com.android.internal.R.styleable.AndroidManifestUsesSdk_minSdkVersion);
if (val != null) { // 数值和字串区别
if (val.type == TypedValue.TYPE_STRING && val.string != null) {
targetCode = minCode = val.string.toString();
} else {
// If it's not a string, it's an integer.
targetVers = minVers = val.data;
}
} // 解析 targetSdkVersion 属性
val = sa.peekValue(
com.android.internal.R.styleable.AndroidManifestUsesSdk_targetSdkVersion);
if (val != null) { // 数值和字串区别
if (val.type == TypedValue.TYPE_STRING && val.string != null) {
targetCode = minCode = val.string.toString();
} else {
// If it's not a string, it's an integer.
targetVers = val.data;
}
} // 解析 maxSdkVersion 属性
int maxVers = sa.getInt(
com.android.internal.R.styleable.AndroidManifestUsesSdk_maxSdkVersion,
mSdkVersion); sa.recycle(); if (minCode != null) {
if (!minCode.equals(mSdkCodename)) {
if (mSdkCodename != null) {
outError[0] = "Requires development platform " + minCode
+ " (current platform is " + mSdkCodename + ")";
} else {
outError[0] = "Requires development platform " + minCode
+ " but this is a release platform.";
}
mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK;
return null;
}
} else if (minVers > mSdkVersion) {
outError[0] = "Requires newer sdk version #" + minVers
+ " (current version is #" + mSdkVersion + ")";
mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK;
return null;
} if (targetCode != null) {
if (!targetCode.equals(mSdkCodename)) {
if (mSdkCodename != null) {
outError[0] = "Requires development platform " + targetCode
+ " (current platform is " + mSdkCodename + ")";
} else {
outError[0] = "Requires development platform " + targetCode
+ " but this is a release platform.";
}
mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK;
return null;
}
// If the code matches, it definitely targets this SDK.
pkg.applicationInfo.targetSdkVersion
= android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
} else {
pkg.applicationInfo.targetSdkVersion = targetVers;
} if (maxVers < mSdkVersion) {
outError[0] = "Requires older sdk version #" + maxVers
+ " (current version is #" + mSdkVersion + ")";
mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK;
return null;
}
} XmlUtils.skipCurrentTag(parser); // 解析 supports-screens 标签
} else if (tagName.equals("supports-screens")) {
sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.AndroidManifestSupportsScreens); // This is a trick to get a boolean and still able to detect
// if a value was actually set.
supportsSmallScreens = sa.getInteger(
com.android.internal.R.styleable.AndroidManifestSupportsScreens_smallScreens,
supportsSmallScreens);
supportsNormalScreens = sa.getInteger(
com.android.internal.R.styleable.AndroidManifestSupportsScreens_normalScreens,
supportsNormalScreens);
supportsLargeScreens = sa.getInteger(
com.android.internal.R.styleable.AndroidManifestSupportsScreens_largeScreens,
supportsLargeScreens);
resizeable = sa.getInteger(
com.android.internal.R.styleable.AndroidManifestSupportsScreens_resizeable,
supportsLargeScreens);
anyDensity = sa.getInteger(
com.android.internal.R.styleable.AndroidManifestSupportsScreens_anyDensity,
anyDensity); sa.recycle(); XmlUtils.skipCurrentTag(parser);
// 解析protected-broadcast 标签
} else if (tagName.equals("protected-broadcast")) {
sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.AndroidManifestProtectedBroadcast); String name = sa.getNonResourceString(
com.android.internal.R.styleable.AndroidManifestProtectedBroadcast_name); sa.recycle(); if (name != null && (flags&PARSE_IS_SYSTEM) != 0) {
if (pkg.protectedBroadcasts == null) {
pkg.protectedBroadcasts = new ArrayList<String>();
}
if (!pkg.protectedBroadcasts.contains(name)) {
pkg.protectedBroadcasts.add(name.intern());
}
} XmlUtils.skipCurrentTag(parser);
// 解析 instrumentation 标签
} else if (tagName.equals("instrumentation")) {
if (parseInstrumentation(pkg, res, parser, attrs, outError) == null) {
return null;
}
// 解析 eat-comment 标签
} else if (tagName.equals("eat-comment")) {
// Just skip this tag
XmlUtils.skipCurrentTag(parser);
continue; } else if (RIGID_PARSER) { // 打印log信息
outError[0] = "Bad element under <manifest>: "
+ parser.getName();
mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
return null; } else { // 打印log信息
Log.w(TAG, "Bad element under <manifest>: "
+ parser.getName());
XmlUtils.skipCurrentTag(parser);
continue;
}
} if (!foundApp && pkg.instrumentation.size() == 0) { // 没有发现 <application> 标签 或 <instrumentation> 标签
outError[0] = "<manifest> does not contain an <application> or <instrumentation>";
mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_EMPTY;
} final int NP = PackageParser.NEW_PERMISSIONS.length;
for (int ip=0; ip<NP; ip++) {
final PackageParser.NewPermissionInfo npi
= PackageParser.NEW_PERMISSIONS[ip];
if (pkg.applicationInfo.targetSdkVersion >= npi.sdkVersion) {
break;
}
if (!pkg.requestedPermissions.contains(npi.name)) {
Log.i(TAG, "Impliciting adding " + npi.name + " to old pkg "
+ pkg.packageName);
pkg.requestedPermissions.add(npi.name);
}
} if (pkg.usesLibraries.size() > 0) {
pkg.usesLibraryFiles = new String[pkg.usesLibraries.size()];
pkg.usesLibraries.toArray(pkg.usesLibraryFiles);
} if (supportsSmallScreens < 0 || (supportsSmallScreens > 0
&& pkg.applicationInfo.targetSdkVersion
>= android.os.Build.VERSION_CODES.DONUT)) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS;
}
if (supportsNormalScreens != 0) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS;
}
if (supportsLargeScreens < 0 || (supportsLargeScreens > 0
&& pkg.applicationInfo.targetSdkVersion
>= android.os.Build.VERSION_CODES.DONUT)) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS;
}
if (resizeable < 0 || (resizeable > 0
&& pkg.applicationInfo.targetSdkVersion
>= android.os.Build.VERSION_CODES.DONUT)) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS;
}
if (anyDensity < 0 || (anyDensity > 0
&& pkg.applicationInfo.targetSdkVersion
>= android.os.Build.VERSION_CODES.DONUT)) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES;
} return pkg;
}

2.3.1.2 collectCertificatesLI

     private boolean collectCertificatesLI(PackageParser pp, PackageSetting ps,
PackageParser.Package pkg, File srcFile, int parseFlags) {
if (GET_CERTIFICATES) {
if (ps == null || !ps.codePath.equals(srcFile)
|| ps.getTimeStamp() != srcFile.lastModified()) {
// 源文件已经改变,再次收集证书
Log.i(TAG, srcFile.toString() + " changed; collecting certs");
// 收集证书
if (!pp.collectCertificates(pkg, parseFlags)) {
mLastScanError = pp.getParseError();
return false;
}
}
}
return true;
}

2.3.1.3 deletePackageResourcesLI

     private void deletePackageResourcesLI(String packageName,
String sourceDir, String publicSourceDir) {
File sourceFile = new File(sourceDir);
if (!sourceFile.exists()) {
Log.w(TAG, "Package source " + sourceDir + " does not exist.");
}
// 删除文件
// Delete application's code and resources
sourceFile.delete();
final File publicSourceFile = new File(publicSourceDir);
if (publicSourceFile.exists()) {
publicSourceFile.delete();
}
if (mInstaller != null) {
// 通过 mInstaller 删除dex文件
int retCode = mInstaller.rmdex(sourceFile.toString());
if (retCode < 0) {
Log.w(TAG, "Couldn't remove dex file for package: "
+ packageName + " at location " + sourceFile.toString() + ", retcode=" + retCode);
// we don't consider this to be a failure of the core package deletion
}
}
}

2.3.1.4 scanPackageLI

 private PackageParser.Package scanPackageLI(
File scanFile, File destCodeFile, File destResourceFile,
PackageParser.Package pkg, int parseFlags, int scanMode) { mScanningPath = scanFile;
if (pkg == null) { // pkg传入的是null,直接返回
mLastScanError = PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME;
return null;
} final String pkgName = pkg.applicationInfo.packageName;
if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
} if (pkgName.equals("android")) { // android包
synchronized (mPackages) {
if (mAndroidApplication != null) { // 已经解析过了,不再解析
Log.w(TAG, "*************************************************");
Log.w(TAG, "Core android package being redefined. Skipping.");
Log.w(TAG, " file=" + mScanningPath);
Log.w(TAG, "*************************************************");
mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
return null;
} // 第一次解析
// Set up information for our fall-back user intent resolution
// activity.
mPlatformPackage = pkg; // 保存平台包信息
pkg.mVersionCode = mSdkVersion;
mAndroidApplication = pkg.applicationInfo;
//### ResolverActivity 这个activity 赋值的地方
mResolveActivity.applicationInfo = mAndroidApplication;
mResolveActivity.name = ResolverActivity.class.getName();
mResolveActivity.packageName = mAndroidApplication.packageName;
mResolveActivity.processName = mAndroidApplication.processName;
mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
mResolveActivity.theme = com.android.internal.R.style.Theme_Dialog_Alert;
mResolveActivity.exported = true;
mResolveActivity.enabled = true;
mResolveInfo.activityInfo = mResolveActivity;
mResolveInfo.priority = 0;
mResolveInfo.preferredOrder = 0;
mResolveInfo.match = 0;
// 构建 ResolverActivity 这个activity的ComponentName
mResolveComponentName = new ComponentName(
mAndroidApplication.packageName, mResolveActivity.name);
}
} if ((parseFlags&PackageParser.PARSE_CHATTY) != 0 && Config.LOGD) Log.d(
TAG, "Scanning package " + pkgName);
if (mPackages.containsKey(pkgName) || mSharedLibraries.containsKey(pkgName)) {
Log.w(TAG, "*************************************************");
Log.w(TAG, "Application package " + pkgName
+ " already installed. Skipping duplicate.");
Log.w(TAG, "*************************************************");
mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
return null;
} SharedUserSetting suid = null;
PackageSetting pkgSetting = null; boolean removeExisting = false; synchronized (mPackages) {
// Check all shared libraries and map to their actual file path.
if (pkg.usesLibraryFiles != null) {
for (int i=0; i<pkg.usesLibraryFiles.length; i++) {
String file = mSharedLibraries.get(pkg.usesLibraryFiles[i]);
if (file == null) {
Log.e(TAG, "Package " + pkg.packageName
+ " requires unavailable shared library "
+ pkg.usesLibraryFiles[i] + "; ignoring!");
mLastScanError = PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
return null;
}
pkg.usesLibraryFiles[i] = file;
}
} if (pkg.mSharedUserId != null) {
suid = mSettings.getSharedUserLP(pkg.mSharedUserId,
pkg.applicationInfo.flags, true);
if (suid == null) {
Log.w(TAG, "Creating application package " + pkgName
+ " for shared user failed");
mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
return null;
}
if ((parseFlags&PackageParser.PARSE_CHATTY) != 0 && Config.LOGD) {
Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid="
+ suid.userId + "): packages=" + suid.packages);
}
} // Just create the setting, don't add it yet. For already existing packages
// the PkgSetting exists already and doesn't have to be created.
pkgSetting = mSettings.getPackageLP(pkg, suid, destCodeFile,
destResourceFile, pkg.applicationInfo.flags, true, false);
if (pkgSetting == null) {
Log.w(TAG, "Creating application package " + pkgName + " failed");
mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
return null;
}
if(mSettings.mDisabledSysPackages.get(pkg.packageName) != null) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
} pkg.applicationInfo.uid = pkgSetting.userId;
pkg.mExtras = pkgSetting; // 校验签名
if (!verifySignaturesLP(pkgSetting, pkg, parseFlags,
(scanMode&SCAN_UPDATE_SIGNATURE) != 0)) {
if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) == 0) {
mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
return null;
}
// 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 (pkgSetting.sharedUser != null) {
if (!pkgSetting.sharedUser.signatures.mergeSignatures(
pkg.mSignatures, false)) {
mLastScanError = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
return null;
}
}
removeExisting = true;
} // Verify that this new package doesn't have any content providers
// that conflict with existing packages. Only do this if the
// package isn't already installed, since we don't want to break
// things that are installed.
if ((scanMode&SCAN_NEW_INSTALL) != 0) { // 检查 content provider 避免冲突
int N = pkg.providers.size();
int i;
for (i=0; i<N; i++) {
PackageParser.Provider p = pkg.providers.get(i);
String names[] = p.info.authority.split(";");
for (int j = 0; j < names.length; j++) {
if (mProviders.containsKey(names[j])) {
PackageParser.Provider other = mProviders.get(names[j]);
Log.w(TAG, "Can't install because provider name " + names[j] +
" (in package " + pkg.applicationInfo.packageName +
") is already used by "
+ ((other != null && other.component != null)
? other.component.getPackageName() : "?"));
mLastScanError = PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
return null;
}
}
}
}
} if (removeExisting) {
if (mInstaller != null) {
int ret = mInstaller.remove(pkgName);
if (ret != 0) {
String msg = "System package " + pkg.packageName
+ " could not have data directory erased after signature change.";
reportSettingsProblem(Log.WARN, msg);
mLastScanError = PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
return null;
}
}
Log.w(TAG, "System package " + pkg.packageName
+ " signature changed: existing data removed.");
mLastScanError = PackageManager.INSTALL_SUCCEEDED;
} // 文件时间戳比对
long scanFileTime = scanFile.lastModified();
final boolean forceDex = (scanMode&SCAN_FORCE_DEX) != 0;
final boolean scanFileNewer = forceDex || scanFileTime != pkgSetting.getTimeStamp();
pkg.applicationInfo.processName = fixProcessName(
pkg.applicationInfo.packageName,
pkg.applicationInfo.processName,
pkg.applicationInfo.uid);
pkg.applicationInfo.publicSourceDir = destResourceFile.toString(); File dataPath;
if (mPlatformPackage == pkg) { // 平台包,包名 “android”
// The system package is special.
dataPath = new File (Environment.getDataDirectory(), "system");// "系统包"是特殊的,路径:data/system
pkg.applicationInfo.dataDir = dataPath.getPath(); // 路径:data/system 目录
} else { // 普通包
// This is a normal package, need to make its data directory.
dataPath = new File(mAppDataDir, pkgName);// 普通应用数据目录:data/data/"包名"
if (dataPath.exists()) {
mOutPermissions[1] = 0;
FileUtils.getPermissions(dataPath.getPath(), mOutPermissions);
if (mOutPermissions[1] == pkg.applicationInfo.uid
|| !Process.supportsProcesses()) {
pkg.applicationInfo.dataDir = dataPath.getPath(); // data/data/"包名"
} else {
boolean recovered = false;
if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { // 如果是system app
// If this is a system app, we can at least delete its
// current data so the application will still work.
if (mInstaller != null) {
int ret = mInstaller.remove(pkgName); // 删除旧数据
if(ret >= 0) {
// Old data gone!
String msg = "System package " + pkg.packageName
+ " has changed from uid: "
+ mOutPermissions[1] + " to "
+ pkg.applicationInfo.uid + "; old data erased";
reportSettingsProblem(Log.WARN, msg);
recovered = true; // 重新安装
// And now re-install the app.
ret = mInstaller.install(pkgName, pkg.applicationInfo.uid,
pkg.applicationInfo.uid);
if (ret == -1) {
// Ack should not happen!
msg = "System package " + pkg.packageName
+ " could not have data directory re-created after delete.";
reportSettingsProblem(Log.WARN, msg);
mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
return null;
}
}
}
if (!recovered) {
mHasSystemUidErrors = true;
}
}
if (!recovered) {
pkg.applicationInfo.dataDir = "/mismatched_uid/settings_"
+ pkg.applicationInfo.uid + "/fs_"
+ mOutPermissions[1];
String msg = "Package " + pkg.packageName
+ " has mismatched uid: "
+ mOutPermissions[1] + " on disk, "
+ pkg.applicationInfo.uid + " in settings";
synchronized (mPackages) {
if (!mReportedUidError) {
mReportedUidError = true;
msg = msg + "; read messages:\n"
+ mSettings.getReadMessagesLP();
}
reportSettingsProblem(Log.ERROR, msg);
}
}
}
pkg.applicationInfo.dataDir = dataPath.getPath();
} else {
if ((parseFlags&PackageParser.PARSE_CHATTY) != 0 && Config.LOGV)
Log.v(TAG, "Want this data dir: " + dataPath);
// 调用 installer 去执行真正的安装
//invoke installer to do the actual installation
if (mInstaller != null) {
int ret = mInstaller.install(pkgName, pkg.applicationInfo.uid,
pkg.applicationInfo.uid);
if(ret < 0) { // 安装失败,直接返回
// Error from installer
mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
return null;
}
} else {
dataPath.mkdirs(); // 创建数据目录
if (dataPath.exists()) {
// 对数据目录设置权限
FileUtils.setPermissions(
dataPath.toString(),
FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
pkg.applicationInfo.uid, pkg.applicationInfo.uid);
}
}
if (dataPath.exists()) { // 目录创建成功,直接赋值
pkg.applicationInfo.dataDir = dataPath.getPath();
} else {
Log.w(TAG, "Unable to create data directory: " + dataPath);
pkg.applicationInfo.dataDir = null;
}
}
} // 如果不是system app,执行共享库安装和dex优化
// Perform shared library installation and dex validation and
// optimization, if this is not a system app.
if (mInstaller != null) {
String path = scanFile.getPath();
if (scanFileNewer) {
Log.i(TAG, path + " changed; unpacking"); // 解包
int err = cachePackageSharedLibsLI(pkg, dataPath, scanFile);
if (err != PackageManager.INSTALL_SUCCEEDED) {
mLastScanError = err;
return null;
}
} pkg.mForwardLocked = (scanMode&SCAN_FORWARD_LOCKED) != 0;
pkg.mScanPath = path; if ((scanMode&SCAN_NO_DEX) == 0) {
// 执行dex优化
if (performDexOptLI(pkg, forceDex) == DEX_OPT_FAILED) {
mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT;
return null;
}
}
} // 工厂测试权限
if (mFactoryTest && pkg.requestedPermissions.contains(
android.Manifest.permission.FACTORY_TEST)) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
} // We don't expect installation to fail beyond this point,
if ((scanMode&SCAN_MONITOR) != 0) {
pkg.mPath = destCodeFile.getAbsolutePath();
mAppDirs.put(pkg.mPath, pkg);
} // Request the ActivityManager to kill the process(only for existing packages)
// so that we do not end up in a confused state while the user is still using the older
// version of the application while the new one gets installed.
IActivityManager am = ActivityManagerNative.getDefault();
if ((am != null) && ((parseFlags & PackageManager.INSTALL_REPLACE_EXISTING ) != 0)) {
try {
// 杀进程
am.killApplicationWithUid(pkg.applicationInfo.packageName,
pkg.applicationInfo.uid);
} catch (RemoteException e) {
}
}
synchronized (mPackages) {
// 添加到mSettings
// Add the new setting to mSettings
mSettings.insertPackageSettingLP(pkgSetting, pkg, destCodeFile, destResourceFile);
// Add the new setting to mPackages
// 添加到mPackages
mPackages.put(pkg.applicationInfo.packageName, pkg);
int N = pkg.providers.size();
StringBuilder r = null;
int i;
for (i=0; i<N; i++) {
PackageParser.Provider p = pkg.providers.get(i);
p.info.processName = fixProcessName(pkg.applicationInfo.processName,
p.info.processName, pkg.applicationInfo.uid);
mProvidersByComponent.put(new ComponentName(p.info.packageName,
p.info.name), p);
p.syncable = p.info.isSyncable;
String names[] = p.info.authority.split(";");
p.info.authority = null;
for (int j = 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 = new PackageParser.Provider(p);
p.syncable = false;
}
if (!mProviders.containsKey(names[j])) {
mProviders.put(names[j], p);
if (p.info.authority == null) {
p.info.authority = names[j];
} else {
p.info.authority = p.info.authority + ";" + names[j];
}
if ((parseFlags&PackageParser.PARSE_CHATTY) != 0 && Config.LOGD)
Log.d(TAG, "Registered content provider: " + names[j] +
", className = " + p.info.name +
", isSyncable = " + p.info.isSyncable);
} else {
PackageParser.Provider other = mProviders.get(names[j]);
Log.w(TAG, "Skipping provider name " + names[j] +
" (in package " + pkg.applicationInfo.packageName +
"): name already used by "
+ ((other != null && other.component != null)
? other.component.getPackageName() : "?"));
}
}
if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ');
}
r.append(p.info.name);
}
}
if (r != null) {
if (Config.LOGD) Log.d(TAG, " Providers: " + r);
} N = pkg.services.size();
r = null;
for (i=0; i<N; i++) {
PackageParser.Service s = pkg.services.get(i);
s.info.processName = fixProcessName(pkg.applicationInfo.processName,
s.info.processName, pkg.applicationInfo.uid);
mServices.addService(s);
if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ');
}
r.append(s.info.name);
}
}
if (r != null) {
if (Config.LOGD) Log.d(TAG, " Services: " + r);
} N = pkg.receivers.size();
r = null;
for (i=0; i<N; i++) {
PackageParser.Activity a = pkg.receivers.get(i);
a.info.processName = fixProcessName(pkg.applicationInfo.processName,
a.info.processName, pkg.applicationInfo.uid);
mReceivers.addActivity(a, "receiver");
if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ');
}
r.append(a.info.name);
}
}
if (r != null) {
if (Config.LOGD) Log.d(TAG, " Receivers: " + r);
} 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);
}
}
if (r != null) {
if (Config.LOGD) Log.d(TAG, " Activities: " + r);
} N = pkg.permissionGroups.size();
r = null;
for (i=0; i<N; i++) {
PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
if (cur == null) {
mPermissionGroups.put(pg.info.name, pg);
if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ');
}
r.append(pg.info.name);
}
} else {
Log.w(TAG, "Permission group " + pg.info.name + " from package "
+ pg.info.packageName + " ignored: original from "
+ cur.info.packageName);
if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ');
}
r.append("DUP:");
r.append(pg.info.name);
}
}
}
if (r != null) {
if (Config.LOGD) Log.d(TAG, " Permission Groups: " + r);
} N = pkg.permissions.size();
r = null;
for (i=0; i<N; i++) {
PackageParser.Permission p = pkg.permissions.get(i);
HashMap<String, BasePermission> permissionMap =
p.tree ? mSettings.mPermissionTrees
: mSettings.mPermissions;
p.group = mPermissionGroups.get(p.info.group);
if (p.info.group == null || p.group != null) {
BasePermission bp = permissionMap.get(p.info.name);
if (bp == null) {
bp = new BasePermission(p.info.name, p.info.packageName,
BasePermission.TYPE_NORMAL);
permissionMap.put(p.info.name, bp);
}
if (bp.perm == null) {
if (bp.sourcePackage == null
|| bp.sourcePackage.equals(p.info.packageName)) {
BasePermission tree = findPermissionTreeLP(p.info.name);
if (tree == null
|| tree.sourcePackage.equals(p.info.packageName)) {
bp.perm = p;
bp.uid = pkg.applicationInfo.uid;
if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ');
}
r.append(p.info.name);
}
} else {
Log.w(TAG, "Permission " + p.info.name + " from package "
+ p.info.packageName + " ignored: base tree "
+ tree.name + " is from package "
+ tree.sourcePackage);
}
} else {
Log.w(TAG, "Permission " + p.info.name + " from package "
+ p.info.packageName + " ignored: original from "
+ bp.sourcePackage);
}
} else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ');
}
r.append("DUP:");
r.append(p.info.name);
}
} else {
Log.w(TAG, "Permission " + p.info.name + " from package "
+ p.info.packageName + " ignored: no group "
+ p.group);
}
}
if (r != null) {
if (Config.LOGD) Log.d(TAG, " Permissions: " + r);
} N = pkg.instrumentation.size();
r = null;
for (i=0; i<N; i++) {
PackageParser.Instrumentation a = pkg.instrumentation.get(i);
a.info.packageName = pkg.applicationInfo.packageName;
a.info.sourceDir = pkg.applicationInfo.sourceDir;
a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
a.info.dataDir = pkg.applicationInfo.dataDir;
mInstrumentation.put(a.component, a);
if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ');
}
r.append(a.info.name);
}
}
if (r != null) {
if (Config.LOGD) Log.d(TAG, " Instrumentation: " + r);
} if (pkg.protectedBroadcasts != null) {
N = pkg.protectedBroadcasts.size();
for (i=0; i<N; i++) {
mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
}
} pkgSetting.setTimeStamp(scanFileTime);
} return pkg;
}

Android 1.6 PackageManagerService源码分析的更多相关文章

  1. Android事件分发机制源码分析

    Android事件分发机制源码分析 Android事件分发机制源码分析 Part1事件来源以及传递顺序 Activity分发事件源码 PhoneWindow分发事件源码 小结 Part2ViewGro ...

  2. Android 自定义View及其在布局文件中的使用示例(三):结合Android 4.4.2_r1源码分析onMeasure过程

    转载请注明出处 http://www.cnblogs.com/crashmaker/p/3549365.html From crash_coder linguowu linguowu0622@gami ...

  3. android高级---->AsyncTask的源码分析

    在Android中实现异步任务机制有两种方式,Handler和AsyncTask,它在子线程更新UI的例子可以参见我的博客(android基础---->子线程更新UI).今天我们通过一个小的案例 ...

  4. Android异步消息传递机制源码分析

    1.Android异步消息传递机制有以下两个方式:(异步消息传递来解决线程通信问题) handler 和 AsyncTask 2.handler官方解释的用途: 1).定时任务:通过handler.p ...

  5. Android 4.0 Launcher2源码分析——主布局文件(转)

    本文来自http://blog.csdn.net/chenshaoyang0011 Android系统的一大特色是它拥有的桌面通知系统,不同于IOS的桌面管理,Android有一个桌面系统用于管理和展 ...

  6. Android面试题-OkHttp3源码分析

    本文配套视频: okhttp内核分析配套视频一 okhttp内核分析配套视频二 okhttp内核分析配套视频三 源码分析相关面试题 Volley源码分析 注解框架实现原理 基本使用 从使用方法出发,首 ...

  7. Android进阶系列之源码分析Activity的启动流程

    美女镇楼,辟邪! 源码,是一个程序猿前进路上一个大的而又不得不去翻越障碍,我讨厌源码,看着一大堆.5000多行,要看完得啥时候去了啊.不过做安卓的总有这一天,自从踏上这条不归路,我就认命了.好吧,我慢 ...

  8. Android 开源项目PhotoView源码分析

    https://github.com/chrisbanes/PhotoView/tree/master/library 这个就是项目地址,相信很多人都用过,我依然不去讲怎么使用.只讲他的原理和具体实现 ...

  9. Android系统原理与源码分析(1):利用Java反射技术阻止通过按钮关闭对话框

    原文出处:博主宇宙的极客http://www.cnblogs.com/nokiaguy/archive/2010/07/27/1786482.html 众所周知,AlertDialog类用于显示对话框 ...

随机推荐

  1. TFTP 1.68智能刷机全能版发布,TTL线在CFE模式解决BCM5357如斐讯FIR302B等产品变砖问题

    TFTP 智能刷机从发布以来一直受广大刷机朋友的喜爱,也有很多人一直加我的Q问如何刷机? 在这里我要告诉大家一下,由于机型种类繁多,建议有遇到问题,直接百度,有空的时候我能回答我尽量回答,其他的爱莫能 ...

  2. opengl deferred shading

    原文地址:http://www.verydemo.com/demo_c284_i6147.html 一.Deferred shading技术简介 Deferred shading是这样一种技术:将光照 ...

  3. Unity3D Shader基础教程

    原文地址:http://bbs.9ria.com/thread-212557-1-1.html 此教程将指引你如何建立自己的Shaders,让你的游戏场景看起来更好.Unity配备了强大的阴影和材料的 ...

  4. PHP和Apache结合 Apache默认虚拟主机

  5. MySql数据库恢复(*frm)文件

    mysql数据库恢复(*frm)文件 WorkBench 在使用虚拟服务器时,服务器提供商一般不会像我们使用本地数据库一样:使用导入导出(这样的文件后缀是*.sql).大部分时候提供的是一个文件夹,里 ...

  6. struts实现国际化

    上篇博客学习了Java国际化的一些基础知识,了解了这些知识之后,我们可以更好的过度到struts国际化. 本篇博客主要学习struts国际化的实现: 1.配置环境设置baseName. 在struts ...

  7. 本文将详细介绍oracle 10g OEM常规错误

    本文将详细介绍oracle 10g OEM常规错误-------Unknown host specified解决方法,需要了解的朋友可以参考下 详细出处参考:http://www.jb51.net/a ...

  8. Java编程思想学习笔记——访问权限修饰词

    几种访问权限修饰词 public,protected,private,friendly(Java中并无该修饰词,即包访问权限,不提供任何访问修饰词) 使用时,放置在类中成员(域或方法)的定义之前的,仅 ...

  9. ML基础 : 训练集,验证集,测试集关系及划分 Relation and Devision among training set, validation set and testing set

    首先三个概念存在于 有监督学习的范畴 Training set: A set of examples used for learning, which is to fit the parameters ...

  10. 如何在Datatable中取得每列的数据列宽度

    你用SqlDataAdapter填充DataTable的时候不要用Fill方法而应该用FillSchema方法: using (SqlConnection conn = new SqlConnecti ...