一 Property系统的属性名称
Property系统中使用的属性名称有一定的命名规则。比如我所设置的属性名称hw.akm.resetdoe会与
system/core/in it/property_service.c中的结构体property_perms中的前缀做比较,如果满足,
则又会比较uid。
从 源代码可知结构体property_perms的定义如下:
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 },
{ "ril.", AID_RADIO, 0 },
{ "gsm.", AID_RADIO, 0 },
{ "persist.radio", AID_RADIO, 0 },
{ "net.dns", AID_RADIO, 0 },
{ "net.", AID_SYSTEM, 0 },
{ "dev.", AID_SYSTEM, 0 },
{ "runtime.", AID_SYSTEM, 0 },
{ "hw.", AID_SYSTEM, 0 },
{ "sys.", AID_SYSTEM, 0 },
{ "service.", AID_SYSTEM, 0 },
{ "wlan.", AID_SYSTEM, 0 },
{ "dhcp.", AID_SYSTEM, 0 },
{ "dhcp.", AID_DHCP, 0 },
{ "vpn.", AID_SYSTEM, 0 },
{ "vpn.", AID_VPN, 0 },
{ "debug.", AID_SHELL, 0 },
{ "log.", AID_SHELL, 0 },
{ "service.adb.root", AID_SHELL, 0 },
{ "persist.sys.", AID_SYSTEM, 0 },
{ "persist.service.", AID_SYSTEM, 0 },
{ "persist.security.", AID_SYSTEM, 0 },
{ NULL, 0, 0 }
};
从结构体可以看到hw.对应的uid为AID_SYSTEM,AID_SYSTEM的定义位于system/core/include/private/android_filesystem_config.h。
#define AID_SYSTEM 1000 /* system server */
#define AID_RADIO 1001 /* telephony subsystem, RIL */
#define AID_DHCP 1014 /* dhcp client */
#define AID_VPN 1016 /* vpn system */
#define AID_SHELL 2000 /* adb and debug shell user */
当我们使用属性名称为hw.akm.resetdoe时,应用程序的uid必须为1000,否则在函数handle_property_set_fd()中就会报出类似这样的错误:
sys_prop: permission denied uid:1013 name:hw.akm.resetdo,如何使应用程序的uid变为1000呢?
l 在应用程序的AndroidManifest.xml文件中的manifest节点中加入属性:
android:sharedUserId="android.uid.system";
通过Shared User id,拥有同一个User id的多个APK可以配置成运行在同一个进程中。那么把程序的UID配成android.uid.system,也就是要让程序运行在系统进程中,这样就有权限来设置前缀为hw.的属性了。
l 修改Android.mk文件,加入LOCAL_CERTIFICATE := platform;
加入UID还不够,如果这时候安装APK的话发现无法安装,提示签名不符,原因是程序想要运行在系统进程中还要有目标系统的platform. key,就是platform.pk8和platform.x509.pem两个文件。通过这样的设置,系统才可以拿到platform.pk8和platform.x509.pem两个文件。使用这两个key签名后apk才真正可以放入系统进程中。
然后使用mm命令来编译,生成的apk的uid就会成为1000。在去调用
property_set("hw.akm.resetdo", "1");就不会有问题了。
另外需要说明的是,property_get()函数的使用是没有这样的限制的。
使用property系统,首先需要包含头文件<cutils/properties.h>,并在Android.mk文件中加入库libcutils,如:
LOCAL_SHARED_LIBRARIES += liblog libcutils
具体的使用实例如下:
property_set("hw.akm.resetdoe","1");
char propBuf[2];
property_get("hw.akm.resetdoe", propBuf, "");
LOGI("property_get: %s.", propBuf);
或:
#include <sys/system_properties.h>
#define AKMD_PROP_RESETDOE "nosecure.akm.resetdoe"
static const prop_info *g_resetdoe;
g_resetdoe = __system_property_find(AKMD_PROP_RESETDOE);
if (g_resetdoe == NULL) {
ALOGE("init AKMD_PROP_RESETDOE");
__system_property_set(AKMD_PROP_RESETDOE, "0");
ALOGE("after init __system_property_set, g_resetdoe=%d\n", g_resetdoe);
g_resetdoe = __system_property_find(AKMD_PROP_RESETDOE);
if(g_resetdoe == NULL) {
ALOGE("after init g_resetdoe is still NULL.\n");
}
}
手动修改属性:
setprop nosecure.akm.resetdoe 1
getprop nosecure.akm.resetdoe