Android的property机制
来源:互联网 发布:广州数据恢复 编辑:程序博客网 时间:2024/05/21 07:56
android 1号进程进程init进程在开机的时候就会调用property_init函数,至于init是怎么起来的,这里不是重点,所以暂时先不介绍,property_init的具体flow如下:
system/core/init/init.c
void property_init(void){ init_property_area(); }system/core/init/property_service.c
static int init_property_area(void){ if (property_area_inited) return -1; if(__system_property_area_init()) return -1; if(init_workspace(&pa_workspace, 0)) return -1; fcntl(pa_workspace.fd, F_SETFD, FD_CLOEXEC); property_area_inited = 1; return 0;}bionic/libc/bionic/system_properties.c
int __system_property_area_init(){ return map_prop_area_rw();}
static int map_prop_area_rw(){ prop_area *pa; int fd; int ret; /* dev is a tmpfs that we can use to carve a shared workspace * out of, so let's do that... */ fd = open(property_filename, O_RDWR | O_CREAT | O_NOFOLLOW | O_CLOEXEC | O_EXCL, 0444); if (fd < 0) { if (errno == EACCES) { /* for consistency with the case where the process has already * mapped the page in and segfaults when trying to write to it */ abort(); } return -1; } ret = fcntl(fd, F_SETFD, FD_CLOEXEC); if (ret < 0) goto out; if (ftruncate(fd, PA_SIZE) < 0) goto out; pa_size = PA_SIZE; pa_data_size = pa_size - sizeof(prop_area); compat_mode = false; pa = mmap(NULL, pa_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if(pa == MAP_FAILED) goto out; memset(pa, 0, pa_size); pa->magic = PROP_AREA_MAGIC; pa->version = PROP_AREA_VERSION; /* reserve root node */ pa->bytes_used = sizeof(prop_bt); /* plug into the lib property services */ __system_property_area__ = pa; close(fd); return 0;out: close(fd); return -1;}看到open(property_filename, O_RDWR | O_CREAT | O_NOFOLLOW | O_CLOEXEC |O_EXCL, 0444);和 pa = mmap(NULL, pa_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);我们知道文件property_filename (即 /dev/__properties__)被打开,并以读写可共享的方式映射到了内存。(其他全局变量,如pa_data_size和__system_property_area__ 暂放置一边,也不细节的讲述get_fd_from_env() )。
property_set/property_get位于libcutils.so库,任何进程若要调用这两个函数,需要链接libcutils.so。libcutils.so调用了__system_property_set和__system_Property_get函数,这两个函数位于bionic库中,生成的库文件为libc_common.so。
bionic/libc/bionic/system_properties.c
int __system_property_set(const char *key, const char *value){ int err; prop_msg msg; if(key == 0) return -1; if(value == 0) value = ""; if(strlen(key) >= PROP_NAME_MAX) return -1; if(strlen(value) >= PROP_VALUE_MAX) return -1; memset(&msg, 0, sizeof msg); msg.cmd = PROP_MSG_SETPROP; strlcpy(msg.name, key, sizeof msg.name); strlcpy(msg.value, value, sizeof msg.value); err = send_prop_msg(&msg); if(err < 0) { return err; } return 0;}
static int send_prop_msg(prop_msg *msg){ struct pollfd pollfds[1]; struct sockaddr_un addr; socklen_t alen; size_t namelen; int s; int r; int result = -1; s = socket(AF_LOCAL, SOCK_STREAM, 0); if(s < 0) { return result; } memset(&addr, 0, sizeof(addr)); namelen = strlen(property_service_socket); strlcpy(addr.sun_path, property_service_socket, sizeof addr.sun_path); addr.sun_family = AF_LOCAL; alen = namelen + offsetof(struct sockaddr_un, sun_path) + 1; if(TEMP_FAILURE_RETRY(connect(s, (struct sockaddr *) &addr, alen)) < 0) { close(s); return result; } r = TEMP_FAILURE_RETRY(send(s, msg, sizeof(prop_msg), 0)); if(r == sizeof(prop_msg)) { // We successfully wrote to the property server but now we // wait for the property server to finish its work. It // acknowledges its completion by closing the socket so we // poll here (on nothing), waiting for the socket to close. // If you 'adb shell setprop foo bar' you'll see the POLLHUP // once the socket closes. Out of paranoia we cap our poll // at 250 ms. pollfds[0].fd = s; pollfds[0].events = 0; r = TEMP_FAILURE_RETRY(poll(pollfds, 1, 250 /* ms */)); if (r == 1 && (pollfds[0].revents & POLLHUP) != 0) { result = 0; } else { // Ignore the timeout and treat it like a success anyway. // The init process is single-threaded and its property // service is sometimes slow to respond (perhaps it's off // starting a child process or something) and thus this // times out and the caller thinks it failed, even though // it's still getting around to it. So we fake it here, // mostly for ctl.* properties, but we do try and wait 250 // ms so callers who do read-after-write can reliably see // what they've written. Most of the time. // TODO: fix the system properties design. result = 0; } } close(s); return result;}property_service.c收到这个msg后,会根据msg.name和msg.value来设置具体的property,在这路需要说明一下,如果根据name能够找到对应的prop_info信息,那么就去update对应的value值,如果找不到对应的prop_info信息,那么就去add一个prop_info。具体flow如下:
system/core/libcutils/properties.c
int property_set(const char *key, const char *value){ char sendBuf[1+PROPERTY_KEY_MAX+PROPERTY_VALUE_MAX]; char recvBuf[1]; int result = -1; //ALOGV("PROPERTY SET [%s]: [%s]\n", key, value); pthread_once(&gInitOnce, init); if (gPropFd < 0) return -1; if (strlen(key) >= PROPERTY_KEY_MAX) return -1; if (strlen(value) >= PROPERTY_VALUE_MAX) return -1; memset(sendBuf, 0xdd, sizeof(sendBuf)); // placate valgrind sendBuf[0] = (char) kSystemPropertySet; strcpy(sendBuf+1, key); strcpy(sendBuf+1+PROPERTY_KEY_MAX, value); pthread_mutex_lock(&gPropertyFdLock); if (write(gPropFd, sendBuf, sizeof(sendBuf)) != sizeof(sendBuf)) { pthread_mutex_unlock(&gPropertyFdLock); return -1; } if (read(gPropFd, recvBuf, sizeof(recvBuf)) != sizeof(recvBuf)) { pthread_mutex_unlock(&gPropertyFdLock); return -1; } pthread_mutex_unlock(&gPropertyFdLock); if (recvBuf[0] != 1) return -1; return 0;}
0 0
- Android的property机制
- 有关android的property机制 (property_set() & property_get())
- Android Property机制
- android property机制
- Android属性(property)机制
- Android属性(property)机制
- Android属性(property)机制
- Android属性(property)机制
- 深入讲解Android Property机制
- 深入讲解Android Property机制
- 深入讲解Android Property机制
- 深入讲解Android Property机制
- 深入讲解Android Property机制
- 深入讲解Android Property机制
- 深入讲解Android Property机制
- 深入讲解Android Property机制
- Android属性(property)机制
- Android属性(property)机制
- 黄璐_对NFV和SDN的思考与实践
- android AsyncTask介绍
- Struts2源码阅读(五)_FilterDispatcher核心控制器
- java将多个文件一起打成zip包后下载实例
- android intent和intent action大全
- Android的property机制
- Android系统之闹钟模块浅析
- [歪谈]运营和技术之间不可调和的“矛盾”
- IntelliJ IDEA 12创建Maven管理的Java Web项目(图解)
- Error setting null for parameter #10 with JdbcType OTHER .
- js-innerHTML
- js的特殊结果
- mydumper
- Android 学习之路--也许就是你需要的