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