• 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/inotify.h>
26 #include <sys/ioctl.h>
27 #include <sys/types.h>
28 #include <unistd.h>
29 
30 #include <functional>
31 #include <memory>
32 
33 #include <android-base/unique_fd.h>
34 
35 #include "minui/minui.h"
36 
37 constexpr const char* INPUT_DEV_DIR = "/dev/input";
38 
39 constexpr size_t MAX_DEVICES = 16;
40 constexpr size_t MAX_MISC_FDS = 16;
41 
42 constexpr size_t BITS_PER_LONG = sizeof(unsigned long) * 8;
BITS_TO_LONGS(size_t bits)43 constexpr size_t BITS_TO_LONGS(size_t bits) {
44   return ((bits + BITS_PER_LONG - 1) / BITS_PER_LONG);
45 }
46 
47 struct FdInfo {
48   android::base::unique_fd fd;
49   ev_callback cb;
50 };
51 
52 static bool g_allow_touch_inputs = true;
53 static ev_callback g_saved_input_cb;
54 static android::base::unique_fd g_epoll_fd;
55 static epoll_event g_polled_events[MAX_DEVICES + MAX_MISC_FDS];
56 static int g_polled_events_count;
57 
58 static FdInfo ev_fdinfo[MAX_DEVICES + MAX_MISC_FDS];
59 
60 static size_t g_ev_count = 0;
61 static size_t g_ev_dev_count = 0;
62 static size_t g_ev_misc_count = 0;
63 
test_bit(size_t bit,unsigned long * array)64 static bool test_bit(size_t bit, unsigned long* array) { // NOLINT
65   return (array[bit / BITS_PER_LONG] & (1UL << (bit % BITS_PER_LONG))) != 0;
66 }
67 
should_add_input_device(int fd,bool allow_touch_inputs)68 static bool should_add_input_device(int fd, bool allow_touch_inputs) {
69   // Use unsigned long to match ioctl's parameter type.
70   unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)];  // NOLINT
71 
72   // Read the evbits of the input device.
73   if (ioctl(fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1) {
74     return false;
75   }
76 
77   // We assume that only EV_KEY, EV_REL, and EV_SW event types are ever needed. EV_ABS is also
78   // allowed if allow_touch_inputs is set.
79   if (!test_bit(EV_KEY, ev_bits) && !test_bit(EV_REL, ev_bits) && !test_bit(EV_SW, ev_bits)) {
80     if (!allow_touch_inputs || !test_bit(EV_ABS, ev_bits)) {
81       return false;
82     }
83   }
84 
85   return true;
86 }
87 
inotify_cb(int fd,__unused uint32_t epevents)88 static int inotify_cb(int fd, __unused uint32_t epevents) {
89   if (g_saved_input_cb == nullptr) return -1;
90 
91   // The inotify will put one or several complete events.
92   // Should not read part of one event.
93   int event_len_int;
94   int ret = ioctl(fd, FIONREAD, &event_len_int);
95   if (ret != 0) return -1;
96   if (event_len_int < 0) return -1;
97   size_t event_len = event_len_int;
98 
99   std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(INPUT_DEV_DIR), closedir);
100   if (!dir) {
101     return -1;
102   }
103 
104   std::vector<int8_t> buf(event_len);
105 
106   ssize_t r = TEMP_FAILURE_RETRY(read(fd, buf.data(), event_len));
107   if (r != event_len) {
108     return -1;
109   }
110 
111   size_t offset = 0;
112   while (offset < event_len) {
113     struct inotify_event* pevent = reinterpret_cast<struct inotify_event*>(buf.data() + offset);
114     if (offset + sizeof(inotify_event) + pevent->len > event_len) {
115       // The pevent->len is too large and buffer will over flow.
116       // In general, should not happen, just make more stable.
117       return -1;
118     }
119     offset += sizeof(inotify_event) + pevent->len;
120 
121     pevent->name[pevent->len] = '\0';
122     if (strncmp(pevent->name, "event", 5)) {
123       continue;
124     }
125 
126     android::base::unique_fd dfd(openat(dirfd(dir.get()), pevent->name, O_RDONLY));
127     if (dfd == -1) {
128       break;
129     }
130 
131     if (!should_add_input_device(dfd, g_allow_touch_inputs)) {
132       continue;
133     }
134 
135     // Only add, we assume the user will not plug out and plug in USB device again and again :)
136     ev_add_fd(std::move(dfd), g_saved_input_cb);
137   }
138 
139   return 0;
140 }
141 
ev_init(ev_callback input_cb,bool allow_touch_inputs)142 int ev_init(ev_callback input_cb, bool allow_touch_inputs) {
143   g_epoll_fd.reset();
144 
145   android::base::unique_fd epoll_fd(epoll_create1(EPOLL_CLOEXEC));
146   if (epoll_fd == -1) {
147     return -1;
148   }
149 
150   android::base::unique_fd inotify_fd(inotify_init1(IN_CLOEXEC));
151   if (inotify_fd.get() == -1) {
152     return -1;
153   }
154 
155   if (inotify_add_watch(inotify_fd, INPUT_DEV_DIR, IN_CREATE) < 0) {
156     return -1;
157   }
158 
159   std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(INPUT_DEV_DIR), closedir);
160   if (!dir) {
161     return -1;
162   }
163 
164   bool epoll_ctl_failed = false;
165   dirent* de;
166   while ((de = readdir(dir.get())) != nullptr) {
167     if (strncmp(de->d_name, "event", 5)) continue;
168     android::base::unique_fd fd(openat(dirfd(dir.get()), de->d_name, O_RDONLY | O_CLOEXEC));
169     if (fd == -1) continue;
170 
171     if (!should_add_input_device(fd, allow_touch_inputs)) {
172       continue;
173     }
174 
175     epoll_event ev;
176     ev.events = EPOLLIN | EPOLLWAKEUP;
177     ev.data.ptr = &ev_fdinfo[g_ev_count];
178     if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ev) == -1) {
179       epoll_ctl_failed = true;
180       continue;
181     }
182 
183     ev_fdinfo[g_ev_count].fd.reset(fd.release());
184     ev_fdinfo[g_ev_count].cb = input_cb;
185     g_ev_count++;
186     g_ev_dev_count++;
187     if (g_ev_dev_count == MAX_DEVICES) break;
188   }
189 
190   if (epoll_ctl_failed && !g_ev_count) {
191     return -1;
192   }
193 
194   g_epoll_fd.reset(epoll_fd.release());
195 
196   g_saved_input_cb = input_cb;
197   g_allow_touch_inputs = allow_touch_inputs;
198   ev_add_fd(std::move(inotify_fd), inotify_cb);
199 
200   return 0;
201 }
202 
ev_get_epollfd(void)203 int ev_get_epollfd(void) {
204   return g_epoll_fd.get();
205 }
206 
ev_add_fd(android::base::unique_fd && fd,ev_callback cb)207 int ev_add_fd(android::base::unique_fd&& fd, ev_callback cb) {
208   if (g_ev_misc_count == MAX_MISC_FDS || cb == nullptr) {
209     return -1;
210   }
211 
212   epoll_event ev;
213   ev.events = EPOLLIN | EPOLLWAKEUP;
214   ev.data.ptr = static_cast<void*>(&ev_fdinfo[g_ev_count]);
215   int ret = epoll_ctl(g_epoll_fd, EPOLL_CTL_ADD, fd, &ev);
216   if (!ret) {
217     ev_fdinfo[g_ev_count].fd.reset(fd.release());
218     ev_fdinfo[g_ev_count].cb = std::move(cb);
219     g_ev_count++;
220     g_ev_misc_count++;
221   }
222 
223   return ret;
224 }
225 
ev_exit(void)226 void ev_exit(void) {
227   while (g_ev_count > 0) {
228     ev_fdinfo[--g_ev_count].fd.reset();
229   }
230   g_ev_misc_count = 0;
231   g_ev_dev_count = 0;
232   g_saved_input_cb = nullptr;
233   g_epoll_fd.reset();
234 }
235 
ev_wait(int timeout)236 int ev_wait(int timeout) {
237   g_polled_events_count = epoll_wait(g_epoll_fd, g_polled_events, g_ev_count, timeout);
238   if (g_polled_events_count <= 0) {
239     return -1;
240   }
241   return 0;
242 }
243 
ev_dispatch(void)244 void ev_dispatch(void) {
245   for (int n = 0; n < g_polled_events_count; n++) {
246     FdInfo* fdi = static_cast<FdInfo*>(g_polled_events[n].data.ptr);
247     const ev_callback& cb = fdi->cb;
248     if (cb) {
249       cb(fdi->fd, g_polled_events[n].events);
250     }
251   }
252 }
253 
ev_get_input(int fd,uint32_t epevents,input_event * ev)254 int ev_get_input(int fd, uint32_t epevents, input_event* ev) {
255   if (epevents & EPOLLIN) {
256     ssize_t r = TEMP_FAILURE_RETRY(read(fd, ev, sizeof(*ev)));
257     if (r == sizeof(*ev)) {
258       return 0;
259     }
260   }
261   if (epevents & EPOLLHUP) {
262     // Delete this watch
263     epoll_ctl(g_epoll_fd, EPOLL_CTL_DEL, fd, nullptr);
264   }
265   return -1;
266 }
267 
ev_sync_key_state(const ev_set_key_callback & set_key_cb)268 int ev_sync_key_state(const ev_set_key_callback& set_key_cb) {
269   // Use unsigned long to match ioctl's parameter type.
270   unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)];    // NOLINT
271   unsigned long key_bits[BITS_TO_LONGS(KEY_MAX)];  // NOLINT
272 
273   for (size_t i = 0; i < g_ev_dev_count; ++i) {
274     memset(ev_bits, 0, sizeof(ev_bits));
275     memset(key_bits, 0, sizeof(key_bits));
276 
277     if (ioctl(ev_fdinfo[i].fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1) {
278       continue;
279     }
280     if (!test_bit(EV_KEY, ev_bits)) {
281       continue;
282     }
283     if (ioctl(ev_fdinfo[i].fd, EVIOCGKEY(sizeof(key_bits)), key_bits) == -1) {
284       continue;
285     }
286 
287     for (int code = 0; code <= KEY_MAX; code++) {
288       if (test_bit(code, key_bits)) {
289         set_key_cb(code, 1);
290       }
291     }
292   }
293 
294   return 0;
295 }
296 
ev_iterate_available_keys(const std::function<void (int)> & f)297 void ev_iterate_available_keys(const std::function<void(int)>& f) {
298   // Use unsigned long to match ioctl's parameter type.
299   unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)];    // NOLINT
300   unsigned long key_bits[BITS_TO_LONGS(KEY_MAX)];  // NOLINT
301 
302   for (size_t i = 0; i < g_ev_dev_count; ++i) {
303     memset(ev_bits, 0, sizeof(ev_bits));
304     memset(key_bits, 0, sizeof(key_bits));
305 
306     // Does this device even have keys?
307     if (ioctl(ev_fdinfo[i].fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1) {
308       continue;
309     }
310     if (!test_bit(EV_KEY, ev_bits)) {
311       continue;
312     }
313 
314     if (ioctl(ev_fdinfo[i].fd, EVIOCGBIT(EV_KEY, KEY_MAX), key_bits) == -1) {
315       continue;
316     }
317 
318     for (int key_code = 0; key_code <= KEY_MAX; ++key_code) {
319       if (test_bit(key_code, key_bits)) {
320         f(key_code);
321       }
322     }
323   }
324 }
325 
ev_iterate_touch_inputs(const std::function<void (int)> & action)326 void ev_iterate_touch_inputs(const std::function<void(int)>& action) {
327   for (size_t i = 0; i < g_ev_dev_count; ++i) {
328     // Use unsigned long to match ioctl's parameter type.
329     unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)] = {};  // NOLINT
330     if (ioctl(ev_fdinfo[i].fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1) {
331       continue;
332     }
333     if (!test_bit(EV_ABS, ev_bits)) {
334       continue;
335     }
336 
337     unsigned long key_bits[BITS_TO_LONGS(KEY_MAX)] = {};  // NOLINT
338     if (ioctl(ev_fdinfo[i].fd, EVIOCGBIT(EV_ABS, KEY_MAX), key_bits) == -1) {
339       continue;
340     }
341 
342     for (int key_code = 0; key_code <= KEY_MAX; ++key_code) {
343       if (test_bit(key_code, key_bits)) {
344         action(key_code);
345       }
346     }
347   }
348 }
349