PackageManagerService分析之一
来源:互联网 发布:网络订票如何选下铺 编辑:程序博客网 时间:2024/06/06 19:28
1, 基本概念
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的构造方法很长很长,主要包括以下逻辑
- 扫描目标文件夹之前的准备工作。
- 扫描目标文件夹。
- 扫描之后的工作。
2, 准备工作
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>();
流程图如下,
2.1 Settings
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突然断电等问题。
2.2 addSharedUserLPw
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; // systempublic static final int PHONE_UID = 1001;// telephonypublic static final int SHELL_UID = 2000;// user shellpublic 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了
2.3 XML文件扫描
接下来是扫描系统目录下与系统权限相关的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); } }
- PackageManagerService分析之一
- PackageManagerService分析
- Android PackageManagerService详细分析
- Android PackageManagerService详细分析
- Android PackageManagerService详细分析
- Android PackageManagerService详细分析
- Android PackageManagerService详细分析 .
- Android PackageManagerService详细分析
- Android PackageManagerService详细分析
- Android PackageManagerService详细分析
- Android PackageManagerService详细分析
- Android PackageManagerService详细分析
- Android PackageManagerService详细分析
- PackageManagerService启动源码分析
- PackageManagerService(Android5.1)分析
- PackageManagerService分析之二
- Android -- PackageManagerService初始化分析
- PackageManagerService分析(一)
- 智能一代云平台(十五):Keepalived+Nginx实现高可用,反向代理---Nginx安装及配置
- 关于JFrame里setbackground()失效的解释
- CodeForces
- 超越spark性能数百倍的性能测试
- 8 HBase结构介绍
- PackageManagerService分析之一
- leetCode 483. Smallest Good Base
- 7 MapReduce进阶之shuffle阶段
- SpringMVC概念原理分析
- 查看内存使用情况
- 关于java代码jtable不显示表头的解决
- 互联网+农业:十万亿市场的各个环节都在这里了
- Servlet监听器
- Trivial Problem CodeForces