android守护进程installd分析

最近在研究android的apk安装,从PackageManagerService开始看的,包括解析包PackagePaser,连接底层的Installer,继而转到c部分的installd,(位于frameworks/base/cmds/installd),installd是个很小的程序,主要文件installd.c处理java层Installer的连接,command.c处理真正的命令,包括install,remove,getsize等。
搜了一些installd的分析,看到唯一一篇比较接近的,但是发现他讲到最后其实都是在讲其中的socket连接,原文地址: android installd分析

虽然说installd这个程序很小,其中的代码也不是很复杂,就我现在的理解是这样的,它主要是做了些创建目录的操作
比如install
C/C++ code
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
int  install( const  char  *pkgname, uid_t uid, gid_t gid)
{
     char  pkgdir[PKG_PATH_MAX];
     char  libdir[PKG_PATH_MAX];
 
     if  ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) {
         LOGE( "invalid uid/gid: %d %d\n" , uid, gid);
         return  -1;
     }
 
     if  (create_pkg_path(pkgdir, PKG_DIR_PREFIX, pkgname, PKG_DIR_POSTFIX))
         return  -1;
     if  (create_pkg_path(libdir, PKG_LIB_PREFIX, pkgname, PKG_LIB_POSTFIX))
         return  -1;
 
     if  (mkdir(pkgdir, 0751) < 0) {
         LOGE( "cannot create dir '%s': %s\n" , pkgdir,  strerror ( errno ));
         return  - errno ;
     }
     if  (chown(pkgdir, uid, gid) < 0) {
         LOGE( "cannot chown dir '%s': %s\n" , pkgdir,  strerror ( errno ));
         unlink(pkgdir);
         return  - errno ;
     }
     if  (mkdir(libdir, 0755) < 0) {
         LOGE( "cannot create dir '%s': %s\n" , libdir,  strerror ( errno ));
         unlink(pkgdir);
         return  - errno ;
     }
     if  (chown(libdir, AID_SYSTEM, AID_SYSTEM) < 0) {
         LOGE( "cannot chown dir '%s': %s\n" , libdir,  strerror ( errno ));
         unlink(libdir);
         unlink(pkgdir);
         return  - errno ;
     }
     return  0;
}

既然只是创建目录,为什么不直接又java来做呢? 感觉installd很鸡肋诶,求各位分析一下!

在java层的操作其实也没什么,就是解析AndroidManifest.xml,还有把包拷贝到/data/app下,把lib拷贝到data/data/<appname>/lib,还有dex文件拷贝到/data/dalvik-cache下。
其实这些我手动解压出来然后考过去也是可以运行的,呵呵。我觉得应该把这些操作放到底层来做才更合理吧。
<think> 我们正在讨论Android系统中的Binder:installd进程。installdAndroid系统中一个重要的守护进程,负责处理应用程序的安装、卸载、优化等操作。它作为系统服务运行,通过Binder IPC机制与其他系统组件(如PackageManagerService)通信。下面将详细解释其作用和工作原理。 ### Binder:installd进程的核心作用 1. **应用安装管理** - 创建应用私有目录(如`/data/data/<包名>`) - 设置目录权限(Linux用户/组隔离) 2. **Dex字节码优化** - 将APK中的Dex文件转换为优化后的Odex文件(`dexopt`过程) - ART模式下生成AOT编译的OAT文件 3. **存储空间管理** - 维护应用大小统计(通过`quota`机制) - 清理残留文件(卸载时删除所有私有数据) 4. **多用户支持** - 为每个用户创建独立的数据空间(`/data/user/<用户ID>/`) - 处理用户删除时的数据清理 ### 关键操作流程(以安装APK为例) ```java // 伪代码展示PackageManagerService与installd的交互 class PackageManagerService { void installPackage(APKFile) { // 1. 通过Binder调用installd创建目录 installd.createAppDataDir("com.example.app", userId); // 2. 复制APK到/data/app目录 copy(APKFile, "/data/app/com.example.app/base.apk"); // 3. 触发Dex优化 installd.dexopt("/data/app/com.example.app/base.apk", targetIsa, // 如arm64-v8a profileFile); // 用于PGO优化 // 4. 更新应用数据库 updatePackageSettings(); } } ``` ### 安全机制 ```markdown - **权限隔离**:installd以`root`身份运行,但执行操作时会切换到`system`或`install`组权限 - **SELinux策略**:限制仅允许特定进程(如system_server)通过Binder调用installd - **操作验证**:检查调用者UID(仅system_server可访问) ``` ### 性能优化技术 ```python # Python伪代码模拟installd的Dex优化任务队列 import threading class InstalldDaemon: def __init__(self): self.task_queue = [] self.worker = threading.Thread(target=self._process_tasks) self.worker.start() def add_task(self, task): self.task_queue.append(task) def _process_tasks(self): while True: task = self.task_queue.pop(0) if task.type == DEXOPT: # 根据CPU负载动态调整并发度 if cpu_load < 50%: run_parallel_optimization(task) else: run_serial_optimization(task) ``` §§相关问题§§ 1. 在Android多用户场景下,installd如何隔离不同用户的相同应用数据? 2. Dex优化过程中使用的`dex2oat`工具支持哪些编译策略(如speed、space)?如何通过ADB命令手动触发? 3. 当应用安装失败时,如何通过`logcat`过滤installd的日志定位问题? 4. 在Android 10引入的APEX模块化更新中,installd承担了哪些新职责? </think> 在Android系统中,`Binder:installd`是系统级守护进程,负责**应用生命周期关键操作**,通过Binder IPC机制与系统服务(如PackageManagerService)通信。其核心作用如下: --- ### 核心职责解析 ```java // 伪代码展示installd工作流程 class InstalldService extends IInstalld.Stub { // 1. 创建应用数据目录 public void createAppDataDir(String uuid, String packageName, int userId) { File dataDir = new File("/data/data/" + packageName); setPermissions(dataDir, 0751, "system", "system"); // 设置权限 } // 2. 执行Dex优化 public void dexopt(String apkPath, int uid) { runCmd("dex2oat --input-file=" + apkPath + " --output=oat"); // 生成OAT文件 } // 3. 卸载清理 public void destroyAppDataDir(String packageName, int userId) { deleteRecursive("/data/data/" + packageName); // 递归删除私有数据 deleteRecursive("/data/app/" + packageName); // 删除APK目录 } } ``` --- ### 具体作用详解 1. **应用安装管理** - 创建应用沙箱目录:`/data/data/<包名>`(设置Linux权限和SELinux标签) - 挂载应用专属文件系统(FUSE/Sdcardfs) - 验证APK签名和权限树 2. **Dex字节码优化** - 调用`dex2oat`将Dex转换为机器码(生成`.odex`或`.oat`文件) - ART模式下执行AOT编译(Android 7.0+) - 管理编译配置文件(`.prof`)实现Profile-Guided Optimization 3. **存储空间管理** - 执行应用迁移(如Adoptable Storage功能) - 维护存储配额(`quota`机制限制应用磁盘占用) - 清理过期ART缓存(`/data/dalvik-cache`) 4. **多用户支持** - 为每个用户创建独立数据副本(`/data/user/<ID>/`) - 处理跨用户数据克隆(Work Profile场景) --- ### 安全机制 ```markdown - **权限隔离**:以`root`身份运行但降权操作,通过SELinux策略`installd.te`限制 - **IPC验证**:仅接受来自`system_server`的Binder调用(UID 1000) - **沙箱防护**:使用Linux Capability机制(`CAP_DAC_OVERRIDE`) ``` --- ### 故障排查示例 ```bash # 通过logcat过滤installd日志 adb logcat -s installd # 常见错误码解析: E/installd: Failed to delete /data/data/com.example: Device or resource busy → 表示文件被占用(需lsof检查进程) E/installd: dexopt failed on /data/app/xxx/base.apk: Permission denied → SELinux策略冲突(需audit2allow分析) ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值