android 系统的属性贯穿整个系统,可以说是android 系统的重要特性之一,属性有很多作用比如启动服务,因为属性在android系统中是全局的,所以任何一个进程都可以读取,但是却有权限的控制,早期版本对于属性的读取都是可以的,但是写入却要按照用户组权限来控制。最新的版本所有的属性的读取和写入必须满足selinux的控制,因此安全性更高。
早起版本的属性在init中初始化,并且建立socket服务监听,因为所有的属性必须由init来写入。而读取是都可以的。提供给用户的读取写入属性接口在bionic 中,读取是直接的,而写入确实向init发送socket请求来完成。并且init会对于属性的写入做一些检查。
AndroidP的属性服务于早期版本结构上并无差别,只是可能支持的多平台,buonic中提供给用户接口部分做了增加。服务部分对于数据结构做了一些优化,变得更具有c++风格了,而且加入了很多stl 14 的新特性。可能对于代码的阅读有一定的复杂度,但是对于老码农来说貌似并无太大差别。
总的来说属性服务功能强大,但是代码结构简单。
当init进程启动的时候会调用
/system/core/init/init.cpp-->main-->property_init 函数完成属性服务的初始化,那么这个属性服务到底做了什么呢?
- 新建目录/dev/__properties__
- 加载selinux中的属性标签 并写入/dev/__properties__/property_info 中去
- 初始化属性内存空间
property_load_boot_defaults 函数负责加载解析一下系统属性
start_property_service 函数 创建socket服务,等待用户请求,处理属性更新和写入,或者启动服务等功能
对于用户端:
需要支持两个函数property_set,property_get,一个设置熟悉,一个获取属性。
property_get 调用__system_property_get 函数 这个函数其实就是直接从文件中读取属性值并返回。这里不再跟踪了。
property_set 函数调用__system_property_set 函数 负责跟服务端连接并发送
prop_msg msg;
memset(&msg, 0, sizeof msg);
msg.cmd = PROP_MSG_SETPROP;
strlcpy(msg.name, key, sizeof msg.name);
strlcpy(msg.value, value, sizeof msg.value);
return send_prop_msg(&msg);
其实P版本的__system_property_set函数写的很精妙,我建议大家都读读。有益身心健康呀!