文件清单
framework\base\services\core\java\com\android\server\pm\PackageManagerService.java
PackageManagerService.rar (已经带有文字注释的文件)
下面截取部分介绍
1 PMS初始化
1 public static final IPackageManager main(Context context, boolean factoryTest) { 2 PackageManagerService m = new PackageManagerService(context, factoryTest); 3 ServiceManager.addService("package", m); 4 return m; 5 }
2 构造函数
1 public PackageManagerService(Context context, boolean factoryTest) { 2 EventLog.writeEvent(LOG_BOOT_PROGRESS_PMS_START, 3 SystemClock.uptimeMillis()); 4 5 if (mSdkVersion <= 0) { 6 Log.w(TAG, "**** ro.build.version.sdk not set!"); 7 } 8 9 mContext = context; 10 mFactoryTest = factoryTest; 11 mNoDexOpt = "eng".equals(SystemProperties.get("ro.build.type")); 12 mMetrics = new DisplayMetrics(); 13 mSettings = new Settings(); 14 mSettings.addSharedUserLP("android.uid.system", 15 Process.SYSTEM_UID, ApplicationInfo.FLAG_SYSTEM); 16 mSettings.addSharedUserLP("android.uid.phone", 17 MULTIPLE_APPLICATION_UIDS 18 ? RADIO_UID : FIRST_APPLICATION_UID, 19 ApplicationInfo.FLAG_SYSTEM); 20 21 String separateProcesses = SystemProperties.get("debug.separate_processes"); 22 if (separateProcesses != null && separateProcesses.length() > 0) { 23 if ("*".equals(separateProcesses)) { 24 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES; 25 mSeparateProcesses = null; 26 Log.w(TAG, "Running with debug.separate_processes: * (ALL)"); 27 } else { 28 mDefParseFlags = 0; 29 mSeparateProcesses = separateProcesses.split(","); 30 Log.w(TAG, "Running with debug.separate_processes: " 31 + separateProcesses); 32 } 33 } else { 34 mDefParseFlags = 0; 35 mSeparateProcesses = null; 36 } 37 38 Installer installer = new Installer(); 39 // Little hacky thing to check if installd is here, to determine 40 // whether we are running on the simulator and thus need to take 41 // care of building the /data file structure ourself. 42 // (apparently the sim now has a working installer) 43 if (installer.ping() && Process.supportsProcesses()) { 44 mInstaller = installer; 45 } else { 46 mInstaller = null; 47 } 48 49 WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE); 50 Display d = wm.getDefaultDisplay(); 51 d.getMetrics(mMetrics); 52 53 synchronized (mInstallLock) { 54 synchronized (mPackages) { 55 mHandlerThread.start(); 56 mHandler = new Handler(mHandlerThread.getLooper()); 57 58 // data目录 59 File dataDir = Environment.getDataDirectory(); 60 // 目录:data/data 61 mAppDataDir = new File(dataDir, "data"); 62 // 目录:data/app-private 63 mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); 64 65 if (mInstaller == null) { 66 // Make sure these dirs exist, when we are running in 67 // the simulator. 68 // Make a wide-open directory for random misc stuff. 69 File miscDir = new File(dataDir, "misc"); 70 miscDir.mkdirs(); 71 mAppDataDir.mkdirs(); 72 mDrmAppPrivateInstallDir.mkdirs(); 73 } 74 75 // 读:system/etc/permissions/platform.xml 等xml文件 76 readPermissions(); 77 78 mRestoredSettings = mSettings.readLP(); 79 long startTime = SystemClock.uptimeMillis(); 80 81 EventLog.writeEvent(LOG_BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, 82 startTime); 83 84 int scanMode = SCAN_MONITOR; 85 if (mNoDexOpt) { 86 Log.w(TAG, "Running ENG build: no pre-dexopt!"); 87 scanMode |= SCAN_NO_DEX; 88 } 89 90 final HashSet<String> libFiles = new HashSet<String>(); 91 92 // 目录:system/framework 93 mFrameworkDir = new File(Environment.getRootDirectory(), "framework"); 94 95 if (mInstaller != null) { 96 /** 97 * Out of paranoia, ensure that everything in the boot class 98 * path has been dexed. 99 */ 100 String bootClassPath = System.getProperty("java.boot.class.path"); 101 if (bootClassPath != null) { 102 String[] paths = splitString(bootClassPath, ':'); 103 for (int i=0; i<paths.length; i++) { 104 try { 105 if (dalvik.system.DexFile.isDexOptNeeded(paths[i])) { 106 libFiles.add(paths[i]); 107 // 执行 dexopt 命令 108 mInstaller.dexopt(paths[i], Process.SYSTEM_UID, true); 109 } 110 } catch (FileNotFoundException e) { 111 Log.w(TAG, "Boot class path not found: " + paths[i]); 112 } catch (IOException e) { 113 Log.w(TAG, "Exception reading boot class path: " + paths[i], e); 114 } 115 } 116 } else { 117 Log.w(TAG, "No BOOTCLASSPATH found!"); 118 } 119 120 /** 121 * Also ensure all external libraries have had dexopt run on them. 122 */ 123 if (mSharedLibraries.size() > 0) { 124 Iterator<String> libs = mSharedLibraries.values().iterator(); 125 while (libs.hasNext()) { 126 String lib = libs.next(); 127 try { 128 if (dalvik.system.DexFile.isDexOptNeeded(lib)) { 129 libFiles.add(lib); 130 // 执行 dexopt 命令 131 mInstaller.dexopt(lib, Process.SYSTEM_UID, true); 132 } 133 } catch (FileNotFoundException e) { 134 Log.w(TAG, "Library not found: " + lib); 135 } catch (IOException e) { 136 Log.w(TAG, "Exception reading library: " + lib, e); 137 } 138 } 139 } 140 141 // 目录:system/framework/framework-res.apk 142 // Gross hack for now: we know this file doesn't contain any 143 // code, so don't dexopt it to avoid the resulting log spew. 144 libFiles.add(mFrameworkDir.getPath() + "/framework-res.apk"); 145 146 /** 147 * And there are a number of commands implemented in Java, which 148 * we currently need to do the dexopt on so that they can be 149 * run from a non-root shell. 150 */ 151 String[] frameworkFiles = mFrameworkDir.list(); // 列出 framework目录下所有文件 152 if (frameworkFiles != null && mInstaller != null) { 153 for (int i=0; i<frameworkFiles.length; i++) { 154 File libPath = new File(mFrameworkDir, frameworkFiles[i]); 155 String path = libPath.getPath(); 156 // Skip the file if we alrady did it. 157 if (libFiles.contains(path)) { 158 continue; 159 } 160 // Skip the file if it is not a type we want to dexopt. 161 if (!path.endsWith(".apk") && !path.endsWith(".jar")) { 162 continue; 163 } 164 try { 165 if (dalvik.system.DexFile.isDexOptNeeded(path)) { 166 // 执行 dexopt命令 apk & jar 167 mInstaller.dexopt(path, Process.SYSTEM_UID, true); 168 } 169 } catch (FileNotFoundException e) { 170 Log.w(TAG, "Jar not found: " + path); 171 } catch (IOException e) { 172 Log.w(TAG, "Exception reading jar: " + path, e); 173 } 174 } 175 } 176 } 177 178 mFrameworkInstallObserver = new AppDirObserver( 179 mFrameworkDir.getPath(), OBSERVER_EVENTS, true); 180 mFrameworkInstallObserver.startWatching(); 181 // 扫描 system/framework 目录 182 scanDirLI(mFrameworkDir, PackageParser.PARSE_IS_SYSTEM, 183 scanMode | SCAN_NO_DEX); 184 mSystemAppDir = new File(Environment.getRootDirectory(), "app"); 185 mSystemInstallObserver = new AppDirObserver( 186 mSystemAppDir.getPath(), OBSERVER_EVENTS, true); 187 mSystemInstallObserver.startWatching(); 188 // 扫描 system/app 目录 189 scanDirLI(mSystemAppDir, PackageParser.PARSE_IS_SYSTEM, scanMode); 190 // data/app 目录 191 mAppInstallDir = new File(dataDir, "app"); 192 if (mInstaller == null) { 193 // Make sure these dirs exist, when we are running in 194 // the simulator. 195 mAppInstallDir.mkdirs(); // scanDirLI() assumes this dir exists // 创建 data/app目录 196 } 197 // 搜索未安装完成的程序包 198 //look for any incomplete package installations 199 ArrayList<String> deletePkgsList = mSettings.getListOfIncompleteInstallPackages(); 200 //clean up list 201 for(int i = 0; i < deletePkgsList.size(); i++) { 202 //clean up here 203 cleanupInstallFailedPackage(deletePkgsList.get(i)); // 清理安装失败的包 204 } 205 //delete tmp files 206 deleteTempPackageFiles(); 207 208 EventLog.writeEvent(LOG_BOOT_PROGRESS_PMS_DATA_SCAN_START, 209 SystemClock.uptimeMillis()); 210 mAppInstallObserver = new AppDirObserver( 211 mAppInstallDir.getPath(), OBSERVER_EVENTS, false); 212 mAppInstallObserver.startWatching(); 213 // 扫描 data/app 目录 214 scanDirLI(mAppInstallDir, 0, scanMode); 215 216 mDrmAppInstallObserver = new AppDirObserver( 217 mDrmAppPrivateInstallDir.getPath(), OBSERVER_EVENTS, false); 218 mDrmAppInstallObserver.startWatching(); 219 // 扫描 data/app-private 目录 220 scanDirLI(mDrmAppPrivateInstallDir, 0, scanMode | SCAN_FORWARD_LOCKED); 221 222 EventLog.writeEvent(LOG_BOOT_PROGRESS_PMS_SCAN_END, 223 SystemClock.uptimeMillis()); 224 Log.i(TAG, "Time to scan packages: " 225 + ((SystemClock.uptimeMillis()-startTime)/1000f) 226 + " seconds"); 227 228 updatePermissionsLP(); 229 230 // 初始化后 231 mSettings.writeLP(); 232 233 EventLog.writeEvent(LOG_BOOT_PROGRESS_PMS_READY, 234 SystemClock.uptimeMillis()); 235 236 // Now after opening every single application zip, make sure they 237 // are all flushed. Not really needed, but keeps things nice and 238 // tidy. 239 Runtime.getRuntime().gc(); 240 } // synchronized (mPackages) 241 } // synchronized (mInstallLock) 242 }
2.1 readPermissions()
1 void readPermissions() { 2 // Read permissions from .../etc/permission directory. 3 File libraryDir = new File(Environment.getRootDirectory(), "etc/permissions"); 4 if (!libraryDir.exists() || !libraryDir.isDirectory()) { 5 Log.w(TAG, "No directory " + libraryDir + ", skipping"); 6 return; 7 } 8 if (!libraryDir.canRead()) { 9 Log.w(TAG, "Directory " + libraryDir + " cannot be read"); 10 return; 11 } 12 13 // Iterate over the files in the directory and scan .xml files 14 for (File f : libraryDir.listFiles()) { 15 // We'll read platform.xml last 16 if (f.getPath().endsWith("etc/permissions/platform.xml")) { 17 continue; 18 } 19 20 if (!f.getPath().endsWith(".xml")) { 21 Log.i(TAG, "Non-xml file " + f + " in " + libraryDir + " directory, ignoring"); 22 continue; 23 } 24 if (!f.canRead()) { 25 Log.w(TAG, "Permissions library file " + f + " cannot be read"); 26 continue; 27 } 28 29 readPermissionsFromXml(f); 30 } 31 32 // 目录:system/etc/permissions/platform.xml 33 // Read permissions from .../etc/permissions/platform.xml last so it will take precedence 34 final File permFile = new File(Environment.getRootDirectory(), 35 "etc/permissions/platform.xml"); 36 readPermissionsFromXml(permFile); 37 }
2.1.1 readPermissionsFromXml
1 private void readPermissionsFromXml(File permFile) { 2 FileReader permReader = null; 3 try { 4 permReader = new FileReader(permFile); 5 } catch (FileNotFoundException e) { 6 Log.w(TAG, "Couldn't find or open permissions file " + permFile); 7 return; 8 } 9 10 try { 11 XmlPullParser parser = Xml.newPullParser(); 12 parser.setInput(permReader); 13 14 XmlUtils.beginDocument(parser, "permissions"); 15 16 while (true) { 17 XmlUtils.nextElement(parser); 18 if (parser.getEventType() == XmlPullParser.END_DOCUMENT) { 19 break; 20 } 21 22 String name = parser.getName(); 23 if ("group".equals(name)) { 24 String gidStr = parser.getAttributeValue(null, "gid"); 25 if (gidStr != null) { 26 int gid = Integer.parseInt(gidStr); 27 mGlobalGids = appendInt(mGlobalGids, gid); 28 } else { 29 Log.w(TAG, "<group> without gid at " 30 + parser.getPositionDescription()); 31 } 32 33 XmlUtils.skipCurrentTag(parser); 34 continue; 35 } else if ("permission".equals(name)) { 36 String perm = parser.getAttributeValue(null, "name"); 37 if (perm == null) { 38 Log.w(TAG, "<permission> without name at " 39 + parser.getPositionDescription()); 40 XmlUtils.skipCurrentTag(parser); 41 continue; 42 } 43 perm = perm.intern(); 44 readPermission(parser, perm); 45 46 } else if ("assign-permission".equals(name)) { 47 String perm = parser.getAttributeValue(null, "name"); 48 if (perm == null) { 49 Log.w(TAG, "<assign-permission> without name at " 50 + parser.getPositionDescription()); 51 XmlUtils.skipCurrentTag(parser); 52 continue; 53 } 54 String uidStr = parser.getAttributeValue(null, "uid"); 55 if (uidStr == null) { 56 Log.w(TAG, "<assign-permission> without uid at " 57 + parser.getPositionDescription()); 58 XmlUtils.skipCurrentTag(parser); 59 continue; 60 } 61 int uid = Process.getUidForName(uidStr); 62 if (uid < 0) { 63 Log.w(TAG, "<assign-permission> with unknown uid \"" 64 + uidStr + "\" at " 65 + parser.getPositionDescription()); 66 XmlUtils.skipCurrentTag(parser); 67 continue; 68 } 69 perm = perm.intern(); 70 HashSet<String> perms = mSystemPermissions.get(uid); 71 if (perms == null) { 72 perms = new HashSet<String>(); 73 mSystemPermissions.put(uid, perms); 74 } 75 perms.add(perm); 76 XmlUtils.skipCurrentTag(parser); 77 78 } else if ("library".equals(name)) { 79 String lname = parser.getAttributeValue(null, "name"); 80 String lfile = parser.getAttributeValue(null, "file"); 81 if (lname == null) { 82 Log.w(TAG, "<library> without name at " 83 + parser.getPositionDescription()); 84 } else if (lfile == null) { 85 Log.w(TAG, "<library> without file at " 86 + parser.getPositionDescription()); 87 } else { 88 Log.i(TAG, "Got library " + lname + " in " + lfile); 89 this.mSharedLibraries.put(lname, lfile); 90 } 91 XmlUtils.skipCurrentTag(parser); 92 continue; 93 94 } else { 95 XmlUtils.skipCurrentTag(parser); 96 continue; 97 } 98 99 } 100 } catch (XmlPullParserException e) { 101 Log.w(TAG, "Got execption parsing permissions.", e); 102 } catch (IOException e) { 103 Log.w(TAG, "Got execption parsing permissions.", e); 104 } 105 }
2.2 mSettings.readLP()
1 boolean readLP() { 2 FileInputStream str = null; 3 // 如果 data/system/packages-backup.xml 文件存在,则继续 4 if (mBackupSettingsFilename.exists()) { 5 try { 6 //文件:data/system/packages-backup.xml 7 str = new FileInputStream(mBackupSettingsFilename); 8 mReadMessages.append("Reading from backup settings file\n"); 9 Log.i(TAG, "Reading from backup settings file!"); 10 } catch (java.io.IOException e) { 11 // We'll try for the normal settings file. 12 } 13 } 14 15 // 清除 mPastSignatures 列表 16 mPastSignatures.clear(); 17 18 try { 19 // 如果 "data/system/packages-backup.xml" 文件不存在 20 if (str == null) { 21 // 如果 data/system/packages.xml 也不存在 22 if (!mSettingsFilename.exists()) { 23 mReadMessages.append("No settings file found\n"); 24 Log.i(TAG, "No current settings file!"); 25 return false; // 直接返回了 26 } 27 // 如果存在,则创建 data/system/packages.xml 文件流 28 str = new FileInputStream(mSettingsFilename); 29 } 30 //若packages-backup.xml存在,则解析,否则 解析 packages.xml 文件 31 XmlPullParser parser = Xml.newPullParser(); 32 parser.setInput(str, null); 33 34 int type; 35 while ((type=parser.next()) != XmlPullParser.START_TAG 36 && type != XmlPullParser.END_DOCUMENT) { 37 ; 38 } 39 40 if (type != XmlPullParser.START_TAG) { 41 mReadMessages.append("No start tag found in settings file\n"); 42 Log.e(TAG, "No start tag found in package manager settings"); 43 return false; 44 } 45 46 int outerDepth = parser.getDepth(); 47 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 48 && (type != XmlPullParser.END_TAG 49 || parser.getDepth() > outerDepth)) { 50 if (type == XmlPullParser.END_TAG 51 || type == XmlPullParser.TEXT) { 52 continue; 53 } 54 55 String tagName = parser.getName(); 56 // 解析 packages.xml 文件中的 "package" 57 if (tagName.equals("package")) { 58 readPackageLP(parser); //解析 package 标签 59 } else if (tagName.equals("permissions")) { //解析 permissions 标签 60 readPermissionsLP(mPermissions, parser); 61 } else if (tagName.equals("permission-trees")) { 62 readPermissionsLP(mPermissionTrees, parser); 63 } else if (tagName.equals("shared-user")) { // 解析 shared-user 标签 64 readSharedUserLP(parser); 65 } else if (tagName.equals("preferred-packages")) { 66 readPreferredPackagesLP(parser); 67 } else if (tagName.equals("preferred-activities")) { 68 readPreferredActivitiesLP(parser); 69 } else if(tagName.equals("updated-package")) { //解析 updated-package 标签 70 readDisabledSysPackageLP(parser); 71 } else { 72 Log.w(TAG, "Unknown element under <packages>: " 73 + parser.getName()); 74 XmlUtils.skipCurrentTag(parser); 75 } 76 } 77 78 str.close(); 79 80 } catch(XmlPullParserException e) { 81 mReadMessages.append("Error reading: " + e.toString()); 82 Log.e(TAG, "Error reading package manager settings", e); 83 84 } catch(java.io.IOException e) { 85 mReadMessages.append("Error reading: " + e.toString()); 86 Log.e(TAG, "Error reading package manager settings", e); 87 88 } 89 90 int N = mPendingPackages.size(); 91 for (int i=0; i<N; i++) { 92 final PendingPackage pp = mPendingPackages.get(i); 93 Object idObj = getUserIdLP(pp.sharedId); 94 if (idObj != null && idObj instanceof SharedUserSetting) { 95 PackageSetting p = getPackageLP(pp.name, 96 (SharedUserSetting)idObj, pp.codePath, pp.resourcePath, 97 pp.versionCode, pp.pkgFlags, true, true); 98 if (p == null) { 99 Log.w(TAG, "Unable to create application package for " 100 + pp.name); 101 continue; 102 } 103 p.copyFrom(pp); 104 } else if (idObj != null) { 105 String msg = "Bad package setting: package " + pp.name 106 + " has shared uid " + pp.sharedId 107 + " that is not a shared uid\n"; 108 mReadMessages.append(msg); 109 Log.e(TAG, msg); 110 } else { 111 String msg = "Bad package setting: package " + pp.name 112 + " has shared uid " + pp.sharedId 113 + " that is not defined\n"; 114 mReadMessages.append(msg); 115 Log.e(TAG, msg); 116 } 117 } 118 mPendingPackages.clear(); 119 120 N = mPendingPreferredPackages.size(); 121 mPreferredPackages.clear(); 122 for (int i=0; i<N; i++) { 123 final String name = mPendingPreferredPackages.get(i); 124 final PackageSetting p = mPackages.get(name); 125 if (p != null) { 126 mPreferredPackages.add(p); 127 } else { 128 Log.w(TAG, "Unknown preferred package: " + name); 129 } 130 } 131 mPendingPreferredPackages.clear(); 132 133 mReadMessages.append("Read completed successfully: " 134 + mPackages.size() + " packages, " 135 + mSharedUsers.size() + " shared uids\n"); 136 137 return true; 138 }
2.2.1 readPackageLP
1 // 解析 data/system/packages.xml 文件中的 "package"标签 2 private void readPackageLP(XmlPullParser parser) 3 throws XmlPullParserException, IOException { 4 String name = null; 5 String idStr = null; 6 String sharedIdStr = null; 7 String codePathStr = null; 8 String resourcePathStr = null; 9 String systemStr = null; 10 String installerPackageName = null; 11 int pkgFlags = 0; 12 String timeStampStr; 13 long timeStamp = 0; 14 PackageSettingBase packageSetting = null; 15 String version = null; 16 int versionCode = 0; 17 try { 18 // name:包名 19 name = parser.getAttributeValue(null, "name"); 20 idStr = parser.getAttributeValue(null, "userId"); 21 sharedIdStr = parser.getAttributeValue(null, "sharedUserId"); 22 codePathStr = parser.getAttributeValue(null, "codePath"); 23 resourcePathStr = parser.getAttributeValue(null, "resourcePath"); 24 version = parser.getAttributeValue(null, "version"); 25 if (version != null) { 26 try { 27 versionCode = Integer.parseInt(version); 28 } catch (NumberFormatException e) { 29 } 30 } 31 systemStr = parser.getAttributeValue(null, "system"); 32 // installer的值: com.google.android.packageinstaller or com.android.vending etc. 33 installerPackageName = parser.getAttributeValue(null, "installer"); 34 if (systemStr != null) { 35 if ("true".equals(systemStr)) { 36 pkgFlags |= ApplicationInfo.FLAG_SYSTEM; 37 } 38 } else { 39 // Old settings that don't specify system... just treat 40 // them as system, good enough. 41 pkgFlags |= ApplicationInfo.FLAG_SYSTEM; 42 } 43 timeStampStr = parser.getAttributeValue(null, "ts"); // 解析时间戳 44 if (timeStampStr != null) { 45 try { 46 timeStamp = Long.parseLong(timeStampStr); 47 } catch (NumberFormatException e) { 48 } 49 } 50 if (DEBUG_SETTINGS) Log.v(TAG, "Reading package: " + name 51 + " userId=" + idStr + " sharedUserId=" + sharedIdStr); 52 int userId = idStr != null ? Integer.parseInt(idStr) : 0; 53 if (resourcePathStr == null) { 54 // 若没有 resourcePath 属性,则赋值为 codePath 属性的值 55 resourcePathStr = codePathStr; 56 } 57 if (name == null) { // 没有包名 58 reportSettingsProblem(Log.WARN, 59 "Error in package manager settings: <package> has no name at " 60 + parser.getPositionDescription()); 61 } else if (codePathStr == null) { // 没有 codePath 属性值 62 reportSettingsProblem(Log.WARN, 63 "Error in package manager settings: <package> has no codePath at " 64 + parser.getPositionDescription()); 65 } else if (userId > 0) { 66 // 有包名、有codePathStr的值,且userId大于0 67 // 根据上述解析的信息,创建 PackageSettingBase 对象 68 packageSetting = addPackageLP(name.intern(), new File(codePathStr), 69 new File(resourcePathStr), userId, versionCode, pkgFlags); 70 if (DEBUG_SETTINGS) Log.i(TAG, "Reading package " + name 71 + ": userId=" + userId + " pkg=" + packageSetting); 72 if (packageSetting == null) { 73 reportSettingsProblem(Log.ERROR, 74 "Failure adding uid " + userId 75 + " while parsing settings at " 76 + parser.getPositionDescription()); 77 } else { 78 // 设置时间戳 79 packageSetting.setTimeStamp(timeStamp, timeStampStr); 80 } 81 } else if (sharedIdStr != null) { // 存在 sharedUserId 的值 82 // 将 sharedUserId 的值赋值给 userId 83 userId = sharedIdStr != null 84 ? Integer.parseInt(sharedIdStr) : 0; 85 if (userId > 0) { 86 // 存在 sharedUserId的值 ,且 sharedUserId 大于0,创建 PendingPackage 对象 87 packageSetting = new PendingPackage(name.intern(), new File(codePathStr), 88 new File(resourcePathStr), userId, versionCode, pkgFlags); 89 packageSetting.setTimeStamp(timeStamp, timeStampStr); 90 // mPendingPackages 装入的是 存在 sharedUserId 值的 package 标签 91 mPendingPackages.add((PendingPackage) packageSetting); 92 if (DEBUG_SETTINGS) Log.i(TAG, "Reading package " + name 93 + ": sharedUserId=" + userId + " pkg=" 94 + packageSetting); 95 } else { // sharedUserId 小于0,报告错误 96 reportSettingsProblem(Log.WARN, 97 "Error in package manager settings: package " 98 + name + " has bad sharedId " + sharedIdStr 99 + " at " + parser.getPositionDescription()); 100 } 101 } else { // userId 的值不符合,报告错误 102 reportSettingsProblem(Log.WARN, 103 "Error in package manager settings: package " 104 + name + " has bad userId " + idStr + " at " 105 + parser.getPositionDescription()); 106 } 107 } catch (NumberFormatException e) { 108 reportSettingsProblem(Log.WARN, 109 "Error in package manager settings: package " 110 + name + " has bad userId " + idStr + " at " 111 + parser.getPositionDescription()); 112 } 113 if (packageSetting != null) { // 针对存在userId 或 sharedUserId 属性的 package标签 114 packageSetting.installerPackageName = installerPackageName; 115 final String enabledStr = parser.getAttributeValue(null, "enabled"); 116 if (enabledStr != null) { // 有 enabled 属性值 117 if (enabledStr.equalsIgnoreCase("true")) { 118 packageSetting.enabled = COMPONENT_ENABLED_STATE_ENABLED; 119 } else if (enabledStr.equalsIgnoreCase("false")) { 120 packageSetting.enabled = COMPONENT_ENABLED_STATE_DISABLED; 121 } else if (enabledStr.equalsIgnoreCase("default")) { 122 packageSetting.enabled = COMPONENT_ENABLED_STATE_DEFAULT; 123 } else { 124 reportSettingsProblem(Log.WARN, 125 "Error in package manager settings: package " 126 + name + " has bad enabled value: " + idStr 127 + " at " + parser.getPositionDescription()); 128 } 129 } else { // 无 enabled 属性 130 packageSetting.enabled = COMPONENT_ENABLED_STATE_DEFAULT; 131 } 132 final String installStatusStr = parser.getAttributeValue(null, "installStatus"); 133 if (installStatusStr != null) { // 有 installStatus 属性值 134 if (installStatusStr.equalsIgnoreCase("false")) { 135 packageSetting.installStatus = PKG_INSTALL_INCOMPLETE; 136 } else { 137 packageSetting.installStatus = PKG_INSTALL_COMPLETE; 138 } 139 } 140 141 int outerDepth = parser.getDepth(); 142 int type; 143 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 144 && (type != XmlPullParser.END_TAG 145 || parser.getDepth() > outerDepth)) { 146 if (type == XmlPullParser.END_TAG 147 || type == XmlPullParser.TEXT) { 148 continue; 149 } 150 151 String tagName = parser.getName(); 152 // 解析 package 标签下 的子标签 153 if (tagName.equals("disabled-components")) { // 解析子标签 disabled-components 154 readDisabledComponentsLP(packageSetting, parser); 155 } else if (tagName.equals("enabled-components")) { 156 readEnabledComponentsLP(packageSetting, parser); // 解析子标签 enabled-components 157 } else if (tagName.equals("sigs")) { // 解析子标签 sigs 158 packageSetting.signatures.readXml(parser, mPastSignatures); 159 } else if (tagName.equals("perms")) { // 解析子标签 perms 160 // 把解析的"权限名称"装入 packageSetting.loadedPermissions 集合中 161 readGrantedPermissionsLP(parser, 162 packageSetting.loadedPermissions); 163 packageSetting.permissionsFixed = true; 164 } else { // 报告错误 165 reportSettingsProblem(Log.WARN, 166 "Unknown element under <package>: " 167 + parser.getName()); 168 XmlUtils.skipCurrentTag(parser); 169 } 170 } 171 } else { 172 XmlUtils.skipCurrentTag(parser); 173 } 174 }
2.2.1.1 readDisabledComponentsLP
1 // 解析"data/system/package.xml"文件中的 package 标签下的子标签 "disabled-components" 2 private void readDisabledComponentsLP(PackageSettingBase packageSetting, 3 XmlPullParser parser) 4 throws IOException, XmlPullParserException { 5 int outerDepth = parser.getDepth(); 6 int type; 7 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 8 && (type != XmlPullParser.END_TAG 9 || parser.getDepth() > outerDepth)) { 10 if (type == XmlPullParser.END_TAG 11 || type == XmlPullParser.TEXT) { 12 continue; 13 } 14 15 String tagName = parser.getName(); 16 if (tagName.equals("item")) { // 解析子标签"item" 17 // 获取name属性值 18 String name = parser.getAttributeValue(null, "name"); 19 if (name != null) { 20 // 装入到 disabledComponents 集合中 21 packageSetting.disabledComponents.add(name.intern()); 22 } else { 23 reportSettingsProblem(Log.WARN, 24 "Error in package manager settings: <disabled-components> has" 25 + " no name at " + parser.getPositionDescription()); 26 } 27 } else { 28 reportSettingsProblem(Log.WARN, 29 "Unknown element under <disabled-components>: " 30 + parser.getName()); 31 } 32 XmlUtils.skipCurrentTag(parser); 33 } 34 }
2.2.1.2 readEnabledComponentsLP
1 // 解析"data/system/package.xml"文件中的 package 标签下的子标签 "enabled-components" 2 private void readEnabledComponentsLP(PackageSettingBase packageSetting, 3 XmlPullParser parser) 4 throws IOException, XmlPullParserException { 5 int outerDepth = parser.getDepth(); 6 int type; 7 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 8 && (type != XmlPullParser.END_TAG 9 || parser.getDepth() > outerDepth)) { 10 if (type == XmlPullParser.END_TAG 11 || type == XmlPullParser.TEXT) { 12 continue; 13 } 14 15 String tagName = parser.getName(); 16 if (tagName.equals("item")) { 17 String name = parser.getAttributeValue(null, "name"); 18 if (name != null) { 19 packageSetting.enabledComponents.add(name.intern()); 20 } else { 21 reportSettingsProblem(Log.WARN, 22 "Error in package manager settings: <enabled-components> has" 23 + " no name at " + parser.getPositionDescription()); 24 } 25 } else { 26 reportSettingsProblem(Log.WARN, 27 "Unknown element under <enabled-components>: " 28 + parser.getName()); 29 } 30 XmlUtils.skipCurrentTag(parser); 31 } 32 }
2.2.1.3 readGrantedPermissionsLP
1 // 解析标签 "perms"的值 2 private void readGrantedPermissionsLP(XmlPullParser parser, 3 HashSet<String> outPerms) throws IOException, XmlPullParserException { 4 int outerDepth = parser.getDepth(); 5 int type; 6 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 7 && (type != XmlPullParser.END_TAG 8 || parser.getDepth() > outerDepth)) { 9 if (type == XmlPullParser.END_TAG 10 || type == XmlPullParser.TEXT) { 11 continue; 12 } 13 14 String tagName = parser.getName(); 15 if (tagName.equals("item")) { // 解析子标签 item 16 // name:权限名称 17 String name = parser.getAttributeValue(null, "name"); 18 if (name != null) { 19 // 解析"权限名称"后装入 outPerms 中 20 outPerms.add(name.intern()); 21 } else { 22 reportSettingsProblem(Log.WARN, 23 "Error in package manager settings: <perms> has" 24 + " no name at " + parser.getPositionDescription()); 25 } 26 } else { 27 reportSettingsProblem(Log.WARN, 28 "Unknown element under <perms>: " 29 + parser.getName()); 30 } 31 XmlUtils.skipCurrentTag(parser); 32 } 33 }
2.2.2 readPermissionsLP
1 // 解析 data/system/packages.xml 文件中的 permissions 标签和 permission-trees 标签 2 private void readPermissionsLP(HashMap<String, BasePermission> out, 3 XmlPullParser parser) 4 throws IOException, XmlPullParserException { 5 int outerDepth = parser.getDepth(); 6 int type; 7 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 8 && (type != XmlPullParser.END_TAG 9 || parser.getDepth() > outerDepth)) { 10 if (type == XmlPullParser.END_TAG 11 || type == XmlPullParser.TEXT) { 12 continue; 13 } 14 15 String tagName = parser.getName(); 16 if (tagName.equals("item")) { 17 String name = parser.getAttributeValue(null, "name"); 18 String sourcePackage = parser.getAttributeValue(null, "package"); 19 String ptype = parser.getAttributeValue(null, "type"); 20 if (name != null && sourcePackage != null) { 21 boolean dynamic = "dynamic".equals(ptype); 22 BasePermission bp = new BasePermission(name, sourcePackage, 23 dynamic 24 ? BasePermission.TYPE_DYNAMIC 25 : BasePermission.TYPE_NORMAL); 26 if (dynamic) { 27 PermissionInfo pi = new PermissionInfo(); 28 pi.packageName = sourcePackage.intern(); 29 pi.name = name.intern(); 30 pi.icon = readInt(parser, null, "icon", 0); 31 pi.nonLocalizedLabel = parser.getAttributeValue( 32 null, "label"); 33 pi.protectionLevel = readInt(parser, null, "protection", 34 PermissionInfo.PROTECTION_NORMAL); 35 bp.pendingInfo = pi; 36 } 37 out.put(bp.name, bp); 38 } else { 39 reportSettingsProblem(Log.WARN, 40 "Error in package manager settings: permissions has" 41 + " no name at " + parser.getPositionDescription()); 42 } 43 } else { 44 reportSettingsProblem(Log.WARN, 45 "Unknown element reading permissions: " 46 + parser.getName() + " at " 47 + parser.getPositionDescription()); 48 } 49 XmlUtils.skipCurrentTag(parser); 50 } 51 }
2.2.3 readSharedUserLP
1 // 解析"data/system/package.xml"文件中的 shared-user 标签 2 private void readSharedUserLP(XmlPullParser parser) 3 throws XmlPullParserException, IOException { 4 String name = null; 5 String idStr = null; 6 int pkgFlags = 0; 7 SharedUserSetting su = null; 8 try { 9 name = parser.getAttributeValue(null, "name");// 解析name属性值 10 idStr = parser.getAttributeValue(null, "userId");// 解析 userId 属性值 11 int userId = idStr != null ? Integer.parseInt(idStr) : 0; 12 if ("true".equals(parser.getAttributeValue(null, "system"))) { 13 pkgFlags |= ApplicationInfo.FLAG_SYSTEM; 14 } 15 if (name == null) { 16 reportSettingsProblem(Log.WARN, 17 "Error in package manager settings: <shared-user> has no name at " 18 + parser.getPositionDescription()); 19 } else if (userId == 0) { 20 reportSettingsProblem(Log.WARN, 21 "Error in package manager settings: shared-user " 22 + name + " has bad userId " + idStr + " at " 23 + parser.getPositionDescription()); 24 } else { 25 if ((su=addSharedUserLP(name.intern(), userId, pkgFlags)) == null) { 26 reportSettingsProblem(Log.ERROR, 27 "Occurred while parsing settings at " 28 + parser.getPositionDescription()); 29 } 30 } 31 } catch (NumberFormatException e) { 32 reportSettingsProblem(Log.WARN, 33 "Error in package manager settings: package " 34 + name + " has bad userId " + idStr + " at " 35 + parser.getPositionDescription()); 36 }; 37 38 if (su != null) { 39 int outerDepth = parser.getDepth(); 40 int type; 41 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 42 && (type != XmlPullParser.END_TAG 43 || parser.getDepth() > outerDepth)) { 44 if (type == XmlPullParser.END_TAG 45 || type == XmlPullParser.TEXT) { 46 continue; 47 } 48 49 String tagName = parser.getName(); 50 if (tagName.equals("sigs")) { // 解析 sigs 子标签 51 su.signatures.readXml(parser, mPastSignatures); 52 } else if (tagName.equals("perms")) { // 解析 perms 标签 53 readGrantedPermissionsLP(parser, su.loadedPermissions); 54 } else { 55 reportSettingsProblem(Log.WARN, 56 "Unknown element under <shared-user>: " 57 + parser.getName()); 58 XmlUtils.skipCurrentTag(parser); 59 } 60 } 61 62 } else { 63 XmlUtils.skipCurrentTag(parser); 64 } 65 }
2.2.4 readDisabledSysPackageLP
1 // 解析 packages.xml 文件中的 updated-package 标签值 2 private void readDisabledSysPackageLP(XmlPullParser parser) 3 throws XmlPullParserException, IOException { 4 String name = parser.getAttributeValue(null, "name"); 5 String codePathStr = parser.getAttributeValue(null, "codePath"); 6 String resourcePathStr = parser.getAttributeValue(null, "resourcePath"); 7 // 如果 resourcePathStr 没有值 8 if(resourcePathStr == null) { 9 // 则赋值为 codePath的值 10 resourcePathStr = codePathStr; 11 } 12 String version = parser.getAttributeValue(null, "version"); 13 int versionCode = 0; 14 // 如果有 version 的值 15 if (version != null) { 16 try { 17 // 则解析version的值 18 versionCode = Integer.parseInt(version); 19 } catch (NumberFormatException e) { 20 } 21 } 22 23 int pkgFlags = 0; 24 pkgFlags |= ApplicationInfo.FLAG_SYSTEM; 25 // 根据上述 解析的信息,创建 PackageSetting 对象 26 // name:包名 27 // codePathStr:com.google.android.gms 28 PackageSetting ps = new PackageSetting(name, 29 new File(codePathStr), 30 new File(resourcePathStr), versionCode, pkgFlags); 31 String timeStampStr = parser.getAttributeValue(null, "ts"); 32 if (timeStampStr != null) { 33 try { 34 // 如果有时间戳信息,则解析时间戳 35 long timeStamp = Long.parseLong(timeStampStr); 36 // 设置时间戳 37 ps.setTimeStamp(timeStamp, timeStampStr); 38 } catch (NumberFormatException e) { 39 } 40 } 41 // 解析 userId的值 42 String idStr = parser.getAttributeValue(null, "userId"); 43 ps.userId = idStr != null ? Integer.parseInt(idStr) : 0; // 设置 userId 44 if(ps.userId <= 0) { 45 // 如果 userId 小于0,则取值于 sharedUserId 的值 46 String sharedIdStr = parser.getAttributeValue(null, "sharedUserId"); 47 ps.userId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0; 48 } 49 int outerDepth = parser.getDepth(); 50 int type; 51 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 52 && (type != XmlPullParser.END_TAG 53 || parser.getDepth() > outerDepth)) { 54 if (type == XmlPullParser.END_TAG 55 || type == XmlPullParser.TEXT) { 56 continue; 57 } 58 59 String tagName = parser.getName(); 60 // 解析 updated-package 标签内的子标签"perms" 61 if (tagName.equals("perms")) { 62 // ps.grantedPermissions 内装入的是子标签"perms"中声明的"权限名称" 63 readGrantedPermissionsLP(parser, 64 ps.grantedPermissions); 65 } else { 66 reportSettingsProblem(Log.WARN, 67 "Unknown element under <updated-package>: " 68 + parser.getName()); 69 XmlUtils.skipCurrentTag(parser); 70 } 71 } 72 // name:包名,根据包名转入 PackageSetting对象 73 mDisabledSysPackages.put(name, ps); 74 }
2.3 scanDirLI
1 // 扫描:system/app目录、system/framework目录、data/app目录、data/app-private目录 2 private void scanDirLI(File dir, int flags, int scanMode) { 3 Log.d(TAG, "Scanning app dir " + dir); 4 5 String[] files = dir.list(); 6 7 int i; 8 for (i=0; i<files.length; i++) { 9 File file = new File(dir, files[i]); 10 File resFile = file; 11 // Pick up the resource path from settings for fwd locked apps 12 if ((scanMode & SCAN_FORWARD_LOCKED) != 0) { // data/app-private目录 ? 13 resFile = null; 14 } 15 // 第1个参数、第2个参数和第3个参数,大多时候同一个值 16 PackageParser.Package pkg = scanPackageLI(file, file, resFile, 17 flags|PackageParser.PARSE_MUST_BE_APK, scanMode); 18 } 19 }
2.3.1 scanPackageLI
1 /* 2 * Scan a package and return the newly parsed package. 3 * Returns null in case of errors and the error code is stored in mLastScanError 4 */ 5 private PackageParser.Package scanPackageLI(File scanFile, 6 File destCodeFile, File destResourceFile, int parseFlags, 7 int scanMode) { 8 mLastScanError = PackageManager.INSTALL_SUCCEEDED; 9 parseFlags |= mDefParseFlags; 10 PackageParser pp = new PackageParser(scanFile.getPath()); 11 pp.setSeparateProcesses(mSeparateProcesses); 12 pp.setSdkVersion(mSdkVersion, mSdkCodename); 13 // 解析包,主要是解析 AndroidManifest.xml 文件 14 final PackageParser.Package pkg = pp.parsePackage(scanFile, 15 destCodeFile.getAbsolutePath(), mMetrics, parseFlags); 16 if (pkg == null) { // 解析异常,直接返回 17 mLastScanError = pp.getParseError(); 18 return null; 19 } 20 PackageSetting ps; 21 PackageSetting updatedPkg; 22 synchronized (mPackages) { 23 ps = mSettings.peekPackageLP(pkg.packageName); 24 updatedPkg = mSettings.mDisabledSysPackages.get(pkg.packageName); 25 } 26 ///// 首先验证APK签名信息,如果验证出现问题,则直接返回 27 // Verify certificates first 28 if (!collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags)) { 29 Log.i(TAG, "Failed verifying certificates for package:" + pkg.packageName); 30 return null; 31 } 32 if (updatedPkg != null) { 33 // An updated system app will not have the PARSE_IS_SYSTEM flag set initially 34 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 35 } 36 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 37 // Check for updated system applications here 38 if (updatedPkg != null) { 39 if ((ps != null) && (!ps.codePath.getPath().equals(scanFile.getPath()))) { 40 if (pkg.mVersionCode <= ps.versionCode) { // 版本号对比:和 mSettings 集合中搜索出来的包进行对比 41 // The system package has been updated and the code path does not match 42 // Ignore entry. Just return 43 Log.w(TAG, "Package:" + pkg.packageName + 44 " has been updated. Ignoring the one from path:"+scanFile); 45 mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; 46 return null; 47 } else { 48 // Delete the older apk pointed to by ps 49 // At this point, its safely assumed that package installation for 50 // apps in system partition will go through. If not there won't be a working 51 // version of the app 52 synchronized (mPackages) { 53 // Just remove the loaded entries from package lists. 54 mPackages.remove(ps.name); 55 } 56 // 删除资源包 57 deletePackageResourcesLI(ps.name, ps.codePathString, ps.resourcePathString); 58 mSettings.enableSystemPackageLP(ps.name); 59 } 60 } 61 } 62 } 63 // The apk is forward locked (not public) if its code and resources 64 // are kept in different files. 65 if (ps != null && !ps.codePath.equals(ps.resourcePath)) { // code 路径和 resourcePath 路径保存位置不同 66 scanMode |= SCAN_FORWARD_LOCKED; 67 } 68 File resFile = destResourceFile; 69 if ((scanMode & SCAN_FORWARD_LOCKED) != 0) { 70 resFile = getFwdLockedResource(ps.name); 71 } 72 // Note that we invoke the following method only if we are about to unpack an application 73 return scanPackageLI(scanFile, destCodeFile, resFile, 74 pkg, parseFlags, scanMode | SCAN_UPDATE_SIGNATURE); 75 }
# PackageParser.java
2.3.1.1 parsePackage
1 public Package parsePackage(File sourceFile, String destFileName, 2 DisplayMetrics metrics, int flags) { 3 // 默认值:安装成功 4 mParseError = PackageManager.INSTALL_SUCCEEDED; 5 6 // 拿到文件路径 7 mArchiveSourcePath = sourceFile.getPath(); 8 if (!sourceFile.isFile()) {// 过滤出目录 9 Log.w(TAG, "Skipping dir: " + mArchiveSourcePath); 10 mParseError = PackageManager.INSTALL_PARSE_FAILED_NOT_APK; 11 return null; 12 } 13 // 判断是否是APK文件,如果不是apk文件,则直接返回 14 if (!isPackageFilename(sourceFile.getName()) 15 && (flags&PARSE_MUST_BE_APK) != 0) { 16 if ((flags&PARSE_IS_SYSTEM) == 0) { 17 // We expect to have non-.apk files in the system dir, 18 // so don't warn about them. 19 Log.w(TAG, "Skipping non-package file: " + mArchiveSourcePath); 20 } 21 mParseError = PackageManager.INSTALL_PARSE_FAILED_NOT_APK; 22 return null; 23 } 24 25 if ((flags&PARSE_CHATTY) != 0 && Config.LOGD) Log.d( 26 TAG, "Scanning package: " + mArchiveSourcePath); 27 28 XmlResourceParser parser = null; 29 AssetManager assmgr = null; 30 boolean assetError = true; 31 try { 32 assmgr = new AssetManager(); 33 // 将apk文件加入装入 34 int cookie = assmgr.addAssetPath(mArchiveSourcePath); 35 if(cookie != 0) {// 文件装入OK 36 parser = assmgr.openXmlResourceParser(cookie, "AndroidManifest.xml");// 打开 AndroidManifest.xml 文件 37 assetError = false; 38 } else { 39 Log.w(TAG, "Failed adding asset path:"+mArchiveSourcePath); 40 } 41 } catch (Exception e) { 42 Log.w(TAG, "Unable to read AndroidManifest.xml of " 43 + mArchiveSourcePath, e); 44 } 45 if(assetError) { // 打开 AndroidManifest.xml 出现错误,直接返回 46 if (assmgr != null) assmgr.close(); 47 mParseError = PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST; 48 return null; 49 } 50 String[] errorText = new String[1]; 51 Package pkg = null; 52 Exception errorException = null; 53 try { 54 // XXXX todo: need to figure out correct configuration. 55 Resources res = new Resources(assmgr, metrics, null); 56 ////////// 解析 AndroidManifest.xml 文件 57 pkg = parsePackage(res, parser, flags, errorText); 58 } catch (Exception e) { 59 errorException = e; 60 mParseError = PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION; 61 } 62 63 64 // 解析包出错,释放资源,直接返回 65 if (pkg == null) { 66 if (errorException != null) { 67 Log.w(TAG, mArchiveSourcePath, errorException); 68 } else { 69 Log.w(TAG, mArchiveSourcePath + " (at " 70 + parser.getPositionDescription() 71 + "): " + errorText[0]); 72 } 73 parser.close(); 74 assmgr.close(); 75 if (mParseError == PackageManager.INSTALL_SUCCEEDED) { 76 mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED; 77 } 78 return null; 79 } 80 81 parser.close(); 82 assmgr.close(); 83 84 // 赋值 sourceDir 和 publicSourceDir 85 pkg.applicationInfo.sourceDir = destFileName; 86 pkg.applicationInfo.publicSourceDir = destFileName; 87 pkg.mSignatures = null; 88 89 return pkg; 90 }
2.3.1.1.1 parsePackage
1 // 解析 AndroidManifest.xml 文件 2 private Package parsePackage( 3 Resources res, XmlResourceParser parser, int flags, String[] outError) 4 throws XmlPullParserException, IOException { 5 AttributeSet attrs = parser; 6 7 mParseInstrumentationArgs = null; 8 mParseActivityArgs = null; 9 mParseServiceArgs = null; 10 mParseProviderArgs = null; 11 12 // 从 AndroidManifest.xml 文件中解析包名 13 String pkgName = parsePackageName(parser, attrs, flags, outError); 14 if (pkgName == null) { // 没有拿到包名 15 mParseError = PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME; 16 return null; 17 } 18 int type; 19 20 // 根据 “包名” 新建 Package 对象 21 final Package pkg = new Package(pkgName); 22 boolean foundApp = false; 23 24 TypedArray sa = res.obtainAttributes(attrs, 25 com.android.internal.R.styleable.AndroidManifest); 26 // 获取 versionCode 属性值 27 pkg.mVersionCode = sa.getInteger( 28 com.android.internal.R.styleable.AndroidManifest_versionCode, 0); 29 // 获取 versionName 属性值 30 pkg.mVersionName = sa.getNonResourceString( 31 com.android.internal.R.styleable.AndroidManifest_versionName); 32 if (pkg.mVersionName != null) { 33 pkg.mVersionName = pkg.mVersionName.intern(); 34 } 35 // 获取 sharedUserId 属性值 36 String str = sa.getNonResourceString( 37 com.android.internal.R.styleable.AndroidManifest_sharedUserId); 38 if (str != null) {// 如果存在 sharedUserId 属性值 39 String nameError = validateName(str, true); 40 if (nameError != null && !"android".equals(pkgName)) { 41 outError[0] = "<manifest> specifies bad sharedUserId name \"" 42 + str + "\": " + nameError; 43 mParseError = PackageManager.INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID; 44 return null; 45 } 46 // 将 sharedUserId 的值赋值给 Package 对象 47 pkg.mSharedUserId = str.intern(); 48 // 获取 sharedUserLabel 属性值 49 pkg.mSharedUserLabel = sa.getResourceId( 50 com.android.internal.R.styleable.AndroidManifest_sharedUserLabel, 0); 51 } 52 sa.recycle(); // TypedArray资源回收 53 54 // Resource boolean are -1, so 1 means we don't know the value. 55 int supportsSmallScreens = 1; 56 int supportsNormalScreens = 1; 57 int supportsLargeScreens = 1; 58 int resizeable = 1; 59 int anyDensity = 1; 60 61 int outerDepth = parser.getDepth(); 62 while ((type=parser.next()) != parser.END_DOCUMENT 63 && (type != parser.END_TAG || parser.getDepth() > outerDepth)) { 64 if (type == parser.END_TAG || type == parser.TEXT) { 65 continue; 66 } 67 68 String tagName = parser.getName(); 69 // 从 AndroidManifest.xml 文件中解析 application 标签 70 if (tagName.equals("application")) { 71 if (foundApp) { 72 if (RIGID_PARSER) { 73 outError[0] = "<manifest> has more than one <application>"; 74 mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED; 75 return null; 76 } else { 77 Log.w(TAG, "<manifest> has more than one <application>"); 78 XmlUtils.skipCurrentTag(parser); 79 continue; 80 } 81 } 82 83 foundApp = true; 84 // 解析 application 标签 85 if (!parseApplication(pkg, res, parser, attrs, flags, outError)) { 86 return null; 87 } 88 // 解析 permission-group 标签 89 } else if (tagName.equals("permission-group")) { 90 if (parsePermissionGroup(pkg, res, parser, attrs, outError) == null) { 91 return null; 92 } 93 // 解析 permission 标签 94 } else if (tagName.equals("permission")) { 95 if (parsePermission(pkg, res, parser, attrs, outError) == null) { 96 return null; 97 } 98 // 解析 permission-tree 标签 99 } else if (tagName.equals("permission-tree")) { 100 if (parsePermissionTree(pkg, res, parser, attrs, outError) == null) { 101 return null; 102 } 103 // 解析 uses-permission 标签 104 } else if (tagName.equals("uses-permission")) { 105 sa = res.obtainAttributes(attrs, 106 com.android.internal.R.styleable.AndroidManifestUsesPermission); 107 108 String name = sa.getNonResourceString( 109 com.android.internal.R.styleable.AndroidManifestUsesPermission_name); 110 111 sa.recycle(); 112 113 if (name != null && !pkg.requestedPermissions.contains(name)) { 114 pkg.requestedPermissions.add(name.intern()); 115 } 116 117 XmlUtils.skipCurrentTag(parser); 118 119 // 解析 uses-configuration 标签 120 } else if (tagName.equals("uses-configuration")) { 121 ConfigurationInfo cPref = new ConfigurationInfo(); 122 sa = res.obtainAttributes(attrs, 123 com.android.internal.R.styleable.AndroidManifestUsesConfiguration); 124 cPref.reqTouchScreen = sa.getInt( 125 com.android.internal.R.styleable.AndroidManifestUsesConfiguration_reqTouchScreen, 126 Configuration.TOUCHSCREEN_UNDEFINED); 127 cPref.reqKeyboardType = sa.getInt( 128 com.android.internal.R.styleable.AndroidManifestUsesConfiguration_reqKeyboardType, 129 Configuration.KEYBOARD_UNDEFINED); 130 if (sa.getBoolean( 131 com.android.internal.R.styleable.AndroidManifestUsesConfiguration_reqHardKeyboard, 132 false)) { 133 cPref.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 134 } 135 cPref.reqNavigation = sa.getInt( 136 com.android.internal.R.styleable.AndroidManifestUsesConfiguration_reqNavigation, 137 Configuration.NAVIGATION_UNDEFINED); 138 if (sa.getBoolean( 139 com.android.internal.R.styleable.AndroidManifestUsesConfiguration_reqFiveWayNav, 140 false)) { 141 cPref.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 142 } 143 sa.recycle(); 144 pkg.configPreferences.add(cPref); 145 146 XmlUtils.skipCurrentTag(parser); 147 // 解析 uses-feature 标签 148 } else if (tagName.equals("uses-feature")) { 149 ConfigurationInfo cPref = new ConfigurationInfo(); 150 sa = res.obtainAttributes(attrs, 151 com.android.internal.R.styleable.AndroidManifestUsesFeature); 152 cPref.reqGlEsVersion = sa.getInt( 153 com.android.internal.R.styleable.AndroidManifestUsesFeature_glEsVersion, 154 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 155 sa.recycle(); 156 pkg.configPreferences.add(cPref); 157 158 XmlUtils.skipCurrentTag(parser); 159 160 // 解析 uses-sdk 标签 161 } else if (tagName.equals("uses-sdk")) { 162 if (mSdkVersion > 0) { 163 sa = res.obtainAttributes(attrs, 164 com.android.internal.R.styleable.AndroidManifestUsesSdk); 165 166 int minVers = 0; 167 String minCode = null; 168 int targetVers = 0; 169 String targetCode = null; 170 171 // 解析 minSdkVersion 属性值 172 TypedValue val = sa.peekValue( 173 com.android.internal.R.styleable.AndroidManifestUsesSdk_minSdkVersion); 174 if (val != null) { // 数值和字串区别 175 if (val.type == TypedValue.TYPE_STRING && val.string != null) { 176 targetCode = minCode = val.string.toString(); 177 } else { 178 // If it's not a string, it's an integer. 179 targetVers = minVers = val.data; 180 } 181 } 182 183 // 解析 targetSdkVersion 属性 184 val = sa.peekValue( 185 com.android.internal.R.styleable.AndroidManifestUsesSdk_targetSdkVersion); 186 if (val != null) { // 数值和字串区别 187 if (val.type == TypedValue.TYPE_STRING && val.string != null) { 188 targetCode = minCode = val.string.toString(); 189 } else { 190 // If it's not a string, it's an integer. 191 targetVers = val.data; 192 } 193 } 194 195 // 解析 maxSdkVersion 属性 196 int maxVers = sa.getInt( 197 com.android.internal.R.styleable.AndroidManifestUsesSdk_maxSdkVersion, 198 mSdkVersion); 199 200 sa.recycle(); 201 202 if (minCode != null) { 203 if (!minCode.equals(mSdkCodename)) { 204 if (mSdkCodename != null) { 205 outError[0] = "Requires development platform " + minCode 206 + " (current platform is " + mSdkCodename + ")"; 207 } else { 208 outError[0] = "Requires development platform " + minCode 209 + " but this is a release platform."; 210 } 211 mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK; 212 return null; 213 } 214 } else if (minVers > mSdkVersion) { 215 outError[0] = "Requires newer sdk version #" + minVers 216 + " (current version is #" + mSdkVersion + ")"; 217 mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK; 218 return null; 219 } 220 221 if (targetCode != null) { 222 if (!targetCode.equals(mSdkCodename)) { 223 if (mSdkCodename != null) { 224 outError[0] = "Requires development platform " + targetCode 225 + " (current platform is " + mSdkCodename + ")"; 226 } else { 227 outError[0] = "Requires development platform " + targetCode 228 + " but this is a release platform."; 229 } 230 mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK; 231 return null; 232 } 233 // If the code matches, it definitely targets this SDK. 234 pkg.applicationInfo.targetSdkVersion 235 = android.os.Build.VERSION_CODES.CUR_DEVELOPMENT; 236 } else { 237 pkg.applicationInfo.targetSdkVersion = targetVers; 238 } 239 240 if (maxVers < mSdkVersion) { 241 outError[0] = "Requires older sdk version #" + maxVers 242 + " (current version is #" + mSdkVersion + ")"; 243 mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK; 244 return null; 245 } 246 } 247 248 XmlUtils.skipCurrentTag(parser); 249 250 // 解析 supports-screens 标签 251 } else if (tagName.equals("supports-screens")) { 252 sa = res.obtainAttributes(attrs, 253 com.android.internal.R.styleable.AndroidManifestSupportsScreens); 254 255 // This is a trick to get a boolean and still able to detect 256 // if a value was actually set. 257 supportsSmallScreens = sa.getInteger( 258 com.android.internal.R.styleable.AndroidManifestSupportsScreens_smallScreens, 259 supportsSmallScreens); 260 supportsNormalScreens = sa.getInteger( 261 com.android.internal.R.styleable.AndroidManifestSupportsScreens_normalScreens, 262 supportsNormalScreens); 263 supportsLargeScreens = sa.getInteger( 264 com.android.internal.R.styleable.AndroidManifestSupportsScreens_largeScreens, 265 supportsLargeScreens); 266 resizeable = sa.getInteger( 267 com.android.internal.R.styleable.AndroidManifestSupportsScreens_resizeable, 268 supportsLargeScreens); 269 anyDensity = sa.getInteger( 270 com.android.internal.R.styleable.AndroidManifestSupportsScreens_anyDensity, 271 anyDensity); 272 273 sa.recycle(); 274 275 XmlUtils.skipCurrentTag(parser); 276 // 解析protected-broadcast 标签 277 } else if (tagName.equals("protected-broadcast")) { 278 sa = res.obtainAttributes(attrs, 279 com.android.internal.R.styleable.AndroidManifestProtectedBroadcast); 280 281 String name = sa.getNonResourceString( 282 com.android.internal.R.styleable.AndroidManifestProtectedBroadcast_name); 283 284 sa.recycle(); 285 286 if (name != null && (flags&PARSE_IS_SYSTEM) != 0) { 287 if (pkg.protectedBroadcasts == null) { 288 pkg.protectedBroadcasts = new ArrayList<String>(); 289 } 290 if (!pkg.protectedBroadcasts.contains(name)) { 291 pkg.protectedBroadcasts.add(name.intern()); 292 } 293 } 294 295 XmlUtils.skipCurrentTag(parser); 296 // 解析 instrumentation 标签 297 } else if (tagName.equals("instrumentation")) { 298 if (parseInstrumentation(pkg, res, parser, attrs, outError) == null) { 299 return null; 300 } 301 // 解析 eat-comment 标签 302 } else if (tagName.equals("eat-comment")) { 303 // Just skip this tag 304 XmlUtils.skipCurrentTag(parser); 305 continue; 306 307 } else if (RIGID_PARSER) { // 打印log信息 308 outError[0] = "Bad element under <manifest>: " 309 + parser.getName(); 310 mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED; 311 return null; 312 313 } else { // 打印log信息 314 Log.w(TAG, "Bad element under <manifest>: " 315 + parser.getName()); 316 XmlUtils.skipCurrentTag(parser); 317 continue; 318 } 319 } 320 321 if (!foundApp && pkg.instrumentation.size() == 0) { // 没有发现 <application> 标签 或 <instrumentation> 标签 322 outError[0] = "<manifest> does not contain an <application> or <instrumentation>"; 323 mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_EMPTY; 324 } 325 326 final int NP = PackageParser.NEW_PERMISSIONS.length; 327 for (int ip=0; ip<NP; ip++) { 328 final PackageParser.NewPermissionInfo npi 329 = PackageParser.NEW_PERMISSIONS[ip]; 330 if (pkg.applicationInfo.targetSdkVersion >= npi.sdkVersion) { 331 break; 332 } 333 if (!pkg.requestedPermissions.contains(npi.name)) { 334 Log.i(TAG, "Impliciting adding " + npi.name + " to old pkg " 335 + pkg.packageName); 336 pkg.requestedPermissions.add(npi.name); 337 } 338 } 339 340 if (pkg.usesLibraries.size() > 0) { 341 pkg.usesLibraryFiles = new String[pkg.usesLibraries.size()]; 342 pkg.usesLibraries.toArray(pkg.usesLibraryFiles); 343 } 344 345 if (supportsSmallScreens < 0 || (supportsSmallScreens > 0 346 && pkg.applicationInfo.targetSdkVersion 347 >= android.os.Build.VERSION_CODES.DONUT)) { 348 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS; 349 } 350 if (supportsNormalScreens != 0) { 351 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS; 352 } 353 if (supportsLargeScreens < 0 || (supportsLargeScreens > 0 354 && pkg.applicationInfo.targetSdkVersion 355 >= android.os.Build.VERSION_CODES.DONUT)) { 356 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS; 357 } 358 if (resizeable < 0 || (resizeable > 0 359 && pkg.applicationInfo.targetSdkVersion 360 >= android.os.Build.VERSION_CODES.DONUT)) { 361 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS; 362 } 363 if (anyDensity < 0 || (anyDensity > 0 364 && pkg.applicationInfo.targetSdkVersion 365 >= android.os.Build.VERSION_CODES.DONUT)) { 366 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES; 367 } 368 369 return pkg; 370 }
2.3.1.2 collectCertificatesLI
1 private boolean collectCertificatesLI(PackageParser pp, PackageSetting ps, 2 PackageParser.Package pkg, File srcFile, int parseFlags) { 3 if (GET_CERTIFICATES) { 4 if (ps == null || !ps.codePath.equals(srcFile) 5 || ps.getTimeStamp() != srcFile.lastModified()) { 6 // 源文件已经改变,再次收集证书 7 Log.i(TAG, srcFile.toString() + " changed; collecting certs"); 8 // 收集证书 9 if (!pp.collectCertificates(pkg, parseFlags)) { 10 mLastScanError = pp.getParseError(); 11 return false; 12 } 13 } 14 } 15 return true; 16 }
2.3.1.3 deletePackageResourcesLI
1 private void deletePackageResourcesLI(String packageName, 2 String sourceDir, String publicSourceDir) { 3 File sourceFile = new File(sourceDir); 4 if (!sourceFile.exists()) { 5 Log.w(TAG, "Package source " + sourceDir + " does not exist."); 6 } 7 // 删除文件 8 // Delete application's code and resources 9 sourceFile.delete(); 10 final File publicSourceFile = new File(publicSourceDir); 11 if (publicSourceFile.exists()) { 12 publicSourceFile.delete(); 13 } 14 if (mInstaller != null) { 15 // 通过 mInstaller 删除dex文件 16 int retCode = mInstaller.rmdex(sourceFile.toString()); 17 if (retCode < 0) { 18 Log.w(TAG, "Couldn't remove dex file for package: " 19 + packageName + " at location " + sourceFile.toString() + ", retcode=" + retCode); 20 // we don't consider this to be a failure of the core package deletion 21 } 22 } 23 }
2.3.1.4 scanPackageLI
1 private PackageParser.Package scanPackageLI( 2 File scanFile, File destCodeFile, File destResourceFile, 3 PackageParser.Package pkg, int parseFlags, int scanMode) { 4 5 mScanningPath = scanFile; 6 if (pkg == null) { // pkg传入的是null,直接返回 7 mLastScanError = PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME; 8 return null; 9 } 10 11 final String pkgName = pkg.applicationInfo.packageName; 12 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 13 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; 14 } 15 16 if (pkgName.equals("android")) { // android包 17 synchronized (mPackages) { 18 if (mAndroidApplication != null) { // 已经解析过了,不再解析 19 Log.w(TAG, "*************************************************"); 20 Log.w(TAG, "Core android package being redefined. Skipping."); 21 Log.w(TAG, " file=" + mScanningPath); 22 Log.w(TAG, "*************************************************"); 23 mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; 24 return null; 25 } 26 27 // 第一次解析 28 // Set up information for our fall-back user intent resolution 29 // activity. 30 mPlatformPackage = pkg; // 保存平台包信息 31 pkg.mVersionCode = mSdkVersion; 32 mAndroidApplication = pkg.applicationInfo; 33 //### ResolverActivity 这个activity 赋值的地方 34 mResolveActivity.applicationInfo = mAndroidApplication; 35 mResolveActivity.name = ResolverActivity.class.getName(); 36 mResolveActivity.packageName = mAndroidApplication.packageName; 37 mResolveActivity.processName = mAndroidApplication.processName; 38 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 39 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; 40 mResolveActivity.theme = com.android.internal.R.style.Theme_Dialog_Alert; 41 mResolveActivity.exported = true; 42 mResolveActivity.enabled = true; 43 mResolveInfo.activityInfo = mResolveActivity; 44 mResolveInfo.priority = 0; 45 mResolveInfo.preferredOrder = 0; 46 mResolveInfo.match = 0; 47 // 构建 ResolverActivity 这个activity的ComponentName 48 mResolveComponentName = new ComponentName( 49 mAndroidApplication.packageName, mResolveActivity.name); 50 } 51 } 52 53 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0 && Config.LOGD) Log.d( 54 TAG, "Scanning package " + pkgName); 55 if (mPackages.containsKey(pkgName) || mSharedLibraries.containsKey(pkgName)) { 56 Log.w(TAG, "*************************************************"); 57 Log.w(TAG, "Application package " + pkgName 58 + " already installed. Skipping duplicate."); 59 Log.w(TAG, "*************************************************"); 60 mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; 61 return null; 62 } 63 64 SharedUserSetting suid = null; 65 PackageSetting pkgSetting = null; 66 67 boolean removeExisting = false; 68 69 synchronized (mPackages) { 70 // Check all shared libraries and map to their actual file path. 71 if (pkg.usesLibraryFiles != null) { 72 for (int i=0; i<pkg.usesLibraryFiles.length; i++) { 73 String file = mSharedLibraries.get(pkg.usesLibraryFiles[i]); 74 if (file == null) { 75 Log.e(TAG, "Package " + pkg.packageName 76 + " requires unavailable shared library " 77 + pkg.usesLibraryFiles[i] + "; ignoring!"); 78 mLastScanError = PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY; 79 return null; 80 } 81 pkg.usesLibraryFiles[i] = file; 82 } 83 } 84 85 if (pkg.mSharedUserId != null) { 86 suid = mSettings.getSharedUserLP(pkg.mSharedUserId, 87 pkg.applicationInfo.flags, true); 88 if (suid == null) { 89 Log.w(TAG, "Creating application package " + pkgName 90 + " for shared user failed"); 91 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 92 return null; 93 } 94 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0 && Config.LOGD) { 95 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" 96 + suid.userId + "): packages=" + suid.packages); 97 } 98 } 99 100 // Just create the setting, don't add it yet. For already existing packages 101 // the PkgSetting exists already and doesn't have to be created. 102 pkgSetting = mSettings.getPackageLP(pkg, suid, destCodeFile, 103 destResourceFile, pkg.applicationInfo.flags, true, false); 104 if (pkgSetting == null) { 105 Log.w(TAG, "Creating application package " + pkgName + " failed"); 106 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 107 return null; 108 } 109 if(mSettings.mDisabledSysPackages.get(pkg.packageName) != null) { 110 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 111 } 112 113 pkg.applicationInfo.uid = pkgSetting.userId; 114 pkg.mExtras = pkgSetting; 115 116 // 校验签名 117 if (!verifySignaturesLP(pkgSetting, pkg, parseFlags, 118 (scanMode&SCAN_UPDATE_SIGNATURE) != 0)) { 119 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) == 0) { 120 mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE; 121 return null; 122 } 123 // The signature has changed, but this package is in the system 124 // image... let's recover! 125 pkgSetting.signatures.mSignatures = pkg.mSignatures; 126 // However... if this package is part of a shared user, but it 127 // doesn't match the signature of the shared user, let's fail. 128 // What this means is that you can't change the signatures 129 // associated with an overall shared user, which doesn't seem all 130 // that unreasonable. 131 if (pkgSetting.sharedUser != null) { 132 if (!pkgSetting.sharedUser.signatures.mergeSignatures( 133 pkg.mSignatures, false)) { 134 mLastScanError = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 135 return null; 136 } 137 } 138 removeExisting = true; 139 } 140 141 // Verify that this new package doesn't have any content providers 142 // that conflict with existing packages. Only do this if the 143 // package isn't already installed, since we don't want to break 144 // things that are installed. 145 if ((scanMode&SCAN_NEW_INSTALL) != 0) { // 检查 content provider 避免冲突 146 int N = pkg.providers.size(); 147 int i; 148 for (i=0; i<N; i++) { 149 PackageParser.Provider p = pkg.providers.get(i); 150 String names[] = p.info.authority.split(";"); 151 for (int j = 0; j < names.length; j++) { 152 if (mProviders.containsKey(names[j])) { 153 PackageParser.Provider other = mProviders.get(names[j]); 154 Log.w(TAG, "Can't install because provider name " + names[j] + 155 " (in package " + pkg.applicationInfo.packageName + 156 ") is already used by " 157 + ((other != null && other.component != null) 158 ? other.component.getPackageName() : "?")); 159 mLastScanError = PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER; 160 return null; 161 } 162 } 163 } 164 } 165 } 166 167 if (removeExisting) { 168 if (mInstaller != null) { 169 int ret = mInstaller.remove(pkgName); 170 if (ret != 0) { 171 String msg = "System package " + pkg.packageName 172 + " could not have data directory erased after signature change."; 173 reportSettingsProblem(Log.WARN, msg); 174 mLastScanError = PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE; 175 return null; 176 } 177 } 178 Log.w(TAG, "System package " + pkg.packageName 179 + " signature changed: existing data removed."); 180 mLastScanError = PackageManager.INSTALL_SUCCEEDED; 181 } 182 183 // 文件时间戳比对 184 long scanFileTime = scanFile.lastModified(); 185 final boolean forceDex = (scanMode&SCAN_FORCE_DEX) != 0; 186 final boolean scanFileNewer = forceDex || scanFileTime != pkgSetting.getTimeStamp(); 187 pkg.applicationInfo.processName = fixProcessName( 188 pkg.applicationInfo.packageName, 189 pkg.applicationInfo.processName, 190 pkg.applicationInfo.uid); 191 pkg.applicationInfo.publicSourceDir = destResourceFile.toString(); 192 193 File dataPath; 194 if (mPlatformPackage == pkg) { // 平台包,包名 “android” 195 // The system package is special. 196 dataPath = new File (Environment.getDataDirectory(), "system");// "系统包"是特殊的,路径:data/system 197 pkg.applicationInfo.dataDir = dataPath.getPath(); // 路径:data/system 目录 198 } else { // 普通包 199 // This is a normal package, need to make its data directory. 200 dataPath = new File(mAppDataDir, pkgName);// 普通应用数据目录:data/data/"包名" 201 if (dataPath.exists()) { 202 mOutPermissions[1] = 0; 203 FileUtils.getPermissions(dataPath.getPath(), mOutPermissions); 204 if (mOutPermissions[1] == pkg.applicationInfo.uid 205 || !Process.supportsProcesses()) { 206 pkg.applicationInfo.dataDir = dataPath.getPath(); // data/data/"包名" 207 } else { 208 boolean recovered = false; 209 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { // 如果是system app 210 // If this is a system app, we can at least delete its 211 // current data so the application will still work. 212 if (mInstaller != null) { 213 int ret = mInstaller.remove(pkgName); // 删除旧数据 214 if(ret >= 0) { 215 // Old data gone! 216 String msg = "System package " + pkg.packageName 217 + " has changed from uid: " 218 + mOutPermissions[1] + " to " 219 + pkg.applicationInfo.uid + "; old data erased"; 220 reportSettingsProblem(Log.WARN, msg); 221 recovered = true; 222 223 // 重新安装 224 // And now re-install the app. 225 ret = mInstaller.install(pkgName, pkg.applicationInfo.uid, 226 pkg.applicationInfo.uid); 227 if (ret == -1) { 228 // Ack should not happen! 229 msg = "System package " + pkg.packageName 230 + " could not have data directory re-created after delete."; 231 reportSettingsProblem(Log.WARN, msg); 232 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 233 return null; 234 } 235 } 236 } 237 if (!recovered) { 238 mHasSystemUidErrors = true; 239 } 240 } 241 if (!recovered) { 242 pkg.applicationInfo.dataDir = "/mismatched_uid/settings_" 243 + pkg.applicationInfo.uid + "/fs_" 244 + mOutPermissions[1]; 245 String msg = "Package " + pkg.packageName 246 + " has mismatched uid: " 247 + mOutPermissions[1] + " on disk, " 248 + pkg.applicationInfo.uid + " in settings"; 249 synchronized (mPackages) { 250 if (!mReportedUidError) { 251 mReportedUidError = true; 252 msg = msg + "; read messages:\n" 253 + mSettings.getReadMessagesLP(); 254 } 255 reportSettingsProblem(Log.ERROR, msg); 256 } 257 } 258 } 259 pkg.applicationInfo.dataDir = dataPath.getPath(); 260 } else { 261 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0 && Config.LOGV) 262 Log.v(TAG, "Want this data dir: " + dataPath); 263 // 调用 installer 去执行真正的安装 264 //invoke installer to do the actual installation 265 if (mInstaller != null) { 266 int ret = mInstaller.install(pkgName, pkg.applicationInfo.uid, 267 pkg.applicationInfo.uid); 268 if(ret < 0) { // 安装失败,直接返回 269 // Error from installer 270 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 271 return null; 272 } 273 } else { 274 dataPath.mkdirs(); // 创建数据目录 275 if (dataPath.exists()) { 276 // 对数据目录设置权限 277 FileUtils.setPermissions( 278 dataPath.toString(), 279 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, 280 pkg.applicationInfo.uid, pkg.applicationInfo.uid); 281 } 282 } 283 if (dataPath.exists()) { // 目录创建成功,直接赋值 284 pkg.applicationInfo.dataDir = dataPath.getPath(); 285 } else { 286 Log.w(TAG, "Unable to create data directory: " + dataPath); 287 pkg.applicationInfo.dataDir = null; 288 } 289 } 290 } 291 292 // 如果不是system app,执行共享库安装和dex优化 293 // Perform shared library installation and dex validation and 294 // optimization, if this is not a system app. 295 if (mInstaller != null) { 296 String path = scanFile.getPath(); 297 if (scanFileNewer) { 298 Log.i(TAG, path + " changed; unpacking"); // 解包 299 int err = cachePackageSharedLibsLI(pkg, dataPath, scanFile); 300 if (err != PackageManager.INSTALL_SUCCEEDED) { 301 mLastScanError = err; 302 return null; 303 } 304 } 305 306 pkg.mForwardLocked = (scanMode&SCAN_FORWARD_LOCKED) != 0; 307 pkg.mScanPath = path; 308 309 if ((scanMode&SCAN_NO_DEX) == 0) { 310 // 执行dex优化 311 if (performDexOptLI(pkg, forceDex) == DEX_OPT_FAILED) { 312 mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT; 313 return null; 314 } 315 } 316 } 317 318 // 工厂测试权限 319 if (mFactoryTest && pkg.requestedPermissions.contains( 320 android.Manifest.permission.FACTORY_TEST)) { 321 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST; 322 } 323 324 // We don't expect installation to fail beyond this point, 325 if ((scanMode&SCAN_MONITOR) != 0) { 326 pkg.mPath = destCodeFile.getAbsolutePath(); 327 mAppDirs.put(pkg.mPath, pkg); 328 } 329 330 // Request the ActivityManager to kill the process(only for existing packages) 331 // so that we do not end up in a confused state while the user is still using the older 332 // version of the application while the new one gets installed. 333 IActivityManager am = ActivityManagerNative.getDefault(); 334 if ((am != null) && ((parseFlags & PackageManager.INSTALL_REPLACE_EXISTING ) != 0)) { 335 try { 336 // 杀进程 337 am.killApplicationWithUid(pkg.applicationInfo.packageName, 338 pkg.applicationInfo.uid); 339 } catch (RemoteException e) { 340 } 341 } 342 synchronized (mPackages) { 343 // 添加到mSettings 344 // Add the new setting to mSettings 345 mSettings.insertPackageSettingLP(pkgSetting, pkg, destCodeFile, destResourceFile); 346 // Add the new setting to mPackages 347 // 添加到mPackages 348 mPackages.put(pkg.applicationInfo.packageName, pkg); 349 int N = pkg.providers.size(); 350 StringBuilder r = null; 351 int i; 352 for (i=0; i<N; i++) { 353 PackageParser.Provider p = pkg.providers.get(i); 354 p.info.processName = fixProcessName(pkg.applicationInfo.processName, 355 p.info.processName, pkg.applicationInfo.uid); 356 mProvidersByComponent.put(new ComponentName(p.info.packageName, 357 p.info.name), p); 358 p.syncable = p.info.isSyncable; 359 String names[] = p.info.authority.split(";"); 360 p.info.authority = null; 361 for (int j = 0; j < names.length; j++) { 362 if (j == 1 && p.syncable) { 363 // We only want the first authority for a provider to possibly be 364 // syncable, so if we already added this provider using a different 365 // authority clear the syncable flag. We copy the provider before 366 // changing it because the mProviders object contains a reference 367 // to a provider that we don't want to change. 368 // Only do this for the second authority since the resulting provider 369 // object can be the same for all future authorities for this provider. 370 p = new PackageParser.Provider(p); 371 p.syncable = false; 372 } 373 if (!mProviders.containsKey(names[j])) { 374 mProviders.put(names[j], p); 375 if (p.info.authority == null) { 376 p.info.authority = names[j]; 377 } else { 378 p.info.authority = p.info.authority + ";" + names[j]; 379 } 380 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0 && Config.LOGD) 381 Log.d(TAG, "Registered content provider: " + names[j] + 382 ", className = " + p.info.name + 383 ", isSyncable = " + p.info.isSyncable); 384 } else { 385 PackageParser.Provider other = mProviders.get(names[j]); 386 Log.w(TAG, "Skipping provider name " + names[j] + 387 " (in package " + pkg.applicationInfo.packageName + 388 "): name already used by " 389 + ((other != null && other.component != null) 390 ? other.component.getPackageName() : "?")); 391 } 392 } 393 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 394 if (r == null) { 395 r = new StringBuilder(256); 396 } else { 397 r.append(' '); 398 } 399 r.append(p.info.name); 400 } 401 } 402 if (r != null) { 403 if (Config.LOGD) Log.d(TAG, " Providers: " + r); 404 } 405 406 N = pkg.services.size(); 407 r = null; 408 for (i=0; i<N; i++) { 409 PackageParser.Service s = pkg.services.get(i); 410 s.info.processName = fixProcessName(pkg.applicationInfo.processName, 411 s.info.processName, pkg.applicationInfo.uid); 412 mServices.addService(s); 413 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 414 if (r == null) { 415 r = new StringBuilder(256); 416 } else { 417 r.append(' '); 418 } 419 r.append(s.info.name); 420 } 421 } 422 if (r != null) { 423 if (Config.LOGD) Log.d(TAG, " Services: " + r); 424 } 425 426 N = pkg.receivers.size(); 427 r = null; 428 for (i=0; i<N; i++) { 429 PackageParser.Activity a = pkg.receivers.get(i); 430 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 431 a.info.processName, pkg.applicationInfo.uid); 432 mReceivers.addActivity(a, "receiver"); 433 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 434 if (r == null) { 435 r = new StringBuilder(256); 436 } else { 437 r.append(' '); 438 } 439 r.append(a.info.name); 440 } 441 } 442 if (r != null) { 443 if (Config.LOGD) Log.d(TAG, " Receivers: " + r); 444 } 445 446 N = pkg.activities.size(); 447 r = null; 448 for (i=0; i<N; i++) { 449 PackageParser.Activity a = pkg.activities.get(i); 450 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 451 a.info.processName, pkg.applicationInfo.uid); 452 mActivities.addActivity(a, "activity"); 453 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 454 if (r == null) { 455 r = new StringBuilder(256); 456 } else { 457 r.append(' '); 458 } 459 r.append(a.info.name); 460 } 461 } 462 if (r != null) { 463 if (Config.LOGD) Log.d(TAG, " Activities: " + r); 464 } 465 466 N = pkg.permissionGroups.size(); 467 r = null; 468 for (i=0; i<N; i++) { 469 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i); 470 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name); 471 if (cur == null) { 472 mPermissionGroups.put(pg.info.name, pg); 473 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 474 if (r == null) { 475 r = new StringBuilder(256); 476 } else { 477 r.append(' '); 478 } 479 r.append(pg.info.name); 480 } 481 } else { 482 Log.w(TAG, "Permission group " + pg.info.name + " from package " 483 + pg.info.packageName + " ignored: original from " 484 + cur.info.packageName); 485 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 486 if (r == null) { 487 r = new StringBuilder(256); 488 } else { 489 r.append(' '); 490 } 491 r.append("DUP:"); 492 r.append(pg.info.name); 493 } 494 } 495 } 496 if (r != null) { 497 if (Config.LOGD) Log.d(TAG, " Permission Groups: " + r); 498 } 499 500 N = pkg.permissions.size(); 501 r = null; 502 for (i=0; i<N; i++) { 503 PackageParser.Permission p = pkg.permissions.get(i); 504 HashMap<String, BasePermission> permissionMap = 505 p.tree ? mSettings.mPermissionTrees 506 : mSettings.mPermissions; 507 p.group = mPermissionGroups.get(p.info.group); 508 if (p.info.group == null || p.group != null) { 509 BasePermission bp = permissionMap.get(p.info.name); 510 if (bp == null) { 511 bp = new BasePermission(p.info.name, p.info.packageName, 512 BasePermission.TYPE_NORMAL); 513 permissionMap.put(p.info.name, bp); 514 } 515 if (bp.perm == null) { 516 if (bp.sourcePackage == null 517 || bp.sourcePackage.equals(p.info.packageName)) { 518 BasePermission tree = findPermissionTreeLP(p.info.name); 519 if (tree == null 520 || tree.sourcePackage.equals(p.info.packageName)) { 521 bp.perm = p; 522 bp.uid = pkg.applicationInfo.uid; 523 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 524 if (r == null) { 525 r = new StringBuilder(256); 526 } else { 527 r.append(' '); 528 } 529 r.append(p.info.name); 530 } 531 } else { 532 Log.w(TAG, "Permission " + p.info.name + " from package " 533 + p.info.packageName + " ignored: base tree " 534 + tree.name + " is from package " 535 + tree.sourcePackage); 536 } 537 } else { 538 Log.w(TAG, "Permission " + p.info.name + " from package " 539 + p.info.packageName + " ignored: original from " 540 + bp.sourcePackage); 541 } 542 } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 543 if (r == null) { 544 r = new StringBuilder(256); 545 } else { 546 r.append(' '); 547 } 548 r.append("DUP:"); 549 r.append(p.info.name); 550 } 551 } else { 552 Log.w(TAG, "Permission " + p.info.name + " from package " 553 + p.info.packageName + " ignored: no group " 554 + p.group); 555 } 556 } 557 if (r != null) { 558 if (Config.LOGD) Log.d(TAG, " Permissions: " + r); 559 } 560 561 N = pkg.instrumentation.size(); 562 r = null; 563 for (i=0; i<N; i++) { 564 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 565 a.info.packageName = pkg.applicationInfo.packageName; 566 a.info.sourceDir = pkg.applicationInfo.sourceDir; 567 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir; 568 a.info.dataDir = pkg.applicationInfo.dataDir; 569 mInstrumentation.put(a.component, a); 570 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 571 if (r == null) { 572 r = new StringBuilder(256); 573 } else { 574 r.append(' '); 575 } 576 r.append(a.info.name); 577 } 578 } 579 if (r != null) { 580 if (Config.LOGD) Log.d(TAG, " Instrumentation: " + r); 581 } 582 583 if (pkg.protectedBroadcasts != null) { 584 N = pkg.protectedBroadcasts.size(); 585 for (i=0; i<N; i++) { 586 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i)); 587 } 588 } 589 590 pkgSetting.setTimeStamp(scanFileTime); 591 } 592 593 return pkg; 594 }