• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <dirent.h>
18 #include <errno.h>
19 #include <fcntl.h>
20 #include <linux/input.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <sys/epoll.h>
25 #include <sys/ioctl.h>
26 #include <sys/types.h>
27 #include <unistd.h>
28 
29 #include <functional>
30 #include <memory>
31 
32 #include <android-base/unique_fd.h>
33 
34 #include "minui/minui.h"
35 
36 constexpr size_t MAX_DEVICES = 16;
37 constexpr size_t MAX_MISC_FDS = 16;
38 
39 constexpr size_t BITS_PER_LONG = sizeof(unsigned long) * 8;
BITS_TO_LONGS(size_t bits)40 constexpr size_t BITS_TO_LONGS(size_t bits) {
41   return ((bits + BITS_PER_LONG - 1) / BITS_PER_LONG);
42 }
43 
44 struct FdInfo {
45   android::base::unique_fd fd;
46   ev_callback cb;
47 };
48 
49 static android::base::unique_fd g_epoll_fd;
50 static epoll_event g_polled_events[MAX_DEVICES + MAX_MISC_FDS];
51 static int g_polled_events_count;
52 
53 static FdInfo ev_fdinfo[MAX_DEVICES + MAX_MISC_FDS];
54 
55 static size_t g_ev_count = 0;
56 static size_t g_ev_dev_count = 0;
57 static size_t g_ev_misc_count = 0;
58 
test_bit(size_t bit,unsigned long * array)59 static bool test_bit(size_t bit, unsigned long* array) { // NOLINT
60   return (array[bit / BITS_PER_LONG] & (1UL << (bit % BITS_PER_LONG))) != 0;
61 }
62 
ev_init(ev_callback input_cb,bool allow_touch_inputs)63 int ev_init(ev_callback input_cb, bool allow_touch_inputs) {
64   g_epoll_fd.reset();
65 
66   android::base::unique_fd epoll_fd(epoll_create1(EPOLL_CLOEXEC));
67   if (epoll_fd == -1) {
68     return -1;
69   }
70 
71   std::unique_ptr<DIR, decltype(&closedir)> dir(opendir("/dev/input"), closedir);
72   if (!dir) {
73     return -1;
74   }
75 
76   bool epoll_ctl_failed = false;
77   dirent* de;
78   while ((de = readdir(dir.get())) != nullptr) {
79     if (strncmp(de->d_name, "event", 5)) continue;
80     android::base::unique_fd fd(openat(dirfd(dir.get()), de->d_name, O_RDONLY | O_CLOEXEC));
81     if (fd == -1) continue;
82 
83     // Use unsigned long to match ioctl's parameter type.
84     unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)];  // NOLINT
85 
86     // Read the evbits of the input device.
87     if (ioctl(fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1) {
88       continue;
89     }
90 
91     // We assume that only EV_KEY, EV_REL, and EV_SW event types are ever needed. EV_ABS is also
92     // allowed if allow_touch_inputs is set.
93     if (!test_bit(EV_KEY, ev_bits) && !test_bit(EV_REL, ev_bits) && !test_bit(EV_SW, ev_bits)) {
94       if (!allow_touch_inputs || !test_bit(EV_ABS, ev_bits)) {
95         continue;
96       }
97     }
98 
99     epoll_event ev;
100     ev.events = EPOLLIN | EPOLLWAKEUP;
101     ev.data.ptr = &ev_fdinfo[g_ev_count];
102     if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ev) == -1) {
103       epoll_ctl_failed = true;
104       continue;
105     }
106 
107     ev_fdinfo[g_ev_count].fd.reset(fd.release());
108     ev_fdinfo[g_ev_count].cb = input_cb;
109     g_ev_count++;
110     g_ev_dev_count++;
111     if (g_ev_dev_count == MAX_DEVICES) break;
112   }
113 
114   if (epoll_ctl_failed && !g_ev_count) {
115     return -1;
116   }
117 
118   g_epoll_fd.reset(epoll_fd.release());
119   return 0;
120 }
121 
ev_get_epollfd(void)122 int ev_get_epollfd(void) {
123   return g_epoll_fd.get();
124 }
125 
ev_add_fd(android::base::unique_fd && fd,ev_callback cb)126 int ev_add_fd(android::base::unique_fd&& fd, ev_callback cb) {
127   if (g_ev_misc_count == MAX_MISC_FDS || cb == nullptr) {
128     return -1;
129   }
130 
131   epoll_event ev;
132   ev.events = EPOLLIN | EPOLLWAKEUP;
133   ev.data.ptr = static_cast<void*>(&ev_fdinfo[g_ev_count]);
134   int ret = epoll_ctl(g_epoll_fd, EPOLL_CTL_ADD, fd, &ev);
135   if (!ret) {
136     ev_fdinfo[g_ev_count].fd.reset(fd.release());
137     ev_fdinfo[g_ev_count].cb = std::move(cb);
138     g_ev_count++;
139     g_ev_misc_count++;
140   }
141 
142   return ret;
143 }
144 
ev_exit(void)145 void ev_exit(void) {
146   while (g_ev_count > 0) {
147     ev_fdinfo[--g_ev_count].fd.reset();
148   }
149   g_ev_misc_count = 0;
150   g_ev_dev_count = 0;
151   g_epoll_fd.reset();
152 }
153 
ev_wait(int timeout)154 int ev_wait(int timeout) {
155   g_polled_events_count = epoll_wait(g_epoll_fd, g_polled_events, g_ev_count, timeout);
156   if (g_polled_events_count <= 0) {
157     return -1;
158   }
159   return 0;
160 }
161 
ev_dispatch(void)162 void ev_dispatch(void) {
163   for (int n = 0; n < g_polled_events_count; n++) {
164     FdInfo* fdi = static_cast<FdInfo*>(g_polled_events[n].data.ptr);
165     const ev_callback& cb = fdi->cb;
166     if (cb) {
167       cb(fdi->fd, g_polled_events[n].events);
168     }
169   }
170 }
171 
ev_get_input(int fd,uint32_t epevents,input_event * ev)172 int ev_get_input(int fd, uint32_t epevents, input_event* ev) {
173     if (epevents & EPOLLIN) {
174         ssize_t r = TEMP_FAILURE_RETRY(read(fd, ev, sizeof(*ev)));
175         if (r == sizeof(*ev)) {
176             return 0;
177         }
178     }
179     return -1;
180 }
181 
ev_sync_key_state(const ev_set_key_callback & set_key_cb)182 int ev_sync_key_state(const ev_set_key_callback& set_key_cb) {
183   // Use unsigned long to match ioctl's parameter type.
184   unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)];    // NOLINT
185   unsigned long key_bits[BITS_TO_LONGS(KEY_MAX)];  // NOLINT
186 
187   for (size_t i = 0; i < g_ev_dev_count; ++i) {
188     memset(ev_bits, 0, sizeof(ev_bits));
189     memset(key_bits, 0, sizeof(key_bits));
190 
191     if (ioctl(ev_fdinfo[i].fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1) {
192       continue;
193     }
194     if (!test_bit(EV_KEY, ev_bits)) {
195       continue;
196     }
197     if (ioctl(ev_fdinfo[i].fd, EVIOCGKEY(sizeof(key_bits)), key_bits) == -1) {
198       continue;
199     }
200 
201     for (int code = 0; code <= KEY_MAX; code++) {
202       if (test_bit(code, key_bits)) {
203         set_key_cb(code, 1);
204       }
205     }
206   }
207 
208   return 0;
209 }
210 
ev_iterate_available_keys(const std::function<void (int)> & f)211 void ev_iterate_available_keys(const std::function<void(int)>& f) {
212   // Use unsigned long to match ioctl's parameter type.
213   unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)];    // NOLINT
214   unsigned long key_bits[BITS_TO_LONGS(KEY_MAX)];  // NOLINT
215 
216   for (size_t i = 0; i < g_ev_dev_count; ++i) {
217     memset(ev_bits, 0, sizeof(ev_bits));
218     memset(key_bits, 0, sizeof(key_bits));
219 
220     // Does this device even have keys?
221     if (ioctl(ev_fdinfo[i].fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1) {
222       continue;
223     }
224     if (!test_bit(EV_KEY, ev_bits)) {
225       continue;
226     }
227 
228     if (ioctl(ev_fdinfo[i].fd, EVIOCGBIT(EV_KEY, KEY_MAX), key_bits) == -1) {
229       continue;
230     }
231 
232     for (int key_code = 0; key_code <= KEY_MAX; ++key_code) {
233       if (test_bit(key_code, key_bits)) {
234         f(key_code);
235       }
236     }
237   }
238 }
239 
ev_iterate_touch_inputs(const std::function<void (int)> & action)240 void ev_iterate_touch_inputs(const std::function<void(int)>& action) {
241   for (size_t i = 0; i < g_ev_dev_count; ++i) {
242     // Use unsigned long to match ioctl's parameter type.
243     unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)] = {};  // NOLINT
244     if (ioctl(ev_fdinfo[i].fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1) {
245       continue;
246     }
247     if (!test_bit(EV_ABS, ev_bits)) {
248       continue;
249     }
250 
251     unsigned long key_bits[BITS_TO_LONGS(KEY_MAX)] = {};  // NOLINT
252     if (ioctl(ev_fdinfo[i].fd, EVIOCGBIT(EV_ABS, KEY_MAX), key_bits) == -1) {
253       continue;
254     }
255 
256     for (int key_code = 0; key_code <= KEY_MAX; ++key_code) {
257       if (test_bit(key_code, key_bits)) {
258         action(key_code);
259       }
260     }
261   }
262 }
263