1.用户空间的接口在kernel/power/main.c中,定义了一组sysfs的属性文件,其中一个定义是:power_attr(state);把这个宏展开后:
- staticstruct kobj_attribute state_attr = {
-
- .attr ={
-
- .name = "state",
-
- .mode = 0644,
-
- },
-
- .show =state_show,
-
- .store =state_store,
-
- }
我们再看看main.c的入口:
- staticint __init pm_init(void)
-
- {
-
- ......
-
- power_kobj =kobject_create_and_add("power", NULL);
-
- if (!power_kobj)
-
- return -ENOMEM;
-
- return sysfs_create_group(power_kobj,&attr_group);
-
- }
显然,该函数执行后,会在生成/sys/power目录,该目录下会建立一系列属性文件,其中一个就是/sys/power/state文件。用户空间向该文件的写入将会导致state_store被调用,读取该文件将会导致state_store函数被调用。现在回到Android的HAL层中,查看一下代码:hardware/libhardware_legacy/power/power.c:
- //定义写入/sys/power/state的命令字符串
-
- staticconst char *off_state = "mem";
-
- staticconst char *on_state = "on";
-
- //打开/sys/power/state等属性文件,保存相应的文件描述符
-
- staticint
-
- open_file_descriptors(constchar * const paths[])
-
- {
-
- int i;
-
- for (i=0; i<OUR_FD_COUNT; i++) {
-
- int fd = open(paths[i], O_RDWR);
-
- if (fd < 0) {
-
- fprintf(stderr, "fatal erroropening "%s"
", paths[i]);
-
- g_error = errno;
-
- return -1;
-
- }
-
- g_fds[i] = fd;
-
- }
-
-
-
- g_error = 0;
-
- return 0;
-
- }
最终,用户空间的电源管理系统会调用set_screen_state函数来触发suspend的流程,该函数实际上就是往/sys/power/state文件写入"mem"或"on"命令字符串。
- int
-
- set_screen_state(inton)
-
- {
-
- ......
-
- initialize_fds();
-
- ......
-
- char buf[32];
-
- int len;
-
- if(on)
-
- len = snprintf(buf, sizeof(buf),"%s", on_state);
-
- else
-
- len = snprintf(buf, sizeof(buf),"%s", off_state);
-
-
-
- buf[sizeof(buf) - 1] = " ";
-
- len = write(g_fds[REQUEST_STATE], buf,len);
-
- ......
-
- return 0;
-
- }