用户态代码运行时可配置,是指不需要重新编译代码。
以前framework运行时可配只能通过读属性值,属性值可以在init.rc或system.prop里赋值, 但对于需要配置大量数据的情景不怎么合适。虽说原则是framework尽量保持不变,让hal变化来适应驱动的变化,但目前来看,hal层变化有人也嫌麻烦(竟然还要考虑以后用框架的人可能不想编译代码),干脆只有配置文件变化。
但如果每个模块都自己写解析配置文件的代码,那就太傻了, 又于是便产生了ConfManager这个东西。各模块按ConfManager的要求写配置文件,然后就可以通过ConfManager的傻瓜接口读到。
ConfManager.h接口定义, 用c++实现, 提供c和c++接口。 如果java层也有需求,后续再打通jni:
#ifndef ANDROID_CONFMANAGER_H
#define ANDROID_CONFMANAGER_H
#ifdef __cplusplus
namespace android {
class ConfManagerPriv;
class ConfManager
{
public:
ConfManager(const char* file_name);
~ConfManager();
bool getIntConf(const char* key,int* value);
bool getStringConf(const char* key,char* value,int size);
bool getArrayConf(const char* key,int value[],int size);
private:
bool loadCfg(const char* file_name);
void dump();
ConfManagerPriv *priv;
};
//----------------------------------------------------------------------------
}; // namespace android
extern "C" {
#endif
typedef void* CONF_HANDLE;
#ifdef __cplusplus
};
#endif
#endif
用例:平台硬件稍有变化,或者用了不同的电池, 系统的电压和电量的关系都会有微妙的变化。 所以电压电量对应表想要运行时可配
Battery.xml:
<?xmlversion="1.0" encoding="utf-8"?>
<battery>
<int name="cat" value="10" />
<string name="fish" value="bird" />
<array name="battery.map_powered.v"
value="3400,3600,3700,3725,3750,3775,3800,3825,3850,3875,3900,3925,3950,3975,4000,
4025,4050,4075,4010,4125,4200"/>
<array name="battery.map_powered.c"
value="15 ,15 ,15 ,15 ,20 ,25 ,30 ,35 ,40 ,45 ,50 ,55 ,60 ,65 ,70 ,75 ,80 ,85 ,
90 ,95 ,100" />
<array name="battery.map_unpowered.v"
value="3400,3475,3550,3575,3600,3625,3650,3675,3700,3725,3750,3800,3825,3850,3875,
3900,3925,3925,3930,3940,3950" />
<arrayname="battery.map_unpowered.c"
value="0 ,5 ,10 ,15 ,20 ,25 ,30 ,35 ,40 ,45 ,50 ,55 ,60 ,65 ,70 ,75 ,80 ,85 ,
90 ,95 ,100" />
</battery>
在batteryhal层battery.c中通过ConfManager接口获取配置:
staticint open_battery(const struct hw_module_t *module, char const *name,
struct hw_device_t **device)
{
int tmp[CAPACITY_MAP_SIZE];
int i, j;
CONF_HANDLE handle = cconf_init("/etc/battery.xml");
cconf_delete(handle);
…………
}