Android 1.6 PackageManagerService源码分析

文件清单

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     }

 

    原文作者:行走的思想
    原文地址: https://www.cnblogs.com/onelikeone/p/9184871.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞