Android 7.0预制应用为可卸载

最近在做CTA认证的时候有个需求,需要预制两个应用为可卸载的方式,且恢复出厂设置之后,可以重新安装。

思路:

  1. 预制应用需要编译输出在/system/preinstall目录
  2. 系统首次运行的时候,需要通过脚本将输出的apk拷贝到/data/app目录

应用编译输出到指定目录,通过在Android.mk文件中添加如下字段实现:

LOCAL_MUDULE_PATH := $(PRODUCT_OUT)/system/preinstall

接下来需要实现应用的拷贝逻辑

#!/system/bin/sh
if [ ! -f "/data/app/installed" ]; then
  chmod 777 /data/app/
  cp -rf /system/preinstall/* /data/app/
  echo "1" > /data/app/installed
  chmod -R 777 /data/app/*
fi

这段脚本的意思是

  1. 首先判断/data/app目录是否存在installed文件
  2. installed文件不存在的情况下,首先对/data/app 赋读写权限。
  3. 然后拷贝/system/preinstall下的所有文件夹到/data/app目录
  4. 创建installed文件,表示已经拷贝完成,下一次开机就不再执行
  5. 给/data/app下所有文件以及文件夹赋权限。

这里遇到了一个问题,使用notepad++编写脚本后push到/system/bin/目录运行,提示"if unmatched"的语法问题,一度以为系统将sh语法支持裁剪了,后面cat了install-recovery.sh查看后,发现系统是支持if语句的,是notepad++编写的字符格式有问题,我把install-recovery.sh pull下来,基于这个文件修改脚本再push就好了。

脚本编译好了之后,需要将其编译进系统里面,在device/xxx/common目录下找到base.mk,添加如下字段:

PRODUCT_COPY_FILES += preload.sh存放路径:preload.sh需要输出的路径
exp:
PRODUCT_COPY_FILES += device/qcom/common/preload.sh:system/bin/preload.sh

添加完成编译后,会发现out目录下的/system/bin中有preload.sh,且其会被打包进system.img

脚本输出到system分区了,还需要在开机启动的时候,执行这个脚本。一般都由init进程触发。

高通平台的init执行动作,描述在device/qcom/common/rootdir/etc/init.qcom.rc文件中。需要在该文件中添加如下代码:

service preload /system/bin/sh /system/bin/preload.sh
    class late_start
    user root
    group root
    oneshot

添加完成后,因为在android 7.0的系统中存在selinux的安全监测,我们需要配置对应的策略。对应高通平台,需要修改device/qcom/sepolicy/msm8937/init_shell.te添加如下代码

allow qti_init_shell apk_data_file:dir { create read write open search getattr setattr add_name };
allow qti_init_shell apk_data_file:file { create read write open getattr setattr };

全部配置完成之后,重编系统,即可。

你可能感兴趣的:(android,framework)