赞
踩
PackageManagerService(简称PMS), 是android系统中一个核心的服务,
它负责系统中Package的管理,应该程序的安装、卸载等.在SystemServer的startBootstrapServices方法启动。
- mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
- mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
PMS的main方法如下,
- public static PackageManagerService main(Context context, Installer installer,
- boolean factoryTest, boolean onlyCore) {
- PackageManagerService m = new PackageManagerService(context, installer,
- factoryTest, onlyCore);
- ServiceManager.addService("package", m); // 注册
- return m;
- }
看来所有动作都在PMS的构造方法中完成的。
再看看PMS的结构可知,PMS服务也是一个Binder服务,
public class PackageManagerService extends IPackageManager.Stub {
在ActivityThread的getPackageManager方法中,可以获取PMS服务。
- if (sPackageManager != null) {
- //Slog.v("PackageManager", "returning cur default = " + sPackageManager);
- return sPackageManager;
- }
- IBinder b = ServiceManager.getService("package");
- //Slog.v("PackageManager", "default service binder = " + b);
- sPackageManager = IPackageManager.Stub.asInterface(b);
- //Slog.v("PackageManager", "default service = " + sPackageManager);
- return sPackageManager;
- }
PMS的构造方法很长很长,主要包括以下逻辑
PMS的构造方法关于Settings部分代码如下,
- mSettings = new Settings(mPackages);
- mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
- ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
- mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
- ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
- mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
- ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
- mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
- ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
- mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
- ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
- mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
- ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
mPackages是一个ArrayMap变量,
- @GuardedBy("mPackages")
- final ArrayMap<String, PackageParser.Package> mPackages =
- new ArrayMap<String, PackageParser.Package>();
流程图如下,
Settings的构造方法如下,
Settings(Object lock) { this(Environment.getDataDirectory(), lock); } Settings(File dataDir, Object lock) { mLock = lock; mRuntimePermissionsPersistence = new RuntimePermissionPersistence(mLock); 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"); mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml"); mPackageListFilename = new File(mSystemDir, "packages.list"); FileUtils.setPermissions(mPackageListFilename, 0640, SYSTEM_UID, PACKAGE_INFO_GID); // Deprecated: Needed for migration mStoppedPackagesFilename = new File(mSystemDir, "packages-stopped.xml"); mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml"); }
新建了5个文件夹,
- private final File mSettingsFilename;
- private final File mBackupSettingsFilename;
- private final File mPackageListFilename;
- private final File mStoppedPackagesFilename;
- private final File mBackupStoppedPackagesFilename;
Environment.getDataDirectory()返回/data目录,然后创建/data/system/目录,并设置它的权限,
并 在/data/system目录中创建5个文件。packages.xml就是保存了系统所有的Package信息,
packages-backup.xml是packages.xml的备份,防止在写packages.xml突然断电等问题。
- mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
- ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
调用addSharedUserLPw将几种SharedUserId的名字和它对应的UID对应写到Settings当中。
关于 SharedUserId的使用,在后面介绍APK的安装过程中再来分析. Process中提供的UID列表如下,
- public static final int ROOT_UID = 0;
- public static final int SYSTEM_UID = 1000; // system
- public static final int PHONE_UID = 1001;// telephony
- public static final int SHELL_UID = 2000;// user shell
- public static final int LOG_UID = 1007;// log group
- public static final int WIFI_UID = 1010;// WIFI
- •••
Settings中的addSharedUserLPw方法如下,
SharedUserSetting addSharedUserLPw(String name, int uid, int pkgFlags, int pkgPrivateFlags) { 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; } s = new SharedUserSetting(name, pkgFlags, pkgPrivateFlags); s.userId = uid; if (addUserIdLPw(uid, s, name)) { mSharedUsers.put(name, s); return s; } return null; }
首先根据name, pkgFlags, pkgPrivateFlags等信息构造SharedUserSetting,然后添加到mSharedUsers的ArrayMap中。
- final ArrayMap<String, SharedUserSetting> mSharedUsers =
- new ArrayMap<String, SharedUserSetting>();
例如在SystemUI.apk的AndroidManifest.xml文件中,有关键代码:
- <mainfest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.systemui"
- coreApp="true"
- android:sharedUserId="android.uid.system"
- android:process="system">
在该标签中,声明了一个android:sharedUserId的属性,其值为“android.uid.system”。sharedUserId和UID有关,它的作用是
1,两个或者多个声明了同一种sharedUserid的APK可共享彼此的数据,并且可运行在同一进程中。
2,通过声明特定的sharedUserId,该APK所在的进程将被赋予指定UID。
例如SystemUI声明了system的uid,运行SystemUI的进程就可享有system用户所对应的权限了,实际上就是将该进程的UID设置为system的uid了
接下来是扫描系统目录下与系统权限相关的xml文件,新建文件,处理线程和Handler等。
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; } mInstaller = installer; mPackageDexOptimizer = new PackageDexOptimizer(this); mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper()); mOnPermissionChangeListeners = new OnPermissionChangeListeners( FgThread.get().getLooper()); getDefaultDisplayMetrics(context, mMetrics); SystemConfig systemConfig = SystemConfig.getInstance(); mGlobalGids = systemConfig.getGlobalGids(); mSystemPermissions = systemConfig.getSystemPermissions(); mAvailableFeatures = systemConfig.getAvailableFeatures();
新建文件
- File dataDir = Environment.getDataDirectory();
- 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");
- mRegionalizationAppInstallDir = new File(dataDir, "app-regional");
解析系统权限文件, 主要是解析系统目录下xml文件,获得设备相关的权限.
例如该设备是否支持蓝牙,wifi等
- 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.setGids(perm.gids, perm.perUser);
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。