android 系统属性介绍
本文属于原创,转载请声明。
前言
Android系统中有一套全局统一的属性管理机制,每个属性都有一个名称和值。属性被大量使用在Android系统中,用来记录系统设置或进程之间的信息交换。每一个安卓的工作者,无论是上层还是底层都必须深刻清晰的理解使用系统属性。
一.属性类别
ro
开头的属性,表明该属性是只读的,重启失效。系统启动之后第一次设置之后不能修改,重启之后不保存。persist
开头的属性,表明该属性可修改的,重启还保存原来的值。ctrl.start
和ctrl.stop
两个属性比较特殊,是用来启动和停止init.rc
中定义的服务(ini服务相关的可以参考我的另一篇博客:https://blog.csdn.net/u012890170/article/details/80659425)
一旦我们设置ctrl.start
等一某个服务,init进程就会启动这个服务。设置ctrl.stop
就会去停止某个服务。- 其他格式的都是:可修改,重启不保存。
二.属性权限
当然上面所说的可修改也是有一定条件的,就是有权限的用户才可以修改和设置。
在文件中/system/core/init/property_service.c
说明了不同开头的属性对应不同的权限
struct {
const char *prefix;
unsigned int uid;
unsigned int gid;
} property_perms[] = {
{ "net.rmnet0.", AID_RADIO, 0 },
{ "net.gprs.", AID_RADIO, 0 },
{ "net.ppp", AID_RADIO, 0 },
{ "net.qmi", AID_RADIO, 0 },
{ "net.lte", AID_RADIO, 0 },
{ "net.cdma", AID_RADIO, 0 },
{ "ril.", AID_RADIO, 0 },
{ "gsm.", AID_RADIO, 0 },
{ "persist.radio", AID_RADIO, 0 },
{ "net.dns", AID_RADIO, 0 },
{ "sys.usb.config", AID_RADIO, 0 },
{ "net.", AID_SYSTEM, 0 },
{ "dev.", AID_SYSTEM, 0 },
{ "runtime.", AID_SYSTEM, 0 },
{ "hw.", AID_SYSTEM, 0 },
{ "sys.", AID_SYSTEM, 0 },
{ "sys.powerctl", AID_SHELL, 0 },
{ "service.", AID_SYSTEM, 0 },
{ "wlan.", AID_SYSTEM, 0 },
{ "bluetooth.", AID_BLUETOOTH, 0 },
{ "dhcp.", AID_SYSTEM, 0 },
{ "dhcp.", AID_DHCP, 0 },
{ "debug.", AID_SYSTEM, 0 },
{ "debug.", AID_SHELL, 0 },
{ "log.", AID_SHELL, 0 },
{ "service.adb.root", AID_SHELL, 0 },
{ "service.adb.tcp.port", AID_SHELL, 0 },
{ "persist.sys.", AID_SYSTEM, 0 },
{ "persist.linkin.", AID_SYSTEM, 0 },
{ "persist.service.", AID_SYSTEM, 0 },
{ "persist.security.", AID_SYSTEM, 0 },
{ "sys_graphic.", AID_MEDIA, 0 },//add for sys_graphic.cam_hal.ver in cameraHal
{ "persist.service.bdroid.", AID_BLUETOOTH, 0 },
{ "selinux." , AID_SYSTEM, 0 },
{ "persist.audio.", AID_SYSTEM, 0 },
{ "persist.audio.", AID_MEDIA, 0 },
{ "media.", AID_SYSTEM, 0 },
{ "media.", AID_MEDIA, 0 },
{ "dolby.audio", AID_MEDIA, 0 },
{ "dolby.audio", AID_SYSTEM, 0 },
{ "persist.dolby.", AID_MEDIA, 0 },
{ "persist.dolby.", AID_SYSTEM, 0 },
{ "persist.bootanima.", AID_GRAPHICS, 0 },
{ "sys_graphic.", AID_SYSTEM, 0 },
{ NULL, 0, 0 }
};
实际上用不同用户权限限制的实现也是在这个文件中
就是通过调用下面的函数进行权限的检查
static int check_control_perms(const char *name, unsigned int uid, unsigned int gid, char *sctx) {
if(strcmp("iso_operate",name)==0)
{
return 1;
}
int i;
if (uid == AID_SYSTEM || uid == AID_ROOT) //判读是不是 SYSTEM/ROOT
return check_control_mac_perms(name, sctx);
/* Search the ACL */
for (i = 0; control_perms[i].service; i++) { //如果普通用户,判读uid gid ,如果有权限就返回相关的逻辑,没权限返回0
if (strcmp(control_perms[i].service, name) == 0) {
if ((uid && control_perms[i].uid == uid) ||
(gid && control_perms[i].gid == gid)) {
return check_control_mac_perms(name, sctx);
}
}
}
return 0;
}
如果我们上层有些需要使用一些属性进行某些逻辑的实现等,可以在这里加入过滤,不进行权限的限制或者放开某个应该的使用权限。
三.不同层操作属性的不同方法
Java层
String data = SystemProperties.get("sys.haha.karaoke_mode");
SystemProperties.set("sys.haha.karaoke_mode",data);
这里只列出最基本的接口,还有其他获取boolean或者String的接口
native层
#include <cutils/properties.h>
property_set("persist.sys.pic_time", delay);
shell
setprop ro.haha.mode mode0
getprop ro.haha.mode