Chinaunix首页 | 论坛 | 博客
  • 博客访问: 669916
  • 博文数量: 207
  • 博客积分: 1743
  • 博客等级: 上尉
  • 技术积分: 2044
  • 用 户 组: 普通用户
  • 注册时间: 2012-08-20 14:36
文章分类

全部博文(207)

文章存档

2016年(24)

2015年(10)

2014年(50)

2013年(45)

2012年(78)

分类: Android平台

2016-01-25 14:10:24

PackageManagerService也是有ServerThread启动的,运行在system_process进程。

我们先来看下PackageManagerService是怎么启动的:

PackageManagerService的启动需要四个参数,context上下文环境信息由ActivityManagerService获 取,installer是一个安装器,是对install程序的一个封装,在new一个Installer之后会调用ping命令测试是否能连接的上 install的服务端。

再来看一下PackageManagerService的初始化流程:


相关代码:

  1. public PackageManagerService(Context context, Installer installer,  
  2.             boolean factoryTest, boolean onlyCore) {  
  3.         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,  
  4.                 SystemClock.uptimeMillis());  
  5.   
  6.         if (mSdkVersion <= 0) {  
  7.             Slog.w(TAG, "**** ro.build.version.sdk not set!");  
  8.         }  
  9.   
  10.         mContext = context;  
  11.         mFactoryTest = factoryTest;  
  12.         mOnlyCore = onlyCore;  
  13.         mNoDexOpt = "eng".equals(SystemProperties.get("ro.build.type"));  
  14.         mMetrics = new DisplayMetrics();  
  15.         mSettings = new Settings(context);//新建一个Settings结构  
  16.         mSettings.addSharedUserLPw("android.uid.system"//添加一些用户id  
  17.                 Process.SYSTEM_UID, ApplicationInfo.FLAG_SYSTEM);  
  18.         mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, ApplicationInfo.FLAG_SYSTEM);  
  19.         mSettings.addSharedUserLPw("android.uid.log", LOG_UID, ApplicationInfo.FLAG_SYSTEM);  
  20.         mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, ApplicationInfo.FLAG_SYSTEM);  
  21.         mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, ApplicationInfo.FLAG_SYSTEM);  
  22.   
  23.         String separateProcesses = SystemProperties.get("debug.separate_processes");  
  24.         if (separateProcesses != null && separateProcesses.length() > 0) {  
  25.             if ("*".equals(separateProcesses)) {  
  26.                 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;  
  27.                 mSeparateProcesses = null;  
  28.                 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");  
  29.             } else {  
  30.                 mDefParseFlags = 0;  
  31.                 mSeparateProcesses = separateProcesses.split(",");  
  32.                 Slog.w(TAG, "Running with debug.separate_processes: "  
  33.                         + separateProcesses);  
  34.             }  
  35.         } else {  
  36.             mDefParseFlags = 0;  
  37.             mSeparateProcesses = null;  
  38.         }  
  39.   
  40.         mInstaller = installer;//在ServerThread中创建,调用了其中的ping测试是否连上  
  41.   
  42.         WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);//获取WINDOW_SERVICE  
  43.         Display d = wm.getDefaultDisplay();//获取显示参数  
  44.         d.getMetrics(mMetrics);  
  45.   
  46.         synchronized (mInstallLock) {  
  47.         // writer  
  48.         synchronized (mPackages) {  
  49.             mHandlerThread.start();//启动消息处理循环  
  50.             mHandler = new PackageHandler(mHandlerThread.getLooper());//PackageHandler封装了对消息的处理  
  51.   
  52.             File dataDir = Environment.getDataDirectory();///data  
  53.             mAppDataDir = new File(dataDir, "data");//待检测目录/data/data  
  54.             mAppInstallDir = new File(dataDir, "app");///data/app  
  55.             mAppLibInstallDir = new File(dataDir, "app-lib");///data/app-lib  
  56.             mAsecInternalPath = new File(dataDir, "app-asec").getPath();///data/app-asec  
  57.             mUserAppDataDir = new File(dataDir, "user");///data/user  
  58.             mDrmAppPrivateInstallDir = new File(dataDir, "app-private");///data/app-private  
  59.   
  60.             sUserManager = new UserManagerService(context, this,  
  61.                     mInstallLock, mPackages);//创建一个UserManagerService  
  62.   
  63.             readPermissions();//读取权限配置文件中的信息,保存到全局变量  
  64.   
  65.             mRestoredSettings = mSettings.readLPw(sUserManager.getUsers(false));  
  66.             long startTime = SystemClock.uptimeMillis();  
  67.   
  68.             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,  
  69.                     startTime);  
  70.   
  71.             // Set flag to monitor and not change apk file paths when  
  72.             // scanning install directories.  
  73.             int scanMode = SCAN_MONITOR | SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING;//设置扫描模式  
  74.             if (mNoDexOpt) {  
  75.                 Slog.w(TAG, "Running ENG build: no pre-dexopt!");  
  76.                 scanMode |= SCAN_NO_DEX;  
  77.             }  
  78.   
  79.             final HashSet libFiles = new HashSet();  
  80.   
  81.             mFrameworkDir = new File(Environment.getRootDirectory(), "framework");///system/framework  
  82.             mDalvikCacheDir = new File(dataDir, "dalvik-cache");///data/dalvik-cache  
  83.   
  84.             boolean didDexOpt = false;  
  85.   
  86.             /** 
  87.              * Out of paranoia, ensure that everything in the boot class 
  88.              * path has been dexed. 
  89.              */  
  90.             String bootClassPath = System.getProperty("java.boot.class.path");//所有在bootClassPath目录的类已经优化了  
  91.             if (bootClassPath != null) {//确保 boot路径的class都被优化了  
  92.                 String[] paths = splitString(bootClassPath, ':');  
  93.                 for (int i=0; i
  94.                     try {  
  95.                         if (dalvik.system.DexFile.isDexOptNeeded(paths[i])) {//需要优化?  
  96.                             libFiles.add(paths[i]);  
  97.                             mInstaller.dexopt(paths[i], Process.SYSTEM_UID, true);  
  98.                             didDexOpt = true;  
  99.                         }  
  100.                     } catch (FileNotFoundException e) {  
  101.                         Slog.w(TAG, "Boot class path not found: " + paths[i]);  
  102.                     } catch (IOException e) {  
  103.                         Slog.w(TAG, "Cannot dexopt " + paths[i] + "; is it an APK or JAR? "  
  104.                                 + e.getMessage());  
  105.                     }  
  106.                 }  
  107.             } else {  
  108.                 Slog.w(TAG, "No BOOTCLASSPATH found!");  
  109.             }  
  110.   
  111.             /** 
  112.              * Also ensure all external libraries have had dexopt run on them. 
  113.              */  
  114.             if (mSharedLibraries.size() > 0) {//确保 外部库也被 优化  
  115.                 Iterator libs = mSharedLibraries.values().iterator();  
  116.                 while (libs.hasNext()) {  
  117.                     String lib = libs.next();  
  118.                     try {  
  119.                         if (dalvik.system.DexFile.isDexOptNeeded(lib)) {  
  120.                             libFiles.add(lib);  
  121.                             mInstaller.dexopt(lib, Process.SYSTEM_UID, true);  
  122.                             didDexOpt = true;  
  123.                         }  
  124.                     } catch (FileNotFoundException e) {  
  125.                         Slog.w(TAG, "Library not found: " + lib);  
  126.                     } catch (IOException e) {  
  127.                         Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "  
  128.                                 + e.getMessage());  
  129.                     }  
  130.                 }  
  131.             }  
  132.   
  133.             // Gross hack for now: we know this file doesn't contain any  
  134.             // code, so don't dexopt it to avoid the resulting log spew.  
  135.             libFiles.add(mFrameworkDir.getPath() + "/framework-res.apk");//framework-res.apk没有包含代码,不需要优化  
  136.   
  137.             /** 
  138.              * And there are a number of commands implemented in Java, which 
  139.              * we currently need to do the dexopt on so that they can be 
  140.              * run from a non-root shell. 
  141.              */  
  142.             String[] frameworkFiles = mFrameworkDir.list();  
  143.             if (frameworkFiles != null) {  
  144.                 for (int i=0; i//优化/system/framework目录下的文件  
  145.                     File libPath = new File(mFrameworkDir, frameworkFiles[i]);  
  146.                     String path = libPath.getPath();  
  147.                     // Skip the file if we alrady did it.  
  148.                     if (libFiles.contains(path)) {//已经包含过,包含过的都优化了  
  149.                         continue;  
  150.                     }  
  151.                     // Skip the file if it is not a type we want to dexopt.  
  152.                     if (!path.endsWith(".apk") && !path.endsWith(".jar")) {//跳过不符合条件的  
  153.                         continue;  
  154.                     }  
  155.                     try {  
  156.                         if (dalvik.system.DexFile.isDexOptNeeded(path)) {//需要优化  
  157.                             mInstaller.dexopt(path, Process.SYSTEM_UID, true);  
  158.                             didDexOpt = true;  
  159.                         }  
  160.                     } catch (FileNotFoundException e) {  
  161.                         Slog.w(TAG, "Jar not found: " + path);  
  162.                     } catch (IOException e) {  
  163.                         Slog.w(TAG, "Exception reading jar: " + path, e);  
  164.                     }  
  165.                 }  
  166.             }  
  167.   
  168.             if (didDexOpt) {  
  169.                 // If we had to do a dexopt of one of the previous  
  170.                 // things, then something on the system has changed.  
  171.                 // Consider this significant, and wipe away all other  
  172.                 // existing dexopt files to ensure we don't leave any  
  173.                 // dangling around.  
  174.                 String[] files = mDalvikCacheDir.list();  
  175.                 if (files != null) {  
  176.                     for (int i=0; i
  177.                         String fn = files[i];  
  178.                         if (fn.startsWith("data@app@")  
  179.                                 || fn.startsWith("data@app-private@")) {  
  180.                             Slog.i(TAG, "Pruning dalvik file: " + fn);  
  181.                             (new File(mDalvikCacheDir, fn)).delete();  
  182.                         }  
  183.                     }  
  184.                 }  
  185.             }  
  186.   
  187.             // Find base frameworks (resource packages without code).  
  188.             mFrameworkInstallObserver = new AppDirObserver(//创建一个监察器监视/system/framework  
  189.                 mFrameworkDir.getPath(), OBSERVER_EVENTS, true);  
  190.             mFrameworkInstallObserver.startWatching();  
  191.             scanDirLI(mFrameworkDir, PackageParser.PARSE_IS_SYSTEM//扫描该目录下的所有apk,进行安装  
  192.                     | PackageParser.PARSE_IS_SYSTEM_DIR,  
  193.                     scanMode | SCAN_NO_DEX, 0);//currentTime 为 0  SCAN_NO_DEX  
  194.   
  195.             // Collect all system packages.  
  196.             mSystemAppDir = new File(Environment.getRootDirectory(), "app");  
  197.             mSystemInstallObserver = new AppDirObserver(//监视/system/app  
  198.                 mSystemAppDir.getPath(), OBSERVER_EVENTS, true);  
  199.             mSystemInstallObserver.startWatching();  
  200.             scanDirLI(mSystemAppDir, PackageParser.PARSE_IS_SYSTEM  //扫描该目录下的所有apk,进行安装  
  201.                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);  
  202.   
  203.             // Collect all vendor packages.  
  204.             mVendorAppDir = new File("/vendor/app");  
  205.             mVendorInstallObserver = new AppDirObserver(//监视/vendor/app  
  206.                 mVendorAppDir.getPath(), OBSERVER_EVENTS, true);  
  207.             mVendorInstallObserver.startWatching();  
  208.             scanDirLI(mVendorAppDir, PackageParser.PARSE_IS_SYSTEM //扫描该目录下的所有apk,进行安装  
  209.                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);  
  210.   
  211.             if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands");  
  212.             mInstaller.moveFiles();  
  213.   
  214.             // Prune any system packages that no longer exist.//去除不存在的系统packages  
  215.             final List possiblyDeletedUpdatedSystemApps = new ArrayList();  
  216.             if (!mOnlyCore) {  
  217.                 Iterator psit = mSettings.mPackages.values().iterator();  
  218.                 while (psit.hasNext()) {  
  219.                     PackageSetting ps = psit.next();  
  220.   
  221.                     /* 
  222.                      * If this is not a system app, it can't be a 
  223.                      * disable system app. 
  224.                      */  
  225.                     if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {//系统app  
  226.                         continue;  
  227.                     }  
  228.   
  229.                     /* 
  230.                      * If the package is scanned, it's not erased. 
  231.                      */  
  232.                     final PackageParser.Package scannedPkg = mPackages.get(ps.name);  
  233.                     if (scannedPkg != null) {  
  234.                         /* 
  235.                          * If the system app is both scanned and in the 
  236.                          * disabled packages list, then it must have been 
  237.                          * added via OTA. Remove it from the currently 
  238.                          * scanned package so the previously user-installed 
  239.                          * application can be scanned. 
  240.                          *///如果系统app刚被扫描并且在disabled列表,则它肯定是通过ota添加的,从当前扫描的package中移除它,所以以前用户安装的可以被扫描到  
  241.                         if (mSettings.isDisabledSystemPackageLPr(ps.name)) {  
  242.                             Slog.i(TAG, "Expecting better updatd system app for " + ps.name  
  243.                                     + "; removing system app");  
  244.                             removePackageLI(ps, true);  
  245.                         }  
  246.   
  247.                         continue;  
  248.                     }  
  249.   
  250.                     if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {  
  251.                         psit.remove();  
  252.                         String msg = "System package " + ps.name  
  253.                                 + " no longer exists; wiping its data";  
  254.                         reportSettingsProblem(Log.WARN, msg);  
  255.                         removeDataDirsLI(ps.name);  
  256.                     } else {  
  257.                         final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);  
  258.                         if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {  
  259.                             possiblyDeletedUpdatedSystemApps.add(ps.name);  
  260.                         }  
  261.                     }  
  262.                 }  
  263.             }  
  264.   
  265.             //look for any incomplete package installations未安装完全的package  
  266.             ArrayList deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();  
  267.             //clean up list  
  268.             for(int i = 0; i < deletePkgsList.size(); i++) {  
  269.                 //clean up here  
  270.                 cleanupInstallFailedPackage(deletePkgsList.get(i));//移除安装失败的package  
  271.             }  
  272.             //delete tmp files  
  273.             deleteTempPackageFiles();//移除临时文件  
  274.   
  275.             if (!mOnlyCore) {  
  276.                 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,  
  277.                         SystemClock.uptimeMillis());  
  278.                 mAppInstallObserver = new AppDirObserver(  
  279.                     mAppInstallDir.getPath(), OBSERVER_EVENTS, false);  
  280.                 mAppInstallObserver.startWatching();//监控/data/app目录  
  281.                 scanDirLI(mAppInstallDir, 0, scanMode, 0);//扫描该目录下的package  
  282.       
  283.                 mDrmAppInstallObserver = new AppDirObserver( //DRM,英文全称Digital Rights Management, 可以翻译为:内容数字版权加密保护技术  
  284.                     mDrmAppPrivateInstallDir.getPath(), OBSERVER_EVENTS, false);  
  285.                 mDrmAppInstallObserver.startWatching();//监控/data/app-private目录  
  286.                 scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,//扫描该目录下的package  
  287.                         scanMode, 0);  
  288.   
  289.                 /** 
  290.                  * Remove disable package settings for any updated system 
  291.                  * apps that were removed via an OTA. If they're not a 
  292.                  * previously-updated app, remove them completely. 
  293.                  * Otherwise, just revoke their system-level permissions. 
  294.                  */  
  295.                 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {  
  296.                     PackageParser.Package deletedPkg = mPackages.get(deletedAppName);  
  297.                     mSettings.removeDisabledSystemPackageLPw(deletedAppName);  
  298.   
  299.                     String msg;  
  300.                     if (deletedPkg == null) {  
  301.                         msg = "Updated system package " + deletedAppName  
  302.                                 + " no longer exists; wiping its data";  
  303.                         removeDataDirsLI(deletedAppName);  
  304.                     } else {  
  305.                         msg = "Updated system app + " + deletedAppName  
  306.                                 + " no longer present; removing system privileges for "  
  307.                                 + deletedAppName;  
  308.   
  309.                         deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;  
  310.   
  311.                         PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);  
  312.                         deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;  
  313.                     }  
  314.                     reportSettingsProblem(Log.WARN, msg);  
  315.                 }  
  316.             } else {  
  317.                 mAppInstallObserver = null;  
  318.                 mDrmAppInstallObserver = null;  
  319.             }  
  320.   
  321.             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,  
  322.                     SystemClock.uptimeMillis());  
  323.             Slog.i(TAG, "Time to scan packages: "  
  324.                     + ((SystemClock.uptimeMillis()-startTime)/1000f)  
  325.                     + " seconds");  
  326.   
  327.             // If the platform SDK has changed since the last time we booted,  
  328.             // we need to re-grant app permission to catch any new ones that  
  329.             // appear.  This is really a hack, and means that apps can in some  
  330.             // cases get permissions that the user didn't initially explicitly  
  331.             // allow...  it would be nice to have some better way to handle  
  332.             // this situation.  
  333.             final boolean regrantPermissions = mSettings.mInternalSdkPlatform  
  334.                     != mSdkVersion;  
  335.             if (regrantPermissions) Slog.i(TAG, "Platform changed from "  
  336.                     + mSettings.mInternalSdkPlatform + " to " + mSdkVersion  
  337.                     + "; regranting permissions for internal storage");  
  338.             mSettings.mInternalSdkPlatform = mSdkVersion;  
  339.               
  340.             updatePermissionsLPw(nullnull, UPDATE_PERMISSIONS_ALL //赋予package相应请求的权限  
  341.                     | (regrantPermissions  
  342.                             ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)  
  343.                             : 0));  
  344.   
  345.             // can downgrade to reader  
  346.             mSettings.writeLPr();//写/data/system/packages.xml  
  347.   
  348.             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,  
  349.                     SystemClock.uptimeMillis());  
  350.   
  351.             // Now after opening every single application zip, make sure they  
  352.             // are all flushed.  Not really needed, but keeps things nice and  
  353.             // tidy.  
  354.             Runtime.getRuntime().gc();  
  355.   
  356.             mRequiredVerifierPackage = getRequiredVerifierLPr();  
  357.         } // synchronized (mPackages)  
  358.         } // synchronized (mInstallLock)  
  359.     }  

PackageManagerService的初始化工作都是在它的构造函数中完成的,主要完成一下任务:

1、  添加一些用户id,如systemphone;

2、   建立并启动PackageHandler消息循环,用于处理apk安装请求如adbinstall packageinstaller安装apk时就会发送消息;

3、  解析/system/etc/permission下的xml文件,主要是platform.xml,建立permission和gid之间的关系,可以 指定一个权限与几个组对应,当一个apk被授予这个权限时它也同时属于这几个组,readPermission(parser, perm);给一些底层用户分配一些权限,如shell授予各种permission,把一个权限赋予一个uid,当apk使用这个uid运行时,就具备 了这个权限系统增加的一些应用需要link的扩展的jar库,系统每增加一个硬件,都要添加相应的featrue,将解析结果放入 mAvailableFeatures;

4、  检查/data/system/packages.xml是否存在,里面记录了系统的ppermission,以及每个apk的 name,codePath,flags,ts,version,userid等,这些信息主要是通过apk安装的时候解析 AndroidManifest.xml获取到的,解析完apk后将更新信息写入这个文件并保存到flash,下次开机直接从里面读取相关信息添加到内存 相关列表中,当有apk安装,升级,删除时会更新这个文件;

5、  检查BootClassPath,mSharedLibraries及/system/framework下的jar是否需要dexopt,需要则通过dexopt进行优化,这里面主要是调用mInstaller.dexopt进行相应的优化;

6、  建立 java 层的 installer  层的 installd  socket 联接,使得在上层的 install,remove,dexopt等功能最终由installd在底层实现;

7、  启动AppDirObserver线程往中监测/system/framework,/system/app,/data/app/data/app- private目录的事件,主要监听add和remove事件,对于目录监听底层通过innotify机制实现,inotify是一种文件系统的变化通知 机制如文件增加、删除等事件可以立刻让用户态得知,它为用户态监视文件系统的变化提供了强大的支持,当有add event时调用scanPackageLI(File,int,int)处理,当有remove event时调用removePackageLI处理;

8、  调用scanDirLI启动apk解析,解析目录包括:/system/framework、/system/app、/vendor/app、/data/app、/data/app-private;

9、  移除临时文件;

10、 赋予package相应请求的权限;

11、 将解析出的Package的相关信息保存到相关全局变量,还有文件。

 

下面来分析前面每一步大概都做了些什么:

一、添加用户:

添加用户调用的是Settings的addSharedUserLPw

  1. SharedUserSetting addSharedUserLPw(String name, int uid, int pkgFlags) {  
  2.        SharedUserSetting s = mSharedUsers.get(name);  
  3.        if (s != null) {  
  4.            if (s.userId == uid) {  
  5.                return s;  
  6.            }  
  7.            PackageManagerService.reportSettingsProblem(Log.ERROR,  
  8.                    "Adding duplicate shared user, keeping first: " + name);  
  9.            return null;  
  10.        }  
  11.        s = new SharedUserSetting(name, pkgFlags);//新建一个SharedUserSetting结构  
  12.        s.userId = uid;  
  13.        if (addUserIdLPw(uid, s, name)) {//保存到mUserIds或mOtherUserIds  
  14.            mSharedUsers.put(name, s);//添加到mSharedUsers  
  15.            return s;  
  16.        }  
  17.        return null;  

首先检查mSharedUsers中是否有这个用户,没有的话则新建一个SharedUserSetting,调用addUserIdLPw保存到mUserIds或mOtherUserIds,并添加到mSharedUsers。

  1. private boolean addUserIdLPw(int uid, Object obj, Object name) {  
  2.       if (uid > Process.LAST_APPLICATION_UID) {//大于应用程序最大pid  
  3.           return false;  
  4.       }  
  5.   
  6.       if (uid >= Process.FIRST_APPLICATION_UID) {//uid大于应用程序id的起始值  
  7.           int N = mUserIds.size();  
  8.           final int index = uid - Process.FIRST_APPLICATION_UID;  
  9.           while (index >= N) {//先添加元素,后面设置值  
  10.               mUserIds.add(null);  
  11.               N++;  
  12.           }  
  13.           if (mUserIds.get(index) != null) {  
  14.               PackageManagerService.reportSettingsProblem(Log.ERROR,  
  15.                       "Adding duplicate user id: " + uid  
  16.                       + " name=" + name);  
  17.               return false;  
  18.           }  
  19.           mUserIds.set(index, obj);//把该uid和对应的PackageSetting保存  
  20.       } else {//系统用户  
  21.           if (mOtherUserIds.get(uid) != null) {  
  22.               PackageManagerService.reportSettingsProblem(Log.ERROR,  
  23.                       "Adding duplicate shared id: " + uid  
  24.                       + " name=" + name);  
  25.               return false;  
  26.           }  
  27.           mOtherUserIds.put(uid, obj);//添加到mOtherUserIds  
  28.       }  
  29.       return true;  
  30.   }  

二、建立并启动PackageHandler消息循环

PackageHandler用来处理安装apk等过程中的各种消息,后面降到apk安装的时候会涉及到。


这个比较简单,主要就新建一个PackageHandler,用来处理消息。


三、解析/system/etc/permission下的xml文件

主要是读取并解析/etc/permissions的xml文件,如我的平板上面:

看一下读取的流程:


相关代码:

  1. void readPermissions() {//从/etc/permission读取权限配置信息  
  2.         // Read permissions from .../etc/permission directory.  
  3.         File libraryDir = new File(Environment.getRootDirectory(), "etc/permissions");  
  4.         if (!libraryDir.exists() || !libraryDir.isDirectory()) {  
  5.             Slog.w(TAG, "No directory " + libraryDir + ", skipping");  
  6.             return;  
  7.         }  
  8.         if (!libraryDir.canRead()) {  
  9.             Slog.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.                 Slog.i(TAG, "Non-xml file " + f + " in " + libraryDir + " directory, ignoring");  
  22.                 continue;  
  23.             }  
  24.             if (!f.canRead()) {  
  25.                 Slog.w(TAG, "Permissions library file " + f + " cannot be read");  
  26.                 continue;  
  27.             }  
  28.   
  29.             readPermissionsFromXml(f);  
  30.         }  
  31.   
  32.         // Read permissions from .../etc/permissions/platform.xml last so it will take precedence  
  33.         final File permFile = new File(Environment.getRootDirectory(),  
  34.                 "etc/permissions/platform.xml");//最后读取  
  35.         readPermissionsFromXml(permFile);  
  36. }  

readPermissions先读取除platform.xml的其他文件,并调用readPermissionsFromXml进行解析,继续看一下readPermissionsFromXml

  1. private void readPermissionsFromXml(File permFile) {  
  2.        FileReader permReader = null;  
  3.        try {  
  4.            permReader = new FileReader(permFile);  
  5.        } catch (FileNotFoundException e) {  
  6.            Slog.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);//保存到mGlobalGids  
  28.                    } else {  
  29.                        Slog.w(TAG, " without gid at "  
  30.                                + parser.getPositionDescription());  
  31.                    }  
  32.   
  33.                    XmlUtils.skipCurrentTag(parser);  
  34.                    continue;  
  35.                } else if ("permission".equals(name)) {//定义了权限和组id(gid)的关系,该组拥有什么权限  
  36.                    String perm = parser.getAttributeValue(null"name");//权限地名字  
  37.                    if (perm == null) {  
  38.                        Slog.w(TAG, " without name at "  
  39.                                + parser.getPositionDescription());  
  40.                        XmlUtils.skipCurrentTag(parser);  
  41.                        continue;  
  42.                    }  
  43.                    perm = perm.intern();  
  44.                    readPermission(parser, perm);//进一步解析,解析结果保存到 mSettings.mPermissions  
  45.   
  46.                } else if ("assign-permission".equals(name)) {//那一个uid都拥有什么权限(把什么权限赋予哪个uid)  
  47.                    String perm = parser.getAttributeValue(null"name");//获取权限名  
  48.                    if (perm == null) {  
  49.                        Slog.w(TAG, " 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.                        Slog.w(TAG, " without uid at "  
  57.                                + parser.getPositionDescription());  
  58.                        XmlUtils.skipCurrentTag(parser);  
  59.                        continue;  
  60.                    }  
  61.                    int uid = Process.getUidForName(uidStr);//该用户名对应的uid  
  62.                    if (uid < 0) {  
  63.                        Slog.w(TAG, " with unknown uid \""  
  64.                                + uidStr + "\" at "  
  65.                                + parser.getPositionDescription());  
  66.                        XmlUtils.skipCurrentTag(parser);  
  67.                        continue;  
  68.                    }  
  69.                    perm = perm.intern();  
  70.                    HashSet perms = mSystemPermissions.get(uid);//从mSystemPermissions查找是否已为该uid分配权限  
  71.                    if (perms == null) {  
  72.                        perms = new HashSet();  
  73.                        mSystemPermissions.put(uid, perms);//添加到mSystemPermissions  
  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.                        Slog.w(TAG, " without name at "  
  83.                                + parser.getPositionDescription());  
  84.                    } else if (lfile == null) {  
  85.                        Slog.w(TAG, " without file at "  
  86.                                + parser.getPositionDescription());  
  87.                    } else {  
  88.                        //Log.i(TAG, "Got library " + lname + " in " + lfile);  
  89.                        mSharedLibraries.put(lname, lfile);//添加到mSharedLibraries  
  90.                    }  
  91.                    XmlUtils.skipCurrentTag(parser);  
  92.                    continue;  
  93.   
  94.                } else if ("feature".equals(name)) {//系统特征 (壁纸等)  
  95.                    String fname = parser.getAttributeValue(null"name");  
  96.                    if (fname == null) {  
  97.                        Slog.w(TAG, " without name at "  
  98.                                + parser.getPositionDescription());  
  99.                    } else {  
  100.                        //Log.i(TAG, "Got feature " + fname);  
  101.                        FeatureInfo fi = new FeatureInfo();  
  102.                        fi.name = fname;  
  103.                        mAvailableFeatures.put(fname, fi);//添加到mAvailableFeatures  
  104.                    }  
  105.                    XmlUtils.skipCurrentTag(parser);  
  106.                    continue;  
  107.   
  108.                } else {  
  109.                    XmlUtils.skipCurrentTag(parser);  
  110.                    continue;  
  111.                }  
  112.   
  113.            }  
  114.            permReader.close();  
  115.        } catch (XmlPullParserException e) {  
  116.            Slog.w(TAG, "Got execption parsing permissions.", e);  
  117.        } catch (IOException e) {  
  118.            Slog.w(TAG, "Got execption parsing permissions.", e);  
  119.        }  
  120.    }  

readPermissionsFromXml主要是:

1、读取permission name添加到mSettings.mPermissions
2、读取gid添加到mSettings.mPermissions

readPermissionsFromXml:

permission

a、读取permission name添加到mSettings.mPermissions

b、读取gid添加到mSettings.mPermissions

assign-permission

a、设置相应uid所具有的权限,保存到mSystemPermissions

 library

a、.jar包保存到mSharedLibraries

 feature

a、  硬件相关信息保存到mAvailableFeatures

 

我们来看一下platform.xml:

  1. xml version="1.0" encoding="utf-8"?>  
  2.   
  3.       
  4.       
  5.   
  6.       
  7.     <permission name="android.permission.READ_NETWORK_USAGE_HISTORY">  
  8.         <group gid="net_bw_stats" />  
  9.     permission>  
  10.   
  11.       
  12.     <permission name="android.permission.MODIFY_NETWORK_ACCOUNTING">  
  13.         <group gid="net_bw_acct" />  
  14.     permission>  
  15.   
  16.       
  17.       
  18.       
  19.   
  20.       
  21.     <assign-permission name="android.permission.WRITE_EXTERNAL_STORAGE" uid="shell" />  
  22.     <assign-permission name="android.permission.SEND_SMS" uid="shell" />  
  23.     <assign-permission name="android.permission.CALL_PHONE" uid="shell" />  
  24.     <assign-permission name="android.permission.READ_CONTACTS" uid="shell" />  
  25.     <assign-permission name="android.permission.WRITE_CONTACTS" uid="shell" />  
  26.     <assign-permission name="android.permission.READ_CALENDAR" uid="shell" />  
  27.     <assign-permission name="android.permission.WRITE_CALENDAR" uid="shell" />  
  28.     <assign-permission name="android.permission.READ_USER_DICTIONARY" uid="shell" />  
  29.     <assign-permission name="android.permission.WRITE_USER_DICTIONARY" uid="shell" />  
  30.     <assign-permission name="android.permission.ACCESS_FINE_LOCATION" uid="shell" />  
  31.     <assign-permission name="android.permission.ACCESS_COARSE_LOCATION" uid="shell" />  
  32.     <assign-permission name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" uid="shell" />  
  33.     <assign-permission name="android.permission.ACCESS_NETWORK_STATE" uid="shell" />  
  34.     <assign-permission name="android.permission.ACCESS_WIFI_STATE" uid="shell" />  
  35.     <assign-permission name="android.permission.BLUETOOTH" uid="shell" />  
  36.       
  37.     <assign-permission name="android.permission.GET_TASKS" uid="shell" />  
  38.     <assign-permission name="android.permission.CHANGE_CONFIGURATION" uid="shell" />  
  39.     <assign-permission name="android.permission.REORDER_TASKS" uid="shell" />  
  40.     <assign-permission name="android.permission.SET_ANIMATION_SCALE" uid="shell" />  
  41.     <assign-permission name="android.permission.SET_PREFERRED_APPLICATIONS" uid="shell" />  
  42.     <assign-permission name="android.permission.WRITE_SETTINGS" uid="shell" />  
  43.     <assign-permission name="android.permission.WRITE_SECURE_SETTINGS" uid="shell" />  
  44.     <assign-permission name="android.permission.BROADCAST_STICKY" uid="shell" />  
  45.       
  46.     <assign-permission name="android.permission.SET_DEBUG_APP" uid="shell" />  
  47.     <assign-permission name="android.permission.SET_PROCESS_LIMIT" uid="shell" />  
  48.     <assign-permission name="android.permission.SET_ALWAYS_FINISH" uid="shell" />  
  49.     <assign-permission name="android.permission.DUMP" uid="shell" />  
  50.     <assign-permission name="android.permission.SIGNAL_PERSISTENT_PROCESSES" uid="shell" />  
  51.     <assign-permission name="android.permission.KILL_BACKGROUND_PROCESSES" uid="shell" />  
  52.       
  53.     <assign-permission name="android.permission.FORCE_BACK" uid="shell" />  
  54.     <assign-permission name="android.permission.BATTERY_STATS" uid="shell" />  
  55.     <assign-permission name="android.permission.INTERNAL_SYSTEM_WINDOW" uid="shell" />  
  56.     <assign-permission name="android.permission.INJECT_EVENTS" uid="shell" />  
  57.     <assign-permission name="android.permission.RETRIEVE_WINDOW_CONTENT" uid="shell" />  
  58.     <assign-permission name="android.permission.SET_ACTIVITY_WATCHER" uid="shell" />  
  59.     <assign-permission name="android.permission.READ_INPUT_STATE" uid="shell" />  
  60.     <assign-permission name="android.permission.SET_ORIENTATION" uid="shell" />  
  61.     <assign-permission name="android.permission.INSTALL_PACKAGES" uid="shell" />  
  62.     <assign-permission name="android.permission.CLEAR_APP_USER_DATA" uid="shell" />  
  63.     <assign-permission name="android.permission.DELETE_CACHE_FILES" uid="shell" />  
  64.     <assign-permission name="android.permission.DELETE_PACKAGES" uid="shell" />  
  65.     <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="shell" />  
  66.     <assign-permission name="android.permission.READ_FRAME_BUFFER" uid="shell" />  
  67.     <assign-permission name="android.permission.DEVICE_POWER" uid="shell" />  
  68.     <assign-permission name="android.permission.INSTALL_LOCATION_PROVIDER" uid="shell" />  
  69.     <assign-permission name="android.permission.BACKUP" uid="shell" />  
  70.     <assign-permission name="android.permission.FORCE_STOP_PACKAGES" uid="shell" />  
  71.     <assign-permission name="android.permission.STOP_APP_SWITCHES" uid="shell" />  
  72.     <assign-permission name="android.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY" uid="shell" />  
  73.     <assign-permission name="android.permission.GRANT_REVOKE_PERMISSIONS" uid="shell" />  
  74.     <assign-permission name="android.permission.SET_KEYBOARD_LAYOUT" uid="shell" />  
  75.     <assign-permission name="android.permission.GET_DETAILED_TASKS" uid="shell" />  
  76.     <assign-permission name="android.permission.SET_SCREEN_COMPATIBILITY" uid="shell" />  
  77.     <assign-permission name="android.permission.READ_EXTERNAL_STORAGE" uid="shell" />  
  78.     <assign-permission name="android.permission.WRITE_EXTERNAL_STORAGE" uid="shell" />  
  79.     <assign-permission name="android.permission.INTERACT_ACROSS_USERS" uid="shell" />  
  80.     <assign-permission name="android.permission.INTERACT_ACROSS_USERS_FULL" uid="shell" />  
  81.     <assign-permission name="android.permission.MANAGE_USERS" uid="shell" />  
  82.     <assign-permission name="android.permission.BLUETOOTH_STACK" uid="shell" />  
  83.       
  84.     <assign-permission name="android.permission.MODIFY_AUDIO_SETTINGS" uid="media" />  
  85.     <assign-permission name="android.permission.ACCESS_DRM" uid="media" />  
  86.     <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="media" />  
  87.     <assign-permission name="android.permission.WAKE_LOCK" uid="media" />  
  88.   
  89.     <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="graphics" />  
  90.   
  91.     
    阅读(2168) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~