2 * A daemon to simulate power button of Android
4 * Copyright (C) 2011 The Android-x86 Open Source Project
6 * by Chih-Wei Huang <cwhuang@linux.org.tw>
8 * Licensed under GPLv2 or later
12 #define LOG_TAG "powerbtn"
19 #include <cutils/log.h>
20 #include <linux/input.h>
21 #include <linux/uinput.h>
23 const int MAX_POWERBTNS = 3;
25 int openfds(struct pollfd pfds[])
28 const char *dirname = "/dev/input";
30 if ((dir = opendir(dirname))) {
33 while ((de = readdir(dir))) {
34 if (de->d_name[0] != 'e') // eventX
37 snprintf(name, PATH_MAX, "%s/%s", dirname, de->d_name);
38 fd = open(name, O_RDWR);
40 LOGE("could not open %s, %s", name, strerror(errno));
43 name[sizeof(name) - 1] = '\0';
44 if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) {
45 LOGE("could not get device name for %s, %s\n", name, strerror(errno));
49 // TODO: parse /etc/excluded-input-devices.xml
50 if (!strcmp(name, "Power Button")) {
51 LOGI("open %s(%s) ok", de->d_name, name);
52 pfds[cnt].events = POLLIN;
54 if (cnt < MAX_POWERBTNS)
69 struct pollfd pfds[MAX_POWERBTNS];
70 int cnt = openfds(pfds);
73 int ufd = open("/dev/uinput", O_WRONLY | O_NDELAY);
75 struct uinput_user_dev ud;
76 memset(&ud, 0, sizeof(ud));
77 strcpy(ud.name, "Android Power Button");
78 write(ufd, &ud, sizeof(ud));
79 ioctl(ufd, UI_SET_EVBIT, EV_KEY);
80 ioctl(ufd, UI_SET_KEYBIT, KEY_POWER);
81 ioctl(ufd, UI_DEV_CREATE, 0);
83 LOGE("could not open uinput device: %s", strerror(errno));
87 while ((pollres = poll(pfds, cnt, -1))) {
90 LOGE("poll error: %s", strerror(errno));
93 for (i = 0; i < cnt; ++i) {
94 if (pfds[i].revents & POLLIN) {
95 struct input_event iev;
96 size_t res = read(pfds[i].fd, &iev, sizeof(iev));
97 if (res < sizeof(iev)) {
98 LOGW("insufficient input data(%d)? fd=%d", res, pfds[i].fd);
101 LOGV("type=%d scancode=%d value=%d from fd=%d", iev.type, iev.code, iev.value, pfds[i].fd);
102 if (iev.type == EV_KEY) {
112 write(ufd, &iev, sizeof(iev));