Android系统-installd守护进程
从前面Android包管理机制(三)PMS处理APK安装中可以了解到PMS在安装APK的时候调用了Installer的函数,而Installer实际是调用了installd中的方法。今天我们就来了解下守护进程installd,看看它做了什么,以及为什么需要有一个守护进程?
installd启动
frameworks/native/cmds/installd/installd.rc
1 | service installd /system/bin/installd |
installd将作为service被init进程启动,同时会创建一个名为installd的socket
frameworks/native/cmds/installd/installd.cpp
1 | int main(const int argc, char *argv[]) { |
上面的代码也比较简单,启动后获取installd socket,监听连接,获取客户端发送的命令并执行。
执行命令
1 | static int execute(int s, char cmd[BUFFER_MAX]) |
execute就是在接收到命令后在cmds中查找对应的指令,然后执行。
1 | struct cmdinfo cmds[] = { |
这个就是cmds数组,第一列是指令名称,第二列是要求的参数个数,第三列是指令对应的执行函数。
以create_app_data为例
frameworks/native/cmds/installd/installd.cpp
1 | static int do_create_app_data(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) { |
frameworks/native/cmds/installd/commands.cpp
1 | int create_app_data(const char *uuid, const char *pkgname, userid_t userid, int flags, |
创建cache和code_cache文件夹,并授予相应的权限。
Installer服务
installd在Framework中对应的是Installer服务。
frameworks/base/services/core/java/com/android/server/pm/Installer.java
1 | public final class Installer extends SystemService |
它是一个SystemService,在系统启动的时候作为核心服务在SystemServer中启动。
1 | private void startBootstrapServices() { |
Install中部分代码
1 | public Installer(Context context) { |
可以看到,Installer在被创建的时候InstallerConnection也被创建了一个实例,createAppData实际调用也是InstallerConnection中的execute方法。所以Installer服务实际是使用InstallerConnection在做具体操作。
frameworks/base/core/java/com/android/internal/os/InstallerConnection.java
1 | public class InstallerConnection { |
可以看到在InstallerConnection中通过socket连接installd服务端,然后将Installer传入的cmd通过socket再传给installd处理。
为什么需要installd
Android已经有了PMS这么复杂的一个服务了,为什么还需要再有一个installd守护进程?
答案其实很简单,system_server以system用户的身份运行,PMS运行在system_server中,所以PMS也是system用户。installd是root用户。
1 | USER PID PPID VSIZE RSS WCHAN PC NAME |
system用户并没有访问应用程序目录的权限。但是作为root用户的installd却可以访问data/data/下的目录,这就是installd存在的原因。