Android 属性文件build.prop,获取属性以及设置属性

本文简要分析一下build.prop是如何生成的。以及Android属性系统的管理,获取及设置方法。

build.prop的生成

Android的build.prop文件是在Android编译时收集的各种property(LCD density/语言/编译时间, etc.),编译完成之后,文件生成在out/target/product/XXXX/system/目录下。
(1)build.prop的生成是由make系统解析build/core/Makefile完成。Makefile中首先定义各种变量,这在下一步执行时会用到。比如:

PRODUCT_DEFAULT_LANGUAGE="$(calldefault-locale-language,$(PRODUCT_LOCALES))" \  
PRODUCT_DEFAULT_REGION="$(calldefault-locale-region,$(PRODUCT_LOCALES))" \  

(2)Makefile中调用build/tools/buildinfo.sh执行脚本,并输出到build.prop。Buildinfo.sh很简单,只是echo一些属性,比如:

echo"ro.product.locale.language=$PRODUCT_DEFAULT_LANGUAGE"  
echo"ro.product.locale.region=$PRODUCT_DEFAULT_REGION"  

(3)Makefile中直接把$(TARGET_DEVICE_DIR)/system.prop的内容追加到build.prop中,还会收集ADDITIONAL_BUILD_PROPERTIES中的属性,追加到build.prop中。
ADDITIONAL_BUILD_PROPERTIES又会收集PRODUCT_PROPERTY_OVERRIDES中定义的属性,如下:

ADDITIONAL_BUILD_PROPERTIES:= \  
        $(ADDITIONAL_BUILD_PROPERTIES)\  
        $(PRODUCT_PROPERTY_OVERRIDES)  

通过build.prop生成过程的分析,可以用以下方式修改原有的属性或加入自己定义属性:

  1. buildinfo.sh;
  2. system.prop;
  3. ADDITIONAL_BUILD_PROPERTIES或PRODUCT_PROPERTY_OVERRIDES。

属性的加载、读、设置

Android中属性从多个地方加载,加载的属性保存在/dev/__properties__中,该文件由init进程创建并管理,其他进程只具备读的权限。当需要设置属性时,则通过socket通知到init进程设置。

属性的加载

首先init进程在启动的时候回进行属性系统的初始化:

property_init();
void property_init(void)
{
    init_property_area();
}

init_property_area会创建/dev/__properties__内存文件,并通过mmap将其映射为一个内存指针。

其后,将会加载各种属性

  1. process_kernel_cmdline根据kernel及uboot环境变量,生成ro属性;
  2. property_load_boot_defaults函数,将从/default.prop加载部分属性到属性系统。
  3. init进程触发“property_service_init”action后,即调用property_service_init_action函数,该函数会加载大部分属性。如下:
static int property_service_init_action(int nargs, char **args)
{
    /* read any property files on system or data and
     * fire up the property service.  This must happen
     * after the ro.foo properties are set above so
     * that /data/local.prop cannot interfere with them.
     */
    start_property_service();
    return 0;
}

start_property_service()会从这几个地方加载属性:
1)/system/build.prop文件中的属性
2)/system/default.prop文件中的属性
3)/data/property目录中读取persist打头的文件,读取的文件内容更新到文件名对应的属性中。
所以需要注意的是persist打头的属性,是可以保存的,而其他属性则是加载在内存中,不会保存。

读取,设置属性

相关函数:
C层
包含头文件:cutils/properties.h
需链接到动态库:libcutils.so
读写函数:

int property_get(const char *key, char *value, const char *default_value);

/* property_set: returns 0 on success, < 0 on failure
*/
int property_set(const char *key, const char *value);

Java层
类: android.os.SystemProperties

读
public static String get(String key);
public static int getInt(String key, int def);
public static long getLong(String key, long def);
public static boolean getBoolean(String key, boolean def);
写
public static void set(String key, String val) ;

读取属性
属性加载完成后,读取属性,无论是C层还是Java层,最终会调用到libc库中的函数,通共享内存的方式从/dev/__properties__获取属性值。读取属性没有权限限制。

设置属性
init进程会创建并监听socket(/dev/socket/property_service)如果其他进程需要设置属性,则发送对应消息到该socket。然后再由init进程就设置属性。
设置属性有权限限制。
限制如下:
ctl开头的属性,需system或root用户,或者在control_perms中uid/gid匹配的用户。

非ctl开头的属性,需root用户,或者property_perms中uid/gid匹配的用户。
如:

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 }
};

属性触发器

init进程中,init.rc等rc文件中可以定义各种服务,属性触发器可以来控制系统服务的启动。
对于ctl开头的属性,可以设置其值,来控制init.rc中服务的启动、停止、重启。
如设置ctl.start为dhcpcd:eth0,则将启动服务dhcpcd,属性值中冒号后的内容作为服务参数。此外还有ctl.stop和ctl.restart属性,分别用于停止和重启服务。
另外我们可以在init.rc等rc文件中定义自己的属性触发器,当一个属性值等于XX时,触发下面的事件,比如启动一个进程,或者设置打印级别。

on property:sys.init_log_level=*
    loglevel ${sys.init_log_level}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值