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
總結
以上是生活随笔為你收集整理的PackageManagerService启动过程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AndroidL的checkPermis
- 下一篇: Android系统的启动流程简要分析