Android系统中有许多属性,属性由两个部分组成:name & value,可以使用这些属性来记录系统设置或进程之间的信息交换。Android系统在启动过程时会按序从以下几个文件中加载系统属性:
1./default.prop
2./system/build.prop
3./system/default.prop
4./data/local.prop
5./data/property/*
属性会按照以上文件的顺序进行加载,并且后加载的属性值会更新原先的属性值。在系统重启后,有的属性会消失,但可以定义以“persist.”为开头的属性值,当在系统中通过setprop命令设置这个属性时,就会在/data/property/目录下会保存一个副本。这样在系统重启后,按照加载流程这些persist属性的值就不会消失了。
如果要在系统中添加新的persist属性的话,要满足添加的属性其前缀必须为property_service.c文件中property_perms[]矩阵中定义的。
property_perms[] = { { "net.dns", AID_RADIO, 0 }, { "net.", AID_SYSTEM, 0 }, { "dev.", AID_SYSTEM, 0 }, { "runtime.", AID_SYSTEM, 0 }, { "sys.", AID_SYSTEM, 0 }, { "service.", AID_SYSTEM, 0 }, { "persist.sys.", AID_SYSTEM, 0 }, { "persist.service.", AID_SYSTEM, 0 }, …… { NULL, 0, 0 } };
当然我们也可以添加自己所需要的persist属性前缀,比如“persist.test.”前缀,只需要在property_perms[]矩阵中添加{"persist.test.", AID_SYSTEM, 0}即可。
使用persist属性来调用脚本文件可以分3步完成:添加脚本文件;添加persist属性;在init.<device>.rc中添加service。
step1.添加脚本文件
将脚本文件“fortest.sh”放到source/system/core/rootdir/etc/目录下,当然也可以放在其它位置。然后在source/device/厂商/设备/目录下的device.mk文件中添加PRODUCT_COPY_FILES命令
PRODUCT_COPY_FILES += /system/core/rootdir/etc/fortest.sh:/system/etc/fortest.sh
通过PRODUCT_COPY_FILES命令可以将在源码中添加的脚本文件“fortest.sh”最终生成到系统的/system/etc/目录下。若想通过persist属性运行该脚本文件的话,仅在系统中添加脚本文件是不够的,这是因为现在/system/etc/fortest.sh脚本还没有可执行权限。
为了给脚本文件添加用户模式 & 文件权限,我有尝试在源码init.<device>.rc中的on boot section添加
chown root root /system/etc/fortest.sh chmod 0777 /system/etc/fortest.sh
但是调试后发现,通过ls /system/etc/fortest.sh -al后显示:-rw-r--r-- root root /system/etc/fortest.sh,没有完成预期目标啊,有尝试在其它section放入该段代码,但一直没有成功。
最后通过在android_filesystem_config.h中实现添加文件的uid & gid & 操作权限。在android_filesystem_config.h中的android_files[]矩阵中添加
{00777, AID_SYSTEM, AID_SHELL, "system/etc/fortest.sh"}
step2.添加persist属性
由前文可以知道,添加自定义的persist属性可以使用android源码中已经存在的前缀,当然也可以使用自己定义的前缀。只需要在propery_service.c文件中的property_perms[]矩阵中添加自定义的persist.test.前缀。
之前有在init.<device>.rc文件中通过“setprop persist.test.test 0”也可以完成该功能,但是由于每次系统重启时,init进程会加载init.rc & init.<device>.rc文件,所以不可避免的都要运行一次“setprop persist.test.test 0”该命令。这样导致persist.test.test每次在系统重启后都恢复到原来的初始值。这与persist属性想要实现的作用有点矛盾了。
在source/device/厂商/设备/BoardConfig.mk文件中添加自定义的persist.test.test属性,并将其default value设置为1 or 0。
ADDITONAL_DEFAULT_PROPERTIES += persist.test.test 0
这样就可以在系统中的default.prop中生成persist.test.test属性,并且其初始值为0。除了该添加方法外,也可以在source/device/厂商/设备/system.prop中添加自定义的属性。
step3.在init.<device>.rc中添加service
关于init.rc的介绍可以参照source/system/core/readme.txt。init由4个部分组成:Actions、Services、Commands & Options。
【Actions】
Actions其实就是一组被命名的命令序列。actions 都有一个触发条件,触发条件决定了action何时执行。当一个事件发生如果匹配action的触发条件,那么这个action将会被添加到预备执行队列的尾部(除非它已经在队列当中)
每一个action中的命令将被顺序执行。init进程负责在其它activities(如:设备创建/销毁,属性设置,进程重启)之间执行这些命令序列。
【Services】
services 是一些由init 启动 和 重新(如果有需要)启动的程序,当然这些程序如果是存在的。
【Options】
options 是service的修饰符,用来告诉init 怎样及何时启动service。
在init.<device>.rc中on boot section后添加一个新的service,命名为new,其对应的脚本文件位置为/system/etc/fortest.sh,将user & group设置为root,自动启动设置为disable,并且该服务只启动一次。
通过Options命令实现当persist.test.test属性发生变化时,开启service “new”。
service new /system/etc/fortest.sh user root group root disable oneshot on property:pesist.test.test=1 start new on property:persist.test.test=0 stop new
总结:本文主要描述添加persist属性,脚本文件和service的流程,当persist属性值发生变化时,开启服务,并最终调用脚本文件。
ps:希望有在init.rc文件中通过chmod命令添加文件权限成功的大神给予帮助。谢谢!
参考文章:http://www.cnblogs.com/leaven/archive/2010/12/25/1917007.html
http://blog.sina.com.cn/s/blog_6b936f150101jhfl.html