赞
踩
需求
每次开机之后,后台自动安装一个apk。(实现方法可能有多种,这里只记录我用的)
需求分析
我的思路是写一个脚本放到系统中,然后每次开机的时候在rc文件中启动这个脚本服务。
具体实现步骤
第一,将所需要安装的apk文件保存在系统,我这里是放到system/etc/目录下面了,放在system分区下有个好处就是不会被用户删掉,当然不能放太多无意义的东西,否则你的img会变得很大。可以通过mk中的PRODUCT_COPY_FILE进行操作:
PRODUCT_COPY_FILE=xxx/xx.apk:system/etc/xx.apk
第二,将安装脚本写好编进系统中去,这个脚本文件很简单,判断apk是否存在并调用pm执行安装,如下:
- #!/system/bin/sh
-
- # Install xx.apk if not already installed
- if [ -f /system/etc/xx.apk ]; then
- pm install -r /system/etc/xx.apk
- fi
和上面copy apk文件一样,将脚本文件copy到system/bin/目录下,如下:
PRODUCT_COPY_FILE=xxx/install_app.sh:system/bin/install_app.sh
第三,在rc文件中启动这个脚本服务,我们在rc文件中声明这个服务:
- service service_install /system/bin/install_app.sh
- user root
- group root
- disabled
- oneshot
这里简单说一下上面代码的意思,
第一个service表示声明服务,后面的service_install指的是service的名字,后面跟的是文件路径;
disable和oneshot表示该服务只执行一次,运行完就设置为禁用。
既然是开机的时候执行,那么就需要一个触发点,这里用到rc里面的on property语法,sys.boot_completed=1,如下:
- on property:sys.boot_completed=1
- start service_install
然后编译烧写整个系统就行。
遇到的问题
烧录开机之后发现服务并没有起来,查看kernel的log发现是权限问题。为了确认这个问题,我尝试把系统SELinux关掉,发现服务是能正常起来的。
解决问题
我们需要通过log来一条条的加上权限,需要添加的权限可能比较多,我这里就只举一个例子:
avc: denied { execute } for pid=3689 comm="install_app.s" name="sh" dev="dm-0" ino=979 scontext=u:r:service_install:s0 tcontext=u:object_r:shell_exec:s0 tclass=file permissive=0
以上log里面关键的地方我标红了,这个log对应告诉我们一个权限需要如何添加,需要的信息都在里面,转化成allow如下:
allow service_install shell_exec:file execute;
基本算是一个死公式了,这条语句需要添加到service_install.te文件里面,由于这个服务是我们自定义的,需要先创建te文件,我们在system/sepolicy/源码目录里面添加service_install.te文件,内容如下:
- # service_install
-
- type service_install, domain;
- type service_install_exec, exec_type, file_type;
-
- init_daemon_domain(service_install)
然后在system/sepolicy/file_contexts中添加以下内容:
/system/bin/install_app.sh u:object_r:service_install_exec:s0
然后就可以将上面的allow语句添加进去了。
总结
这个需求解决方案还有许多,比如直接在上层服务中进行操作,调用PackageManagerService的安装接口,不过应该也会涉及到权限问题。但是我觉得在rc文件中处理操作起来要更明确一点。
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。