Android-x86
Fork
Donation

  • R/O
  • HTTP
  • SSH
  • HTTPS

hardware-libhardware_legacy: Commit

hardware/libhardware_legacy


Commit MetaInfo

Revision36c6e87c8308ac979de7d861bf2f64d26aa1b198 (tree)
Time2011-07-12 16:06:24
AuthorChih-Wei Huang <cwhuang@linu...>
CommiterChih-Wei Huang

Log Message

add powerbtnd to simulate long press of power button.

On x86 PC, power button usually generates key press and release events
simultaneously. However, the android framework expects a long press
of power button to invoke the power off dialog.

The daemon simulates a long press of power button in 2 seconds.

A target needs to add excluded-input-devices.xml to exclude
'Power Button' from processing by EventHub.

Change Summary

Incremental Difference

--- a/Android.mk
+++ b/Android.mk
@@ -40,3 +40,14 @@ LOCAL_MODULE:= libpower
4040 LOCAL_SRC_FILES += power/power.c
4141
4242 include $(BUILD_STATIC_LIBRARY)
43+
44+# powerbtn executable
45+include $(CLEAR_VARS)
46+
47+LOCAL_SRC_FILES := power/powerbtnd.c
48+
49+LOCAL_MODULE := powerbtnd
50+LOCAL_MODULE_TAGS := optional
51+LOCAL_SHARED_LIBRARIES := liblog
52+
53+include $(BUILD_EXECUTABLE)
--- /dev/null
+++ b/power/powerbtnd.c
@@ -0,0 +1,118 @@
1+/**
2+ * A daemon to simulate power button of Android
3+ *
4+ * Copyright (C) 2011 The Android-x86 Open Source Project
5+ *
6+ * by Chih-Wei Huang <cwhuang@linux.org.tw>
7+ *
8+ * Licensed under GPLv2 or later
9+ *
10+ **/
11+
12+#define LOG_TAG "powerbtn"
13+
14+#include <sys/stat.h>
15+#include <poll.h>
16+#include <fcntl.h>
17+#include <errno.h>
18+#include <dirent.h>
19+#include <cutils/log.h>
20+#include <linux/input.h>
21+#include <linux/uinput.h>
22+
23+const int MAX_POWERBTNS = 3;
24+
25+int openfds(struct pollfd pfds[])
26+{
27+ int cnt = 0;
28+ const char *dirname = "/dev/input";
29+ DIR *dir;
30+ if ((dir = opendir(dirname))) {
31+ int fd;
32+ struct dirent *de;
33+ while ((de = readdir(dir))) {
34+ if (de->d_name[0] != 'e') // eventX
35+ continue;
36+ char name[PATH_MAX];
37+ snprintf(name, PATH_MAX, "%s/%s", dirname, de->d_name);
38+ fd = open(name, O_RDWR);
39+ if (fd < 0) {
40+ LOGE("could not open %s, %s", name, strerror(errno));
41+ continue;
42+ }
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));
46+ name[0] = '\0';
47+ }
48+
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;
53+ pfds[cnt++].fd = fd;
54+ if (cnt < MAX_POWERBTNS)
55+ continue;
56+ else
57+ break;
58+ }
59+ close(fd);
60+ }
61+ closedir(dir);
62+ }
63+
64+ return cnt;
65+}
66+
67+int main()
68+{
69+ struct pollfd pfds[MAX_POWERBTNS];
70+ int cnt = openfds(pfds);
71+ int pollres;
72+
73+ int ufd = open("/dev/uinput", O_WRONLY | O_NDELAY);
74+ if (ufd >= 0) {
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);
82+ } else {
83+ LOGE("could not open uinput device: %s", strerror(errno));
84+ return -1;
85+ }
86+
87+ while ((pollres = poll(pfds, cnt, -1))) {
88+ int i;
89+ if (pollres < 0) {
90+ LOGE("poll error: %s", strerror(errno));
91+ break;
92+ }
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);
99+ continue;
100+ }
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) {
103+ switch (iev.code)
104+ {
105+ case KEY_POWER:
106+ if (!iev.value)
107+ sleep(2);
108+ break;
109+ }
110+ }
111+
112+ write(ufd, &iev, sizeof(iev));
113+ }
114+ }
115+ }
116+
117+ return 0;
118+}
Show on old repository browser