Android平台上使用属性系统(property system)


在使用Android的属性系统(property system)时遇到了一些问题,结合此次经历,对属性系统的使用做以简单介绍。

一、Property系统简介

属性系统是android的一个重要特性。它作为一个服务运行,管理系统配置和状态。所有这些配置和状态都是属性。每个属性是一个键值对(key/value pair),其类型都是字符串。

从功能上看,属性与windows系统的注册表非常相似。许多android应用程序和库直接或者间接地依赖此特性,以决定它们的运行时行为。例如,adbd进程查询属性服务已确认当前是否运行在模拟器环境中。另一个例子是java.io.File.pathSpearator,其返回存储于属性服务中的值。

二、Property系统使用

使用property系统,首先需要包含头文件<cutils/properties.h>,同时需要在Android.mk文件中加入库libcutils。

具体的使用实例如下:

property_set("hw.jpeg.path", "/data/test.jpg");
    char propBuf[PROPERTY_VALUE_MAX]; 
    property_get("hw.jpeg.path ", propBuf, "");
    LOGI("property_get: %s.", propBuf);

Property系统的使用很简单,这里需要说明的,只有一个问题,那就是属性名称。

三、Property系统的属性名称

Property系统中使用的属性名称有一定的命名规则。

如果属性名称以“ro.”开头,那么这个属性被视为只读属性。一旦设置,属性值不能改变。

如果属性名称以“persist.”开头,当设置这个属性时,其值也将写入/data/property。

如果属性名称以“net.”开头,当设置这个属性时,“net.change”属性将会自动设置,以加入到最后修改的属性名。(这是很巧妙的。 netresolve模块的使用这个属性来追踪在net.*属性上的任何变化。)

属性“ ctrl.start ”和“ ctrl.stop ”是用来启动和停止服务。每一项服务必须在/init.rc中定义.系统启动时,与init守护进程将解析init.rc和启动属性服务。一旦收到设置“ ctrl.start ”属性的请求,属性服务将使用该属性值作为服务名找到该服务,启动该服务。这项服务的启动结果将会放入“ init.svc.<服务名>“属性中 。客户端应用程序可以轮询那个属性值,以确定结果。

另外,还有其他的前缀;在介绍这些前缀之前,我们先来看点别的东西。

在文件system/core/init/property_service.h中,有如下两个函数定义:

extern void handle_property_set_fd(int fd);

extern int property_set(const char *name, const char *value);

它们的实现都位于system/core/init/property_service.c。

另外在system/core/init/init.c中,有如下code:

int main(int argc, char **argv)

{

    ……

for(;;) {

        ……

        if (ufds[0].revents == POLLIN)

            handle_device_fd(device_fd);

        if (ufds[1].revents == POLLIN)

            handle_property_set_fd(property_set_fd);

        if (ufds[3].revents == POLLIN)

            handle_keychord(keychord_fd);

}

……

}

在开机启动后的init操作中,会执行一个loop循环,当检测到有新的设置时,进入设置流程,鉴权失败会提示相关的异常,如:

sys_prop: permission denied uid:1013  name:hw.jpeg.path

这里得介绍一下函数handle_property_set_fd(),其实现为:

void handle_property_set_fd(int fd)

{

    prop_msg msg;

    ……

    switch(msg.cmd) {

    case PROP_MSG_SETPROP:

        msg.name[PROP_NAME_MAX-1] = 0;

        msg.value[PROP_VALUE_MAX-1] = 0;

 

        if(memcmp(msg.name,"ctl.",4) == 0) {

            if (check_control_perms(msg.value, cr.uid, cr.gid)) {

                handle_control_message((char*) msg.name + 4, (char*) msg.value);

            } else {

                ERROR("sys_prop: Unable to %s service ctl [%s] uid: %d pid:%d/n",

                        msg.name + 4, msg.value, cr.uid, cr.pid);

            }

        } else {

            if (check_perms(msg.name, cr.uid, cr.gid)) {

                property_set((char*) msg.name, (char*) msg.value);

            } else {

                ERROR("sys_prop: permission denied uid:%d  name:%s/n",

                      cr.uid, msg.name);

            }

        }

        break;

 

    default:

        break;

    }

}

  • 1
  • 2
  • 下一页

相关内容