PackageManagerService启动过程

1.PackageManagerService服务启动过程:【Android的所有Java服务都是通过SystemServer进程启动的,并且驻留在SystemServer进程中】
public final class SystemServer {
……..
private Context mSystemContext;
private SystemServiceManager mSystemServiceManager;
   
private Installer mInstaller; //应用安装器
……..
private PackageManagerService mPackageManagerService;
private PackageManager mPackageManager;
private ContentResolver mContentResolver;
   
private boolean mOnlyCore;
private boolean mFirstBoot;
……..
public static void main(String[] args) {
   new SystemServer().run();
}
……..
private void run() {
     ……..
     Looper.prepareMainLooper(); // 准备主线程的looper
     ……..
     createSystemContext();
     mSystemServiceManager = new SystemServiceManager(mSystemContext);//创建SystemServiceManager对象
     LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
     // Start services. 启动服务
     try {
        startBootstrapServices();
        startCoreServices();
         startOtherServices();
     } catch (Throwable ex) {
     Slog.e(“System”, “******************************************”);
     Slog.e(“System”, “************ Failure starting system services”, ex);
     throw ex;
   }
   ……..
   // Loop forever.
   Looper.loop(); // 进入循环
   throw new RuntimeException(“Main thread loop unexpectedly exited”);
}
……..
private void createSystemContext() {
   ActivityThread activityThread = ActivityThread.systemMain();
   mSystemContext = activityThread.getSystemContext();
   mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar);
}
   
startBootstrapServices(){
   //通过反射获取Installer类,然后实例化该类,并注册到mServices中,再调用该对象的onStart方法
   mInstaller = mSystemServiceManager.startService(Installer.class);
   ……..
   //通过读取属性来判断运行核心应用
   String cryptState = SystemProperties.get(“vold.decrypt”);
   if (ENCRYPTING_STATE.equals(cryptState)) {
       Slog.w(TAG, “Detected encryption in progress – only parsing core apps”);
                mOnlyCore = true;
   } else if (ENCRYPTED_STATE.equals(cryptState)) {
                Slog.w(TAG, “Device encrypted – only parsing core apps”);
                mOnlyCore = true;
   }
   //调用PackageManagerService的静态方法main来构造PackageManagerService的对象
   mPackageManagerService = PackageManagerService.main(mSystemContext, mInstaller, mFactoryTestMode !=

                                                        FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
   //判断PackageManagerService是否是第一次启动,SystemServer进程被杀后会被重启
   mFirstBoot = mPackageManagerService.isFirstBoot();
   mPackageManager = mSystemContext.getPackageManager();
}
……..
private void startOtherServices() {
   ……..
   //PackageManagerService执行dex优化
   try {
                mPackageManagerService.performBootDexOpt();
   } catch (Throwable e) {
                reportWtf(“performing boot dexopt”, e);
   }
   ……..
   try {
                mPackageManagerService.systemReady();//PackageManagerService执行systemReady方法
   } catch (Throwable e) {
                reportWtf(“making Package Manager Service ready”, e);
   }
   ……..
}

2.Installer的实例化与onStart方法
public final class Installer extends SystemService {
    private final InstallerConnection mInstaller;

    public Installer(Context context) {
        super(context);
        mInstaller = new InstallerConnection();//与底层installer连接的类
    }
    
    @Override
    public void onStart() {
        Slog.i(TAG, “Waiting for installd to be ready.”);
        ping();
    }
    ……..
    public boolean ping() {
        if (mInstaller.execute(“ping”) < 0) {//调用底层installer执行ping命令
            return false;
        } else {
            return true;
        }
    }
    ……..
}

3.PackageManagerService的实例化
public class PackageManagerService extends IPackageManager.Stub{
    ……..
    final Installer mInstaller;
    ……..
    final Settings mSettings;
    boolean mRestoredSettings;
    ……..
    final ActivityIntentResolver mActivities = new ActivityIntentResolver();
    final ActivityIntentResolver mReceivers = new ActivityIntentResolver();
    final ServiceIntentResolver mServices = new ServiceIntentResolver();
    final ProviderIntentResolver mProviders = new ProviderIntentResolver();
    ……..
    public static final PackageManagerService main(Context context, Installer installer, boolean factoryTest, boolean onlyCore) {
        //构造PackageManagerService服务对象
        PackageManagerService m = new PackageManagerService(context, installer, factoryTest, onlyCore);
        //注册PackageManagerService服务
        ServiceManager.addService(“package”, m);
        return m;
    }
    ……..
    //测量屏幕尺寸
    private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
        DisplayManager displayManager = (DisplayManager) context.getSystemService(
                Context.DISPLAY_SERVICE);
        displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
    }
    
    public PackageManagerService(Context context, Installer installer, boolean factoryTest, boolean onlyCore) {
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, SystemClock.uptimeMillis());
        if (mSdkVersion <= 0) {//SDK版本检查
            Slog.w(TAG, “**** ro.build.version.sdk not set!”);
        }
        ……..
        mContext = context;
        mFactoryTest = factoryTest;//开机模式
        mOnlyCore = onlyCore;//是否对包做dex优化
        mLazyDexOpt = “eng”.equals(SystemProperties.get(“ro.build.type”));//如果编译版本为eng,则不需要dex优化
        mMetrics = new DisplayMetrics();//创建显示尺寸信息
        
        // 创建SharedUserSetting对象并添加到Settings的成员变量mSharedUsers中

        mSettings = new Settings(context); // 存储系统运行过程中的设置信息
        // 通过Settings的addSharedUserLPw函数向mSharedUsers,mUserIds,mOtherUserIds数组

        // 添加了6个特定进程的SharedUserSetting对象
        mSettings.addSharedUserLPw(“android.uid.system”, Process.SYSTEM_UID,

                              ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw(“android.uid.phone”, RADIO_UID,

                             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw(“android.uid.log”, LOG_UID,

                             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw(“android.uid.nfc”, NFC_UID,

                             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw(“android.uid.bluetooth”, BLUETOOTH_UID,

                             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw(“android.uid.shell”, SHELL_UID,

                             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);

        String separateProcesses = SystemProperties.get(“debug.separate_processes”);
        if (separateProcesses != null && separateProcesses.length() > 0) {
            if (“*”.equals(separateProcesses)) {
                mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
                mSeparateProcesses = null;
                Slog.w(TAG, “Running with debug.separate_processes: * (ALL)”);
            } else {
                mDefParseFlags = 0;
                mSeparateProcesses = separateProcesses.split(“,”);
                Slog.w(TAG, “Running with debug.separate_processes: “
                        + separateProcesses);
            }
        } else {
            mDefParseFlags = 0;
            mSeparateProcesses = null;
        }
        
        // 保存应用安装器,用于访问installd服务进程,完成一些apk安装,卸载,优化工作
        mInstaller = installer; //在ServerServer中创建,调用了其中的ping测试是否连上  
        //获取屏幕尺寸大小

        getDefaultDisplayMetrics(context, mMetrics);
        
        // 获取SystemConfig对象【见后续详解】
        SystemConfig systemConfig = SystemConfig.getInstance();
        mGlobalGids = systemConfig.getGlobalGids();
        mSystemPermissions = systemConfig.getSystemPermissions();
        mAvailableFeatures = systemConfig.getAvailableFeatures(); // 从systemConfig中获取硬件支持的特性

        synchronized (mInstallLock) {
        // writer
        synchronized (mPackages) {
            //创建消息处理线程并启动【HandlerThread的子类ServiceThread的对象】
            mHandlerThread = new ServiceThread(TAG, Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
            mHandlerThread.start();
            //创建往消息处理线程中发消息的mHandler,
            mHandler = new PackageHandler(mHandlerThread.getLooper());
            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);

            //创建一些安装目录
            File dataDir = Environment.getDataDirectory(); // dataDir =/data/
            mAppDataDir = new File(dataDir, “data”);
            mAppInstallDir = new File(dataDir, “app”);
            mAppLib32InstallDir = new File(dataDir, “app-lib”);
            mAsecInternalPath = new File(dataDir, “app-asec”).getPath();
            mUserAppDataDir = new File(dataDir, “user”);
            mDrmAppPrivateInstallDir = new File(dataDir, “app-private”);
            
            //创建用户管理对象UserManagerService
            sUserManager = new UserManagerService(context, this, mInstallLock, mPackages);
            
            // 获取系统权限
            // Propagate permission configuration in to package manager.
            ArrayMap<String, SystemConfig.PermissionEntry> permConfig = systemConfig.getPermissions();
            for (int i=0; i<permConfig.size(); i++) {
                SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
                BasePermission bp = mSettings.mPermissions.get(perm.name);
                if (bp == null) {
                    bp = new BasePermission(perm.name, “android”, BasePermission.TYPE_BUILTIN);
                    mSettings.mPermissions.put(perm.name, bp);
                }
                if (perm.gids != null) {
                    bp.gids = appendInts(bp.gids, perm.gids);
                }
            }
            
            // 获取系统库并保存到mSharedLibraries中
            ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
            for (int i=0; i<libConfig.size(); i++) {
                mSharedLibraries.put(libConfig.keyAt(i),
                        new SharedLibraryEntry(libConfig.valueAt(i), null));
            }

            mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
            // 调用Settings的readLPw方法读取文件信息
            mRestoredSettings = mSettings.readLPw(this, sUserManager.getUsers(false), mSdkVersion, mOnlyCore);
            ……..
            long startTime = SystemClock.uptimeMillis();
            ……..
            // 设置扫描模式
            final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING;
            
            //alreadyDexOpted记录已经进行过Dex优化的文件
            final HashSet<String> alreadyDexOpted = new HashSet<String>();
            final String bootClassPath = System.getenv(“BOOTCLASSPATH”); // 获取BOOTCLASSPATH属性
           //获取SYSTEMSERVERCLASSPATH属性

            final String systemServerClassPath = System.getenv(“SYSTEMSERVERCLASSPATH”);

            //如果bootClassPath不为空则将这个属性中的所有文件添加到alreadyDexOpted中
            if (bootClassPath != null) {
                String[] bootClassPathElements = splitString(bootClassPath, ‘:’);
                for (String element : bootClassPathElements) {
                    alreadyDexOpted.add(element);
                }
            } else {
                Slog.w(TAG, “No BOOTCLASSPATH found!”);
            }
            //如果systemServerClassPath不为空则将这个属性中的所有文件添加到alreadyDexOpted中
            if (systemServerClassPath != null) {
                String[] systemServerClassPathElements = splitString(systemServerClassPath, ‘:’);
                for (String element : systemServerClassPathElements) {
                    alreadyDexOpted.add(element);
                }
            } else {
                Slog.w(TAG, “No SYSTEMSERVERCLASSPATH found!”);
            }

            // 判断前面获取的mSharedLibraries,如果有需要进行Dex优化的则进行优化,
            boolean didDexOptLibraryOrTool = false;
            final List<String> allInstructionSets = getAllInstructionSets();
            final String[] dexCodeInstructionSets = getDexCodeInstructionSets(allInstructionSets.toArray(new String[allInstructionSets.size()]));
            //在前面解析platfor.xml时,将一些外部库路径保存到了mSharedLibraries变量中
            if (mSharedLibraries.size() > 0) { //确保 外部库也被 优化  
                //循环变量mSharedLibraries变量

                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
                    for (SharedLibraryEntry libEntry : mSharedLibraries.values()) {
                        final String lib = libEntry.path;
                        if (lib == null) {
                            continue;
                        }

                        try {
                            byte dexoptRequired = DexFile.isDexOptNeededInternal(lib, null, dexCodeInstructionSet, false);
                            if (dexoptRequired != DexFile.UP_TO_DATE) {
                                alreadyDexOpted.add(lib);

                                // The list of “shared libraries” we have at this point is
                                if (dexoptRequired == DexFile.DEXOPT_NEEDED) {
                                    //通过安装器进行dex优化
                                    mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet);
                                } else {
                                    mInstaller.patchoat(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet);
                                }
                                didDexOptLibraryOrTool = true;
                            }
                        } catch (FileNotFoundException e) {
                            Slog.w(TAG, “Library not found: ” + lib);
                        } catch (IOException e) {
                            Slog.w(TAG, “Cannot dexopt ” + lib + “; is it an APK or JAR? “
                                    + e.getMessage());
                        }
                    }
                }
            }
            // 将framework-res.apk与core-libart.jar添加到alreadyDexOpted中,不需要优化
            File frameworkDir = new File(Environment.getRootDirectory(), “framework”);
            alreadyDexOpted.add(frameworkDir.getPath() + “/framework-res.apk”);
            alreadyDexOpted.add(frameworkDir.getPath() + “/core-libart.jar”);

            // 判断/system/frameworks/下所有文件,有需要进行Dex优化的则进行优化
            String[] frameworkFiles = frameworkDir.list();
            if (frameworkFiles != null) {
                // TODO: We could compile these only for the most preferred ABI. We should
                // first double check that the dex files for these commands are not referenced
                // by other system apps.
                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
                    for (int i=0; i<frameworkFiles.length; i++) {
                        File libPath = new File(frameworkDir, frameworkFiles[i]);
                        String path = libPath.getPath();
                        // Skip the file if we already did it.
                        if (alreadyDexOpted.contains(path)) { // 跳过所有已经进行过Dex优化的文件
                            continue;
                        }
                        // Skip the file if it is not a type we want to dexopt.
                        if (!path.endsWith(“.apk”) && !path.endsWith(“.jar”)) { // 跳过既不是APK也不是JAR的文件
                            continue;
                        }
                        try { // 如果需要进行优化,则进行Dex优化
                            byte dexoptRequired = DexFile.isDexOptNeededInternal(path, null, dexCodeInstructionSet, false);
                            if (dexoptRequired == DexFile.DEXOPT_NEEDED) {
                                mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet);
                                didDexOptLibraryOrTool = true;
                            } else if (dexoptRequired == DexFile.PATCHOAT_NEEDED) {
                                mInstaller.patchoat(path, Process.SYSTEM_UID, true, dexCodeInstructionSet);
                                didDexOptLibraryOrTool = true;
                            }
                        } catch (FileNotFoundException e) {
                            Slog.w(TAG, “Jar not found: ” + path);
                        } catch (IOException e) {
                            Slog.w(TAG, “Exception reading jar: ” + path, e);
                        }
                    }
                }
            }

            //扫描以下各个目录下的apk文件
            File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR);
            scanDirLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM
                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0);

            // Find base frameworks (resource packages without code).
            scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM
                    | PackageParser.PARSE_IS_SYSTEM_DIR
                    | PackageParser.PARSE_IS_PRIVILEGED,
                    scanFlags | SCAN_NO_DEX, 0);

            // Collected privileged system packages.
            final File privilegedAppDir = new File(Environment.getRootDirectory(), “priv-app”);
            scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM
                    | PackageParser.PARSE_IS_SYSTEM_DIR
                    | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);

            // Collect ordinary system packages.
            final File systemAppDir = new File(Environment.getRootDirectory(), “app”);
            scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM
                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);

            // Collect all vendor packages.
            File vendorAppDir = new File(“/vendor/app”);
            try {
                vendorAppDir = vendorAppDir.getCanonicalFile();
            } catch (IOException e) {
                // failed to look up canonical path, continue with original one
            }
            scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM
                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);

            // Collect all OEM packages.
            final File oemAppDir = new File(Environment.getOemDirectory(), “app”);
            scanDirLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM
                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);

            //调用底层installer,执行movefiles命令
            if (DEBUG_UPGRADE) Log.v(TAG, “Running installd update commands”);
            mInstaller.moveFiles();

            // 保存通过OTA升级删除的apk
            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
            final ArrayMap<String, File> expectingBetter = new ArrayMap<>();
            if (!mOnlyCore) {
                Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();//遍历Settings的成员变量mPackages
                while (psit.hasNext()) {
                    PackageSetting ps = psit.next();

                    //不是系统app则继续进行下一个
                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { 
                        continue;
                    }

                    //如果是系统app,同时已经被PackageManagerService扫描过了
                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
                    if (scannedPkg != null) {
                        // 如果系统app刚被扫描并且在disabled列表,则它肯定是通过ota添加的,

                        // 从当前扫描的package中移除它,所以以前用户安装的可以被扫描到
                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
                            logCriticalInfo(Log.WARN, “Expecting better updated system app for “
                                    + ps.name + “; removing system app.  Last known codePath=”
                                    + ps.codePathString + “, installStatus=” + ps.installStatus
                                    + “, versionCode=” + ps.versionCode + “; scanned versionCode=”
                                    + scannedPkg.mVersionCode);
                            removePackageLI(ps, true); // 如果该apk包在当前扫描记录中且已不能使用,则移除该apk包信息
                            expectingBetter.put(ps.name, ps.codePath);
                        }
                        continue;
                    }

                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
                        psit.remove();
                        logCriticalInfo(Log.WARN, “System package ” + ps.name
                                + ” no longer exists; wiping its data”);
                        removeDataDirsLI(ps.name);
                    } else {
                        final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
                            possiblyDeletedUpdatedSystemApps.add(ps.name); // 将通过OTA升级删除的系统apk信息起来
                        }
                    }
                }
            }
            //查找未完成安装的apk包,清除未完成的安装包并且删除临时文件
            ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
            for(int i = 0; i < deletePkgsList.size(); i++) {
                cleanupInstallFailedPackage(deletePkgsList.get(i)); //移除安装失败的package 
            }
            deleteTempPackageFiles();

            // 删除所有没有与包关联起来的shared userIDs
            mSettings.pruneSharedUsersLPw();

            if (!mOnlyCore) {
                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, SystemClock.uptimeMillis());
                
                // 扫描/data/app/与/data/app-private/目录【第二个参数为0,可卸载】
                scanDirLI(mAppInstallDir, 0, scanFlags, 0);
                scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK, scanFlags, 0);

                // 删除通过OTA升级删除的系统apk信息,如果不是以前更新的应用则完全删除,否则撤销其系统权限
                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
                    mSettings.removeDisabledSystemPackageLPw(deletedAppName); //删除通过OTA升级删除的系统apk信息

                    String msg;
                    if (deletedPkg == null) {
                        msg = “Updated system package ” + deletedAppName
                                + ” no longer exists; wiping its data”;
                        removeDataDirsLI(deletedAppName);// 完全删除
                    } else { // 撤销其系统权限
                        msg = “Updated system app + ” + deletedAppName
                                + ” no longer present; removing system privileges for “
                                + deletedAppName;

                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;

                        PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
                    }
                    logCriticalInfo(Log.WARN, msg);
                }

                // 确保所有出现在userdata分区的apk都是可见的,如果不可见,则crawl back and revive the system version
                for (int i = 0; i < expectingBetter.size(); i++) {
                    final String packageName = expectingBetter.keyAt(i);
                    if (!mPackages.containsKey(packageName)) {
                        final File scanFile = expectingBetter.valueAt(i);

                        logCriticalInfo(Log.WARN, “Expected better ” + packageName
                                + ” but never showed up; reverting to system”);

                        final int reparseFlags;
                        if (FileUtils.contains(privilegedAppDir, scanFile)) {
                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
                                    | PackageParser.PARSE_IS_SYSTEM_DIR
                                    | PackageParser.PARSE_IS_PRIVILEGED;
                        } else if (FileUtils.contains(systemAppDir, scanFile)) {
                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
                        } else if (FileUtils.contains(vendorAppDir, scanFile)) {
                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
                        } else if (FileUtils.contains(oemAppDir, scanFile)) {
                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
                        } else {
                            Slog.e(TAG, “Ignoring unexpected fallback path ” + scanFile);
                            continue;
                        }

                        mSettings.enableSystemPackageLPw(packageName);

                        try {
                            scanPackageLI(scanFile, reparseFlags, scanFlags, 0, null);
                        } catch (PackageManagerException e) {
                            Slog.e(TAG, “Failed to parse original system package: “
                                    + e.getMessage());
                        }
                    }
                }
            }
            ……..
            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL //赋予package相应请求的权限
                    | (regrantPermissions ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL) : 0));
            ……..
            mSettings.writeLPr(); // 最后将扫描到的信息保存到文件/data/system/packages.xml中 

            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
                    SystemClock.uptimeMillis());

            mRequiredVerifierPackage = getRequiredVerifierLPr();
        } // synchronized (mPackages)
        } // synchronized (mInstallLock)

        mInstallerService = new PackageInstallerService(context, this, mAppInstallDir);

        // Now after opening every single application zip, make sure they
        // are all flushed.  Not really needed, but keeps things nice and
        // tidy.
        Runtime.getRuntime().gc();
    }
    ……..
    private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
        final File[] files = dir.listFiles();
        ……..
        for (File file : files) {
            final boolean isPackage = (isApkFile(file) || file.isDirectory())
                    && !PackageInstallerService.isStageName(file.getName());
            if (!isPackage) {
                // Ignore entries which are not packages
                continue;
            }
            try { //调用scanPackageLI函数来对它进行解析和安装
                scanPackageLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK,
                        scanFlags, currentTime, null);
            } catch (PackageManagerException e) {
                ……..
            }
        }
    }
    ……..
    private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
            long currentTime, UserHandle user) throws PackageManagerException {
        if (DEBUG_INSTALL) Slog.d(TAG, “Parsing: ” + scanFile);
        parseFlags |= mDefParseFlags;
        PackageParser pp = new PackageParser(); // 创建一个PackageParser实例
        pp.setSeparateProcesses(mSeparateProcesses);
        pp.setOnlyCoreApps(mOnlyCore);
        pp.setDisplayMetrics(mMetrics);

        if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
            parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
        }

        final PackageParser.Package pkg;
        try {
            pkg = pp.parsePackage(scanFile, parseFlags); //调用PackageParser实例的parsePackage函数来对这个Apk文件进行解析
        } catch (PackageParserException e) {
            throw PackageManagerException.from(e);
        }
        ……..
        // 调用另外一个版本的scanPackageLI函数把来解析后得到的应用程序信息保存在PackageManagerService中
        PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags
                | SCAN_UPDATE_SIGNATURE, currentTime, user);
        ……..
        return scannedPkg;
    }
    ……..
    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags,
            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
        boolean success = false;
        try {
            final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags,
                    currentTime, user);
            success = true;
            return res;
        } finally {
            if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
                removeDataDirsLI(pkg.packageName);
            }
        }
    }
    ……..
    private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags,
            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
        ……..
        // writer
        synchronized (mPackages) {
            ……..
            int N = pkg.providers.size();
            StringBuilder r = null;
            int i;
            for (i=0; i<N; i++) {
                PackageParser.Provider p = pkg.providers.get(i);
                p.info.processName = fixProcessName(pkg.applicationInfo.processName,
                        p.info.processName, pkg.applicationInfo.uid);
                mProviders.addProvider(p); // 保存所有的Provider
                ……..
                }
                ……..
            }
            if (r != null) {
                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, ”  Providers: ” + r);
            }

            N = pkg.services.size();
            r = null;
            for (i=0; i<N; i++) {
                PackageParser.Service s = pkg.services.get(i);
                s.info.processName = fixProcessName(pkg.applicationInfo.processName,
                        s.info.processName, pkg.applicationInfo.uid);
                mServices.addService(s); // 保存所有的Service
                ……..
            }
            if (r != null) {
                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, ”  Services: ” + r);
            }

            N = pkg.receivers.size();
            r = null;
            for (i=0; i<N; i++) {
                PackageParser.Activity a = pkg.receivers.get(i);
                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
                        a.info.processName, pkg.applicationInfo.uid);
                mReceivers.addActivity(a, “receiver”); // 保存所有的Receiver
                ……..
            }
            if (r != null) {
                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, ”  Receivers: ” + r);
            }

            N = pkg.activities.size();
            r = null;
            for (i=0; i<N; i++) {
                PackageParser.Activity a = pkg.activities.get(i);
                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
                        a.info.processName, pkg.applicationInfo.uid);
                mActivities.addActivity(a, “activity”); // 保存所有的Activitie
                ……..
            }
            if (r != null) {
                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, ”  Activities: ” + r);
            }

            N = pkg.permissionGroups.size();
            r = null;
            for (i=0; i<N; i++) {
                PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
                PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
                if (cur == null) {
                    mPermissionGroups.put(pg.info.name, pg); // 保存所有的PermissionGroup
                    ……..
                } else {
                    ……..
                }
            }
            ……..
            N = pkg.instrumentation.size();
            r = null;
            for (i=0; i<N; i++) {
                PackageParser.Instrumentation a = pkg.instrumentation.get(i);
                a.info.packageName = pkg.applicationInfo.packageName;
                a.info.sourceDir = pkg.applicationInfo.sourceDir;
                a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
                a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
                a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
                a.info.dataDir = pkg.applicationInfo.dataDir;

                // TODO: Update instrumentation.nativeLibraryDir as well ? Does it
                // need other information about the application, like the ABI and what not ?
                a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
                mInstrumentation.put(a.getComponentName(), a); // 保存所有的Instrumentation
                ……..
            }
            if (r != null) {
                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, ”  Instrumentation: ” + r);
            }

            if (pkg.protectedBroadcasts != null) {
                N = pkg.protectedBroadcasts.size();
                for (i=0; i<N; i++) {
                    mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));// 保存所有的ProtectedBroadcast
                }
            }
            ……..
        }

        return pkg;
    }
    ……..
}

4.Settings对象的构造
final class Settings {
  ……..
    final HashMap<String, SharedUserSetting> mSharedUsers = new HashMap<String, SharedUserSetting>();
    private final ArrayList<Object> mUserIds = new ArrayList<Object>();// 非系统应用
    private final SparseArray<Object> mOtherUserIds = new SparseArray<Object>();// 系统应用
  ……..
    private final File mSettingsFilename; // packages.xml文件用于记录系统中所安装的Package信息
    private final File mBackupSettingsFilename; // packages-backup.xml文件,是packages.xml文件的备份
    private final File mPackageListFilename; // packages.list保存系统中存在的所有非系统自带的APK信息,即UID大于1000的apk
    private final File mStoppedPackagesFilename; // packages-stopped.xml文件用于记录系统中强制停止运行的Package信息
    private final File mBackupStoppedPackagesFilename; // packages-stopped.xml文件的备份,在强制停止某个应用时,会记录。
    ……
    Settings(Context context) {
        this(context, Environment.getDataDirectory());
    }

    Settings(Context context, File dataDir) {
        //创建/data/system/目录,并设置这个目录的权限
        mSystemDir = new File(dataDir, “system”); 
        mSystemDir.mkdirs();
        FileUtils.setPermissions(mSystemDir.toString(),
                FileUtils.S_IRWXU|FileUtils.S_IRWXG
                |FileUtils.S_IROTH|FileUtils.S_IXOTH,
                -1, -1);
        // 创建一些文件
        mSettingsFilename = new File(mSystemDir, “packages.xml”); // mSettingsFilename = /data/system/packages.xml
        mBackupSettingsFilename = new File(mSystemDir, “packages-backup.xml”);

        mPackageListFilename = new File(mSystemDir, “packages.list”); // mPackageListFilename = /data/system/packages.list
        FileUtils.setPermissions(mPackageListFilename, 0660, SYSTEM_UID, PACKAGE_INFO_GID); // 设置目录的权限

        // Deprecated: Needed for migration
        mStoppedPackagesFilename = new File(mSystemDir, “packages-stopped.xml”); 

        mBackupStoppedPackagesFilename = new File(mSystemDir, “packages-stopped-backup.xml”);
    }
    ……..
    SharedUserSetting addSharedUserLPw(String name, int uid, int pkgFlags) {
        //根据进程UID对应的名称从成员变量mSharedUsers中查找对应的SharedUserSetting对象并返回查询结果
        SharedUserSetting s = mSharedUsers.get(name);
        if (s != null) {
            if (s.userId == uid) {
                return s;
            }
            PackageManagerService.reportSettingsProblem(Log.ERROR,
                    “Adding duplicate shared user, keeping first: ” + name);
            return null;
        }
        //没有查找到对应的SharedUserSetting对象,则传入的UID名称与UID创建一个新的SharedUserSetting对象。
        s = new SharedUserSetting(name, pkgFlags);
        s.userId = uid;
        //添加到成员变量mUserIds,mOtherUserIds中,这两个变量主要是加快查找速度
        if (addUserIdLPw(uid, s, name)) {
            mSharedUsers.put(name, s);//如果加入成功则加入到mSharedUsers中
            return s;
        }
        return null;
    }
    ……..
    private boolean addUserIdLPw(int uid, Object obj, Object name) {
        //判断添加的UID是否大于19999,系统应用与非系统应用的UID分别在0<=x<10000,10000<=y<19999
        if (uid > Process.LAST_APPLICATION_UID) {
            return false;
        }
        //如果不是系统应用则将SharedUserSetting对象到mUserIds动态数组中
        if (uid >= Process.FIRST_APPLICATION_UID) {
            //计算在数组中的索引为uid-10000
            int N = mUserIds.size();
            final int index = uid – Process.FIRST_APPLICATION_UID;
            while (index >= N) {
                mUserIds.add(null);
                N++;
            }
            if (mUserIds.get(index) != null) {
                PackageManagerService.reportSettingsProblem(Log.ERROR,
                        “Adding duplicate user id: ” + uid
                        + ” name=” + name);
                return false;
            }
            mUserIds.set(index, obj);
        } else {// 如果是系统应用则将SharedUserSetting对象到mOtherUserIds动态数组中
            if (mOtherUserIds.get(uid) != null) {
                PackageManagerService.reportSettingsProblem(Log.ERROR,
                        “Adding duplicate shared id: ” + uid
                        + ” name=” + name);
                return false;
            }
            mOtherUserIds.put(uid, obj);
        }
        return true;
    }
    ……
    boolean readLPw(PackageManagerService service, List<UserInfo> users, int sdkVersion, boolean onlyCore) {
        FileInputStream str = null;
        if (mBackupSettingsFilename.exists()) { //如果/data/system/packages-backup.xml文件存在
            try {
                //读取/data/system/packages-backup.xml文件
                str = new FileInputStream(mBackupSettingsFilename);
                mReadMessages.append(“Reading from backup settings file\n”);
                PackageManagerService.reportSettingsProblem(Log.INFO, “Need to read from backup settings file”);
                
                //当/data/system/packages.xml文件的备份文件存在时,删除packages.xml文件
                if (mSettingsFilename.exists()) {
                    ……..
                    mSettingsFilename.delete();
                }
            } catch (java.io.IOException e) {
                // We’ll try for the normal settings file.
            }
        }

        mPendingPackages.clear();
        mPastSignatures.clear();

        try {
            if (str == null) { //如果/data/system/packages-backup.xml文件为空
                if (!mSettingsFilename.exists()) {
                    // 同时/data/system/packages.xml文件不存在,则返回
                    mReadMessages.append(“No settings file found\n”);
                    PackageManagerService.reportSettingsProblem(Log.INFO, “No settings file; creating initial state”);
                    mInternalSdkPlatform = mExternalSdkPlatform = sdkVersion;
                    mFingerprint = Build.FINGERPRINT;
                    return false;
                }
                // 否则读取/data/system/packages.xml文件
                str = new FileInputStream(mSettingsFilename); 
            }
            
            // 解析文件内容
            XmlPullParser parser = Xml.newPullParser();
            parser.setInput(str, null);

            int type;
            while ((type = parser.next()) != XmlPullParser.START_TAG
                    && type != XmlPullParser.END_DOCUMENT) {
                ;
            }
            ……..
        }
        ……..
        return true;
    }
    ……..
}

5.UserManagerService对象的构建
public class UserManagerService extends IUserManager.Stub {
   ……..
   UserManagerService(Context context, PackageManagerService pm, Object installLock, Object packagesLock) {
        this(context, pm, installLock, packagesLock, Environment.getDataDirectory(), new File(Environment.getDataDirectory(), “user”));
   }

    /**
     * Available for testing purposes.
     */
    private UserManagerService(Context context, PackageManagerService pm, Object installLock, Object packagesLock,
            File dataDir, File baseUserPath) {
        mContext = context;
        mPm = pm;
        mInstallLock = installLock;
        mPackagesLock = packagesLock;
        mHandler = new Handler();
        synchronized (mInstallLock) {
            synchronized (mPackagesLock) {
                //创建用户安装目录/data/user
                mUsersDir = new File(dataDir, USER_INFO_DIR);
                mUsersDir.mkdirs();
                //创建userZeroDir=/data/system/users/0目录
                // Make zeroth user directory, for services to migrate their files to that location
                File userZeroDir = new File(mUsersDir, “0”);
                userZeroDir.mkdirs();
                //创建mBaseUserPath=/data/user目录并设置权限
                mBaseUserPath = baseUserPath;
                FileUtils.setPermissions(mUsersDir.toString(),
                        FileUtils.S_IRWXU|FileUtils.S_IRWXG
                        |FileUtils.S_IROTH|FileUtils.S_IXOTH,
                        -1, -1);
                        
                // 创建mUserListFile=/data/system/users/userlist.xml文件
                mUserListFile = new File(mUsersDir, USER_LIST_FILENAME);
                
                // 读取用户列表【从userlist.xml文件中读取用户信息,保存到UserManager的成员变量mUsers中】
                readUserListLocked();
                // Prune out any partially created/partially removed users.
                ArrayList<UserInfo> partials = new ArrayList<UserInfo>();
                for (int i = 0; i < mUsers.size(); i++) {
                    UserInfo ui = mUsers.valueAt(i);
                    if ((ui.partial || ui.guestToRemove) && i != 0) {
                        partials.add(ui);
                    }
                }
                for (int i = 0; i < partials.size(); i++) {
                    UserInfo ui = partials.get(i);
                    Slog.w(LOG_TAG, “Removing partially created user #” + i
                            + ” (name=” + ui.name + “)”);
                    removeUserStateLocked(ui.id);
                }
                sInstance = this;
            }
        }
    }
    ……..
  }
   
6.SystemConfig对象的构建
public class SystemConfig {
    ……..
    static SystemConfig sInstance;
    ……..
    final SparseArray<HashSet<String>> mSystemPermissions = new SparseArray<>();
    final ArrayMap<String, String> mSharedLibraries  = new ArrayMap<>(); // 保存系统库,程序运行时需要加载一些必要的库
    final HashMap<String, FeatureInfo> mAvailableFeatures = new HashMap<>(); // 保存硬件支持的特性
    ……..   
    final ArrayMap<String, PermissionEntry> mPermissions = new ArrayMap<>(); // 保存PermissionEntry对象
    ……..   
    public SparseArray<HashSet<String>> getSystemPermissions() {
        return mSystemPermissions;
    }

    public ArrayMap<String, String> getSharedLibraries() {
        return mSharedLibraries;
    }

    public HashMap<String, FeatureInfo> getAvailableFeatures() {
        return mAvailableFeatures;
    }
    
    public ArrayMap<String, PermissionEntry> getPermissions() {
        return mPermissions;
    }
    ……..
    public static SystemConfig getInstance() { // 采用单例模式构造一个SystemConfig对象
        synchronized (SystemConfig.class) {
            if (sInstance == null) {
                sInstance = new SystemConfig();
            }
            return sInstance;
        }
    }
    ……..
    SystemConfig() {
        // Read configuration from system
        readPermissions(Environment.buildPath(Environment.getRootDirectory(), “etc”, “sysconfig”), false);
        // Read configuration from the old permissions dir
        readPermissions(Environment.buildPath(Environment.getRootDirectory(), “etc”, “permissions”), false);
        // Only read features from OEM config
        readPermissions(Environment.buildPath(Environment.getOemDirectory(), “etc”, “sysconfig”), true);
        readPermissions(Environment.buildPath(Environment.getOemDirectory(), “etc”, “permissions”), true);
    }

    void readPermissions(File libraryDir, boolean onlyFeatures) {
        //如果给定目录不存在则返回
        // Read permissions from given directory.
        if (!libraryDir.exists() || !libraryDir.isDirectory()) {
            if (!onlyFeatures) {
                Slog.w(TAG, “No directory ” + libraryDir + “, skipping”);
            }
            return;
        }
        //如果给定目录不可读则返回
        if (!libraryDir.canRead()) {
            Slog.w(TAG, “Directory ” + libraryDir + ” cannot be read”);
            return;
        }
        // 循环读取指定目录下的XML文件
        // Iterate over the files in the directory and scan .xml files
        for (File f : libraryDir.listFiles()) {
            // 跳过platform.xml文件,最后读取该文件
            // We’ll read platform.xml last
            if (f.getPath().endsWith(“etc/permissions/platform.xml”)) {
                continue;
            }
            // 过滤不是以.xml结尾的文件
            if (!f.getPath().endsWith(“.xml”)) {
                Slog.i(TAG, “Non-xml file ” + f + ” in ” + libraryDir + ” directory, ignoring”);
                continue;
            }
            // 过滤不可读的文件
            if (!f.canRead()) {
                Slog.w(TAG, “Permissions library file ” + f + ” cannot be read”);
                continue;
            }
            // 使用PULL方式解析这些XML文件
            readPermissionsFromXml(f, onlyFeatures);
        }
        
        // 读取该文件…/etc/permissions/platform.xml文件
        // Read permissions from …/etc/permissions/platform.xml last so it will take precedence
        final File permFile = new File(Environment.getRootDirectory(), “etc/permissions/platform.xml”);
        // 使用PULL方式解析这些XML文件
        readPermissionsFromXml(permFile, onlyFeatures);
    }
    
    private void readPermissionsFromXml(File permFile, boolean onlyFeatures) {
        // 使用出入的文件permFile构造FileReader对象
        FileReader permReader = null;
        try {
            permReader = new FileReader(permFile);
        } catch (FileNotFoundException e) {
            Slog.w(TAG, “Couldn’t find or open permissions file ” + permFile);
            return;
        }
        
        // 使用PULL方式解析传入的XML文件
        try {
            XmlPullParser parser = Xml.newPullParser();
            parser.setInput(permReader);

            int type;
            while ((type=parser.next()) != parser.START_TAG
                       && type != parser.END_DOCUMENT) {
                ;
            }

            if (type != parser.START_TAG) {
                throw new XmlPullParserException(“No start tag found”);
            }

            if (!parser.getName().equals(“permissions”) && !parser.getName().equals(“config”)) {
                throw new XmlPullParserException(“Unexpected start tag: found ” + parser.getName() +
                        “, expected ‘permissions’ or ‘config'”);
            }

            while (true) {
                XmlUtils.nextElement(parser);
                if (parser.getEventType() == XmlPullParser.END_DOCUMENT) {
                    break;
                }

                String name = parser.getName();
                if (“group”.equals(name) && !onlyFeatures) { // group标签用于建立Android层与Linux层之间的权限映射关系
                    String gidStr = parser.getAttributeValue(null, “gid”); // 读取属性gid的值
                    if (gidStr != null) {
                        int gid = android.os.Process.getGidForName(gidStr);
                        mGlobalGids = appendInt(mGlobalGids, gid);
                    } else {
                        Slog.w(TAG, “<group> without gid at “
                                + parser.getPositionDescription());
                    }

                    XmlUtils.skipCurrentTag(parser);
                    continue;
                } else if (“permission”.equals(name) && !onlyFeatures) {
                    String perm = parser.getAttributeValue(null, “name”); // 读取属性name的值
                    if (perm == null) {
                        Slog.w(TAG, “<permission> without name at “
                                + parser.getPositionDescription());
                        XmlUtils.skipCurrentTag(parser);
                        continue;
                    }
                    perm = perm.intern();
                    readPermission(parser, perm); //【读取权限】

                } else if (“assign-permission”.equals(name) && !onlyFeatures) { //将解析到的内容保存到mSystemPermissions中
                    String perm = parser.getAttributeValue(null, “name”); // 获取属性name的值
                    if (perm == null) {
                        Slog.w(TAG, “<assign-permission> without name at “
                                + parser.getPositionDescription());
                        XmlUtils.skipCurrentTag(parser);
                        continue;
                    }
                    String uidStr = parser.getAttributeValue(null, “uid”); // 获取属性uid的值
                    if (uidStr == null) {
                        Slog.w(TAG, “<assign-permission> without uid at “
                                + parser.getPositionDescription());
                        XmlUtils.skipCurrentTag(parser);
                        continue;
                    }
                    int uid = Process.getUidForName(uidStr); // 根据uidStr字符串获取uid的值
                    if (uid < 0) {
                        Slog.w(TAG, “<assign-permission> with unknown uid \””
                                + uidStr + “\” at “
                                + parser.getPositionDescription());
                        XmlUtils.skipCurrentTag(parser);
                        continue;
                    }
                    perm = perm.intern();
                    HashSet<String> perms = mSystemPermissions.get(uid); // 根据uid获取对应的值
                    if (perms == null) {
                        perms = new HashSet<String>();
                        mSystemPermissions.put(uid, perms); // 如果获取失败则新建一个并保存到mSystemPermissions中
                    }
                    perms.add(perm);
                    XmlUtils.skipCurrentTag(parser);

                } else if (“library”.equals(name) && !onlyFeatures) { // library用于指定系统库
                    //读取属性name的值与属性file的值
                    String lname = parser.getAttributeValue(null, “name”);
                    String lfile = parser.getAttributeValue(null, “file”);
                    if (lname == null) {
                        Slog.w(TAG, “<library> without name at “
                                + parser.getPositionDescription());
                    } else if (lfile == null) {
                        Slog.w(TAG, “<library> without file at “
                                + parser.getPositionDescription());
                    } else {
                        // 保存进程运行库
                        mSharedLibraries.put(lname, lfile);
                    }
                    XmlUtils.skipCurrentTag(parser);
                    continue;

                } else if (“feature”.equals(name)) { // feature标签用来描述设备应该支持的硬件特性
                    String fname = parser.getAttributeValue(null, “name”); //读取属性name的值
                    if (fname == null) {
                        Slog.w(TAG, “<feature> without name at “
                                + parser.getPositionDescription());
                    } else if (isLowRamDevice() && “android.software.managed_users”.equals(fname)) {
                        Slog.w(TAG, “Feature not supported on low memory device “+fname);
                    } else {
                        //创建一个FeatureInfo对象,保存读取到的属性name值,并将这个FeatureInfo对象保存到mAvailableFeatures中
                        //Log.i(TAG, “Got feature ” + fname);
                        FeatureInfo fi = new FeatureInfo();
                        fi.name = fname;
                        //mAvailableFeatures是SystemConfig的成员变量,以HashMap的方式保存硬件支持的特性
                        mAvailableFeatures.put(fname, fi);
                    }
                    XmlUtils.skipCurrentTag(parser);
                    continue;

                } else if (“allow-in-power-save”.equals(name)) {
                    String pkgname = parser.getAttributeValue(null, “package”);
                    if (pkgname == null) {
                        Slog.w(TAG, “<allow-in-power-save> without package at “
                                + parser.getPositionDescription());
                    } else {
                        mAllowInPowerSave.add(pkgname);
                    }
                    XmlUtils.skipCurrentTag(parser);
                    continue;

                } else if (“fixed-ime-app”.equals(name)) {
                    String pkgname = parser.getAttributeValue(null, “package”);
                    if (pkgname == null) {
                        Slog.w(TAG, “<fixed-ime-app> without package at “
                                + parser.getPositionDescription());
                    } else {
                        mFixedImeApps.add(pkgname);
                    }
                    XmlUtils.skipCurrentTag(parser);
                    continue;

                } else {
                    XmlUtils.skipCurrentTag(parser);
                    continue;
                }

            }
            permReader.close();
        } catch (XmlPullParserException e) {
            Slog.w(TAG, “Got execption parsing permissions.”, e);
        } catch (IOException e) {
            Slog.w(TAG, “Got execption parsing permissions.”, e);
        }
    }

    void readPermission(XmlPullParser parser, String name) throws IOException, XmlPullParserException {
        name = name.intern();
        //根据name在mPermissions表中查找对应的PermissionEntry对象,如果不存在,则新建一个并加入到mPermissions表中
        PermissionEntry perm = mPermissions.get(name);
        if (perm == null) {
            perm = new PermissionEntry(name);
            mPermissions.put(name, perm);
        }
        int outerDepth = parser.getDepth();
        int type;
        while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
               && (type != XmlPullParser.END_TAG
                       || parser.getDepth() > outerDepth)) {
            if (type == XmlPullParser.END_TAG
                    || type == XmlPullParser.TEXT) {
                continue;
            }

            String tagName = parser.getName();
            if (“group”.equals(tagName)) {
                String gidStr = parser.getAttributeValue(null, “gid”); // 读取group的gid属性
                if (gidStr != null) {
                    int gid = Process.getGidForName(gidStr); //根据gid字符串,找到对应的gid值
                    perm.gids = appendInt(perm.gids, gid); //设置PermissionEntry对象的gid值
                } else {
                    Slog.w(TAG, “<group> without gid at “
                            + parser.getPositionDescription());
                }
            }
            XmlUtils.skipCurrentTag(parser);
        }
    }
    ……..
}


原文地址: http://blog.csdn.net/ctyjqcq/article/details/49230927

    原文作者:Omni-Space
    原文地址: https://blog.csdn.net/omnispace/article/details/52592210
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞