blob: a72f055c388c03a6c4ec6c1db0a493a982d3e345 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001//
2// Copyright 2005 The Android Open Source Project
3//
4// Handle events, like key input and vsync.
5//
6// The goal is to provide an optimized solution for Linux, not an
7// implementation that works well across all platforms. We expect
8// events to arrive on file descriptors, so that we can use a select()
9// select() call to sleep.
10//
11// We can't select() on anything but network sockets in Windows, so we
12// provide an alternative implementation of waitEvent for that platform.
13//
14#define LOG_TAG "EventHub"
15
16//#define LOG_NDEBUG 0
17
18#include <ui/EventHub.h>
19#include <hardware_legacy/power.h>
20
21#include <cutils/properties.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022#include <utils/Log.h>
23#include <utils/Timers.h>
Mathias Agopian3b4062e2009-05-31 19:13:00 -070024#include <utils/threads.h>
25#include <utils/List.h>
26#include <utils/Errors.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027
28#include <stdlib.h>
29#include <stdio.h>
30#include <unistd.h>
31#include <fcntl.h>
32#include <memory.h>
33#include <errno.h>
34#include <assert.h>
35
36#include "KeyLayoutMap.h"
37
38#include <string.h>
39#include <stdint.h>
40#include <dirent.h>
41#ifdef HAVE_INOTIFY
42# include <sys/inotify.h>
43#endif
44#ifdef HAVE_ANDROID_OS
45# include <sys/limits.h> /* not part of Linux */
46#endif
47#include <sys/poll.h>
48#include <sys/ioctl.h>
49
50/* this macro is used to tell if "bit" is set in "array"
51 * it selects a byte from the array, and does a boolean AND
52 * operation with a byte that only has the relevant bit set.
53 * eg. to check for the 12th bit, we do (array[1] & 1<<4)
54 */
55#define test_bit(bit, array) (array[bit/8] & (1<<(bit%8)))
56
57#define ID_MASK 0x0000ffff
58#define SEQ_MASK 0x7fff0000
59#define SEQ_SHIFT 16
60#define id_to_index(id) ((id&ID_MASK)+1)
61
62namespace android {
63
64static const char *WAKE_LOCK_ID = "KeyEvents";
65static const char *device_path = "/dev/input";
66
67/* return the larger integer */
68static inline int max(int v1, int v2)
69{
70 return (v1 > v2) ? v1 : v2;
71}
72
73EventHub::device_t::device_t(int32_t _id, const char* _path)
74 : id(_id), path(_path), classes(0)
75 , keyBitmask(NULL), layoutMap(new KeyLayoutMap()), next(NULL) {
76}
77
78EventHub::device_t::~device_t() {
79 delete [] keyBitmask;
80 delete layoutMap;
81}
82
83EventHub::EventHub(void)
84 : mError(NO_INIT), mHaveFirstKeyboard(false), mFirstKeyboardId(0)
85 , mDevicesById(0), mNumDevicesById(0)
86 , mOpeningDevices(0), mClosingDevices(0)
87 , mDevices(0), mFDs(0), mFDCount(0)
88{
89 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
90#ifdef EV_SW
91 memset(mSwitches, 0, sizeof(mSwitches));
92#endif
93}
94
95/*
96 * Clean up.
97 */
98EventHub::~EventHub(void)
99{
100 release_wake_lock(WAKE_LOCK_ID);
101 // we should free stuff here...
102}
103
104void EventHub::onFirstRef()
105{
106 mError = openPlatformInput() ? NO_ERROR : UNKNOWN_ERROR;
107}
108
109status_t EventHub::errorCheck() const
110{
111 return mError;
112}
113
114String8 EventHub::getDeviceName(int32_t deviceId) const
115{
116 AutoMutex _l(mLock);
117 device_t* device = getDevice(deviceId);
118 if (device == NULL) return String8();
119 return device->name;
120}
121
122uint32_t EventHub::getDeviceClasses(int32_t deviceId) const
123{
124 AutoMutex _l(mLock);
125 device_t* device = getDevice(deviceId);
126 if (device == NULL) return 0;
127 return device->classes;
128}
129
130int EventHub::getAbsoluteInfo(int32_t deviceId, int axis, int *outMinValue,
131 int* outMaxValue, int* outFlat, int* outFuzz) const
132{
133 AutoMutex _l(mLock);
134 device_t* device = getDevice(deviceId);
135 if (device == NULL) return -1;
136
137 struct input_absinfo info;
138
139 if(ioctl(mFDs[id_to_index(device->id)].fd, EVIOCGABS(axis), &info)) {
140 LOGE("Error reading absolute controller %d for device %s fd %d\n",
141 axis, device->name.string(), mFDs[id_to_index(device->id)].fd);
142 return -1;
143 }
144 *outMinValue = info.minimum;
145 *outMaxValue = info.maximum;
146 *outFlat = info.flat;
147 *outFuzz = info.fuzz;
148 return 0;
149}
150
151int EventHub::getSwitchState(int sw) const
152{
153#ifdef EV_SW
154 if (sw >= 0 && sw <= SW_MAX) {
155 int32_t devid = mSwitches[sw];
156 if (devid != 0) {
157 return getSwitchState(devid, sw);
158 }
159 }
160#endif
161 return -1;
162}
163
164int EventHub::getSwitchState(int32_t deviceId, int sw) const
165{
166#ifdef EV_SW
167 AutoMutex _l(mLock);
168 device_t* device = getDevice(deviceId);
169 if (device == NULL) return -1;
170
171 if (sw >= 0 && sw <= SW_MAX) {
172 uint8_t sw_bitmask[(SW_MAX+1)/8];
173 memset(sw_bitmask, 0, sizeof(sw_bitmask));
174 if (ioctl(mFDs[id_to_index(device->id)].fd,
175 EVIOCGSW(sizeof(sw_bitmask)), sw_bitmask) >= 0) {
176 return test_bit(sw, sw_bitmask) ? 1 : 0;
177 }
178 }
179#endif
180
181 return -1;
182}
183
184int EventHub::getScancodeState(int code) const
185{
186 return getScancodeState(mFirstKeyboardId, code);
187}
188
189int EventHub::getScancodeState(int32_t deviceId, int code) const
190{
191 AutoMutex _l(mLock);
192 device_t* device = getDevice(deviceId);
193 if (device == NULL) return -1;
194
195 if (code >= 0 && code <= KEY_MAX) {
196 uint8_t key_bitmask[(KEY_MAX+1)/8];
197 memset(key_bitmask, 0, sizeof(key_bitmask));
198 if (ioctl(mFDs[id_to_index(device->id)].fd,
199 EVIOCGKEY(sizeof(key_bitmask)), key_bitmask) >= 0) {
200 return test_bit(code, key_bitmask) ? 1 : 0;
201 }
202 }
203
204 return -1;
205}
206
207int EventHub::getKeycodeState(int code) const
208{
209 return getKeycodeState(mFirstKeyboardId, code);
210}
211
212int EventHub::getKeycodeState(int32_t deviceId, int code) const
213{
214 AutoMutex _l(mLock);
215 device_t* device = getDevice(deviceId);
216 if (device == NULL || device->layoutMap == NULL) return -1;
217
218 Vector<int32_t> scanCodes;
219 device->layoutMap->findScancodes(code, &scanCodes);
220
221 uint8_t key_bitmask[(KEY_MAX+1)/8];
222 memset(key_bitmask, 0, sizeof(key_bitmask));
223 if (ioctl(mFDs[id_to_index(device->id)].fd,
224 EVIOCGKEY(sizeof(key_bitmask)), key_bitmask) >= 0) {
225 #if 0
226 for (size_t i=0; i<=KEY_MAX; i++) {
227 LOGI("(Scan code %d: down=%d)", i, test_bit(i, key_bitmask));
228 }
229 #endif
230 const size_t N = scanCodes.size();
231 for (size_t i=0; i<N && i<=KEY_MAX; i++) {
232 int32_t sc = scanCodes.itemAt(i);
233 //LOGI("Code %d: down=%d", sc, test_bit(sc, key_bitmask));
234 if (sc >= 0 && sc <= KEY_MAX && test_bit(sc, key_bitmask)) {
235 return 1;
236 }
237 }
238 }
239
240 return 0;
241}
242
Dianne Hackborne3dd8842009-07-14 12:06:54 -0700243status_t EventHub::scancodeToKeycode(int32_t deviceId, int scancode,
244 int32_t* outKeycode, uint32_t* outFlags) const
245{
246 AutoMutex _l(mLock);
247 device_t* device = getDevice(deviceId);
248
249 if (device != NULL && device->layoutMap != NULL) {
250 status_t err = device->layoutMap->map(scancode, outKeycode, outFlags);
251 if (err == NO_ERROR) {
252 return NO_ERROR;
253 }
254 }
255
256 if (mHaveFirstKeyboard) {
257 device = getDevice(mFirstKeyboardId);
258
259 if (device != NULL && device->layoutMap != NULL) {
260 status_t err = device->layoutMap->map(scancode, outKeycode, outFlags);
261 if (err == NO_ERROR) {
262 return NO_ERROR;
263 }
264 }
265 }
266
267 *outKeycode = 0;
268 *outFlags = 0;
269 return NAME_NOT_FOUND;
270}
271
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800272EventHub::device_t* EventHub::getDevice(int32_t deviceId) const
273{
274 if (deviceId == 0) deviceId = mFirstKeyboardId;
275 int32_t id = deviceId & ID_MASK;
276 if (id >= mNumDevicesById || id < 0) return NULL;
277 device_t* dev = mDevicesById[id].device;
Dianne Hackborn4e829f02009-03-25 16:21:55 -0700278 if (dev == NULL) return NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279 if (dev->id == deviceId) {
280 return dev;
281 }
282 return NULL;
283}
284
285bool EventHub::getEvent(int32_t* outDeviceId, int32_t* outType,
286 int32_t* outScancode, int32_t* outKeycode, uint32_t *outFlags,
287 int32_t* outValue, nsecs_t* outWhen)
288{
289 *outDeviceId = 0;
290 *outType = 0;
291 *outScancode = 0;
292 *outKeycode = 0;
293 *outFlags = 0;
294 *outValue = 0;
295 *outWhen = 0;
296
297 status_t err;
298
299 fd_set readfds;
300 int maxFd = -1;
301 int cc;
302 int i;
303 int res;
304 int pollres;
305 struct input_event iev;
306
307 // Note that we only allow one caller to getEvent(), so don't need
308 // to do locking here... only when adding/removing devices.
309
310 while(1) {
311
312 // First, report any devices that had last been added/removed.
313 if (mClosingDevices != NULL) {
314 device_t* device = mClosingDevices;
315 LOGV("Reporting device closed: id=0x%x, name=%s\n",
316 device->id, device->path.string());
317 mClosingDevices = device->next;
318 *outDeviceId = device->id;
319 if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0;
320 *outType = DEVICE_REMOVED;
321 delete device;
322 return true;
323 }
324 if (mOpeningDevices != NULL) {
325 device_t* device = mOpeningDevices;
326 LOGV("Reporting device opened: id=0x%x, name=%s\n",
327 device->id, device->path.string());
328 mOpeningDevices = device->next;
329 *outDeviceId = device->id;
330 if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0;
331 *outType = DEVICE_ADDED;
332 return true;
333 }
334
335 release_wake_lock(WAKE_LOCK_ID);
336
337 pollres = poll(mFDs, mFDCount, -1);
338
339 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
340
341 if (pollres <= 0) {
342 if (errno != EINTR) {
343 LOGW("select failed (errno=%d)\n", errno);
344 usleep(100000);
345 }
346 continue;
347 }
348
349 //printf("poll %d, returned %d\n", mFDCount, pollres);
350
351 // mFDs[0] is used for inotify, so process regular events starting at mFDs[1]
352 for(i = 1; i < mFDCount; i++) {
353 if(mFDs[i].revents) {
354 LOGV("revents for %d = 0x%08x", i, mFDs[i].revents);
355 if(mFDs[i].revents & POLLIN) {
356 res = read(mFDs[i].fd, &iev, sizeof(iev));
357 if (res == sizeof(iev)) {
358 LOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, v=%d",
359 mDevices[i]->path.string(),
360 (int) iev.time.tv_sec, (int) iev.time.tv_usec,
361 iev.type, iev.code, iev.value);
362 *outDeviceId = mDevices[i]->id;
363 if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0;
364 *outType = iev.type;
365 *outScancode = iev.code;
366 if (iev.type == EV_KEY) {
367 err = mDevices[i]->layoutMap->map(iev.code, outKeycode, outFlags);
368 LOGV("iev.code=%d outKeycode=%d outFlags=0x%08x err=%d\n",
369 iev.code, *outKeycode, *outFlags, err);
370 if (err != 0) {
371 *outKeycode = 0;
372 *outFlags = 0;
373 }
374 } else {
375 *outKeycode = iev.code;
376 }
377 *outValue = iev.value;
378 *outWhen = s2ns(iev.time.tv_sec) + us2ns(iev.time.tv_usec);
379 return true;
380 } else {
381 if (res<0) {
382 LOGW("could not get event (errno=%d)", errno);
383 } else {
384 LOGE("could not get event (wrong size: %d)", res);
385 }
386 continue;
387 }
388 }
389 }
390 }
391
392 // read_notify() will modify mFDs and mFDCount, so this must be done after
393 // processing all other events.
394 if(mFDs[0].revents & POLLIN) {
395 read_notify(mFDs[0].fd);
396 }
397 }
398}
399
400/*
401 * Open the platform-specific input device.
402 */
403bool EventHub::openPlatformInput(void)
404{
405 /*
406 * Open platform-specific input device(s).
407 */
408 int res;
409
410 mFDCount = 1;
411 mFDs = (pollfd *)calloc(1, sizeof(mFDs[0]));
412 mDevices = (device_t **)calloc(1, sizeof(mDevices[0]));
413 mFDs[0].events = POLLIN;
414 mDevices[0] = NULL;
415#ifdef HAVE_INOTIFY
416 mFDs[0].fd = inotify_init();
417 res = inotify_add_watch(mFDs[0].fd, device_path, IN_DELETE | IN_CREATE);
418 if(res < 0) {
419 LOGE("could not add watch for %s, %s\n", device_path, strerror(errno));
420 }
421#else
422 /*
423 * The code in EventHub::getEvent assumes that mFDs[0] is an inotify fd.
424 * We allocate space for it and set it to something invalid.
425 */
426 mFDs[0].fd = -1;
427#endif
428
429 res = scan_dir(device_path);
430 if(res < 0) {
431 LOGE("scan dir failed for %s\n", device_path);
432 //open_device("/dev/input/event0");
433 }
434
435 return true;
436}
437
438/*
439 * Inspect the known devices to determine whether physical keys exist for the given
440 * framework-domain key codes.
441 */
442bool EventHub::hasKeys(size_t numCodes, int32_t* keyCodes, uint8_t* outFlags) {
443 for (size_t codeIndex = 0; codeIndex < numCodes; codeIndex++) {
444 outFlags[codeIndex] = 0;
445
446 // check each available hardware device for support for this keycode
447 Vector<int32_t> scanCodes;
448 for (int n = 0; (n < mFDCount) && (outFlags[codeIndex] == 0); n++) {
449 if (mDevices[n]) {
450 status_t err = mDevices[n]->layoutMap->findScancodes(keyCodes[codeIndex], &scanCodes);
451 if (!err) {
452 // check the possible scan codes identified by the layout map against the
453 // map of codes actually emitted by the driver
454 for (size_t sc = 0; sc < scanCodes.size(); sc++) {
455 if (test_bit(scanCodes[sc], mDevices[n]->keyBitmask)) {
456 outFlags[codeIndex] = 1;
457 break;
458 }
459 }
460 }
461 }
462 }
463 }
464
465 return true;
466}
467
468// ----------------------------------------------------------------------------
469
470int EventHub::open_device(const char *deviceName)
471{
472 int version;
473 int fd;
474 struct pollfd *new_mFDs;
475 device_t **new_devices;
476 char **new_device_names;
477 char name[80];
478 char location[80];
479 char idstr[80];
480 struct input_id id;
481
482 LOGV("Opening device: %s", deviceName);
483
484 AutoMutex _l(mLock);
485
486 fd = open(deviceName, O_RDWR);
487 if(fd < 0) {
488 LOGE("could not open %s, %s\n", deviceName, strerror(errno));
489 return -1;
490 }
491
492 if(ioctl(fd, EVIOCGVERSION, &version)) {
493 LOGE("could not get driver version for %s, %s\n", deviceName, strerror(errno));
494 return -1;
495 }
496 if(ioctl(fd, EVIOCGID, &id)) {
497 LOGE("could not get driver id for %s, %s\n", deviceName, strerror(errno));
498 return -1;
499 }
500 name[sizeof(name) - 1] = '\0';
501 location[sizeof(location) - 1] = '\0';
502 idstr[sizeof(idstr) - 1] = '\0';
503 if(ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) {
504 //fprintf(stderr, "could not get device name for %s, %s\n", deviceName, strerror(errno));
505 name[0] = '\0';
506 }
507 if(ioctl(fd, EVIOCGPHYS(sizeof(location) - 1), &location) < 1) {
508 //fprintf(stderr, "could not get location for %s, %s\n", deviceName, strerror(errno));
509 location[0] = '\0';
510 }
511 if(ioctl(fd, EVIOCGUNIQ(sizeof(idstr) - 1), &idstr) < 1) {
512 //fprintf(stderr, "could not get idstring for %s, %s\n", deviceName, strerror(errno));
513 idstr[0] = '\0';
514 }
515
516 int devid = 0;
517 while (devid < mNumDevicesById) {
518 if (mDevicesById[devid].device == NULL) {
519 break;
520 }
521 devid++;
522 }
523 if (devid >= mNumDevicesById) {
524 device_ent* new_devids = (device_ent*)realloc(mDevicesById,
525 sizeof(mDevicesById[0]) * (devid + 1));
526 if (new_devids == NULL) {
527 LOGE("out of memory");
528 return -1;
529 }
530 mDevicesById = new_devids;
531 mNumDevicesById = devid+1;
532 mDevicesById[devid].device = NULL;
533 mDevicesById[devid].seq = 0;
534 }
535
536 mDevicesById[devid].seq = (mDevicesById[devid].seq+(1<<SEQ_SHIFT))&SEQ_MASK;
537 if (mDevicesById[devid].seq == 0) {
538 mDevicesById[devid].seq = 1<<SEQ_SHIFT;
539 }
540
541 new_mFDs = (pollfd*)realloc(mFDs, sizeof(mFDs[0]) * (mFDCount + 1));
542 new_devices = (device_t**)realloc(mDevices, sizeof(mDevices[0]) * (mFDCount + 1));
543 if (new_mFDs == NULL || new_devices == NULL) {
544 LOGE("out of memory");
545 return -1;
546 }
547 mFDs = new_mFDs;
548 mDevices = new_devices;
549
550#if 0
551 LOGI("add device %d: %s\n", mFDCount, deviceName);
552 LOGI(" bus: %04x\n"
553 " vendor %04x\n"
554 " product %04x\n"
555 " version %04x\n",
556 id.bustype, id.vendor, id.product, id.version);
557 LOGI(" name: \"%s\"\n", name);
558 LOGI(" location: \"%s\"\n"
559 " id: \"%s\"\n", location, idstr);
560 LOGI(" version: %d.%d.%d\n",
561 version >> 16, (version >> 8) & 0xff, version & 0xff);
562#endif
563
564 device_t* device = new device_t(devid|mDevicesById[devid].seq, deviceName);
565 if (device == NULL) {
566 LOGE("out of memory");
567 return -1;
568 }
569
570 mFDs[mFDCount].fd = fd;
571 mFDs[mFDCount].events = POLLIN;
572
573 // figure out the kinds of events the device reports
574 uint8_t key_bitmask[(KEY_MAX+1)/8];
575 memset(key_bitmask, 0, sizeof(key_bitmask));
576 LOGV("Getting keys...");
577 if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask) >= 0) {
578 //LOGI("MAP\n");
579 //for (int i=0; i<((KEY_MAX+1)/8); i++) {
580 // LOGI("%d: 0x%02x\n", i, key_bitmask[i]);
581 //}
582 for (int i=0; i<((BTN_MISC+7)/8); i++) {
583 if (key_bitmask[i] != 0) {
584 device->classes |= CLASS_KEYBOARD;
585 // 'Q' key support = cheap test of whether this is an alpha-capable kbd
586 if (test_bit(KEY_Q, key_bitmask)) {
587 device->classes |= CLASS_ALPHAKEY;
588 }
589 break;
590 }
591 }
592 if ((device->classes & CLASS_KEYBOARD) != 0) {
593 device->keyBitmask = new uint8_t[(KEY_MAX+1)/8];
594 if (device->keyBitmask != NULL) {
595 memcpy(device->keyBitmask, key_bitmask, sizeof(key_bitmask));
596 } else {
597 delete device;
598 LOGE("out of memory allocating key bitmask");
599 return -1;
600 }
601 }
602 }
603 if (test_bit(BTN_MOUSE, key_bitmask)) {
604 uint8_t rel_bitmask[(REL_MAX+1)/8];
605 memset(rel_bitmask, 0, sizeof(rel_bitmask));
606 LOGV("Getting relative controllers...");
607 if (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(rel_bitmask)), rel_bitmask) >= 0)
608 {
609 if (test_bit(REL_X, rel_bitmask) && test_bit(REL_Y, rel_bitmask)) {
610 device->classes |= CLASS_TRACKBALL;
611 }
612 }
613 }
614 if (test_bit(BTN_TOUCH, key_bitmask)) {
615 uint8_t abs_bitmask[(ABS_MAX+1)/8];
616 memset(abs_bitmask, 0, sizeof(abs_bitmask));
617 LOGV("Getting absolute controllers...");
618 if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask) >= 0)
619 {
620 if (test_bit(ABS_X, abs_bitmask) && test_bit(ABS_Y, abs_bitmask)) {
621 device->classes |= CLASS_TOUCHSCREEN;
622 }
623 }
624 }
625
626#ifdef EV_SW
627 // figure out the switches this device reports
628 uint8_t sw_bitmask[(SW_MAX+1)/8];
629 memset(sw_bitmask, 0, sizeof(sw_bitmask));
630 if (ioctl(fd, EVIOCGBIT(EV_SW, sizeof(sw_bitmask)), sw_bitmask) >= 0) {
631 for (int i=0; i<EV_SW; i++) {
632 //LOGI("Device 0x%x sw %d: has=%d", device->id, i, test_bit(i, sw_bitmask));
633 if (test_bit(i, sw_bitmask)) {
634 if (mSwitches[i] == 0) {
635 mSwitches[i] = device->id;
636 }
637 }
638 }
639 }
640#endif
641
642 LOGI("New device: path=%s name=%s id=0x%x (of 0x%x) index=%d fd=%d classes=0x%x\n",
643 deviceName, name, device->id, mNumDevicesById, mFDCount, fd, device->classes);
644
645 if ((device->classes&CLASS_KEYBOARD) != 0) {
646 char devname[101];
647 char tmpfn[101];
648 char keylayoutFilename[300];
649
650 // a more descriptive name
651 ioctl(mFDs[mFDCount].fd, EVIOCGNAME(sizeof(devname)-1), devname);
652 devname[sizeof(devname)-1] = 0;
653 device->name = devname;
654
655 // replace all the spaces with underscores
656 strcpy(tmpfn, devname);
657 for (char *p = strchr(tmpfn, ' '); p && *p; p = strchr(tmpfn, ' '))
658 *p = '_';
659
660 // find the .kl file we need for this device
661 const char* root = getenv("ANDROID_ROOT");
662 snprintf(keylayoutFilename, sizeof(keylayoutFilename),
663 "%s/usr/keylayout/%s.kl", root, tmpfn);
664 bool defaultKeymap = false;
665 if (access(keylayoutFilename, R_OK)) {
666 snprintf(keylayoutFilename, sizeof(keylayoutFilename),
667 "%s/usr/keylayout/%s", root, "qwerty.kl");
668 defaultKeymap = true;
669 }
670 device->layoutMap->load(keylayoutFilename);
671
672 // tell the world about the devname (the descriptive name)
673 int32_t publicID;
674 if (!mHaveFirstKeyboard && !defaultKeymap) {
675 publicID = 0;
676 // the built-in keyboard has a well-known device ID of 0,
677 // this device better not go away.
678 mHaveFirstKeyboard = true;
679 mFirstKeyboardId = device->id;
680 } else {
681 publicID = device->id;
682 // ensure mFirstKeyboardId is set to -something-.
683 if (mFirstKeyboardId == 0) {
684 mFirstKeyboardId = device->id;
685 }
686 }
687 char propName[100];
688 sprintf(propName, "hw.keyboards.%u.devname", publicID);
689 property_set(propName, devname);
690
691 LOGI("New keyboard: publicID=%d device->id=%d devname='%s' propName='%s' keylayout='%s'\n",
692 publicID, device->id, devname, propName, keylayoutFilename);
693 }
694
695 LOGV("Adding device %s %p at %d, id = %d, classes = 0x%x\n",
696 deviceName, device, mFDCount, devid, device->classes);
697
698 mDevicesById[devid].device = device;
699 device->next = mOpeningDevices;
700 mOpeningDevices = device;
701 mDevices[mFDCount] = device;
702
703 mFDCount++;
704 return 0;
705}
706
707int EventHub::close_device(const char *deviceName)
708{
709 AutoMutex _l(mLock);
710
711 int i;
712 for(i = 1; i < mFDCount; i++) {
713 if(strcmp(mDevices[i]->path.string(), deviceName) == 0) {
714 //LOGD("remove device %d: %s\n", i, deviceName);
715 device_t* device = mDevices[i];
716 int count = mFDCount - i - 1;
717 int index = (device->id&ID_MASK);
718 mDevicesById[index].device = NULL;
719 memmove(mDevices + i, mDevices + i + 1, sizeof(mDevices[0]) * count);
720 memmove(mFDs + i, mFDs + i + 1, sizeof(mFDs[0]) * count);
721
722#ifdef EV_SW
723 for (int j=0; j<EV_SW; j++) {
724 if (mSwitches[j] == device->id) {
725 mSwitches[j] = 0;
726 }
727 }
728#endif
729
730 device->next = mClosingDevices;
731 mClosingDevices = device;
732
733 mFDCount--;
734
735 uint32_t publicID;
736 if (device->id == mFirstKeyboardId) {
737 LOGW("built-in keyboard device %s (id=%d) is closing! the apps will not like this",
738 device->path.string(), mFirstKeyboardId);
739 mFirstKeyboardId = 0;
740 publicID = 0;
741 } else {
742 publicID = device->id;
743 }
744 // clear the property
745 char propName[100];
746 sprintf(propName, "hw.keyboards.%u.devname", publicID);
747 property_set(propName, NULL);
748 return 0;
749 }
750 }
751 LOGE("remote device: %s not found\n", deviceName);
752 return -1;
753}
754
755int EventHub::read_notify(int nfd)
756{
757#ifdef HAVE_INOTIFY
758 int res;
759 char devname[PATH_MAX];
760 char *filename;
761 char event_buf[512];
762 int event_size;
763 int event_pos = 0;
764 struct inotify_event *event;
765
766 res = read(nfd, event_buf, sizeof(event_buf));
767 if(res < (int)sizeof(*event)) {
768 if(errno == EINTR)
769 return 0;
770 LOGW("could not get event, %s\n", strerror(errno));
771 return 1;
772 }
773 //printf("got %d bytes of event information\n", res);
774
775 strcpy(devname, device_path);
776 filename = devname + strlen(devname);
777 *filename++ = '/';
778
779 while(res >= (int)sizeof(*event)) {
780 event = (struct inotify_event *)(event_buf + event_pos);
781 //printf("%d: %08x \"%s\"\n", event->wd, event->mask, event->len ? event->name : "");
782 if(event->len) {
783 strcpy(filename, event->name);
784 if(event->mask & IN_CREATE) {
785 open_device(devname);
786 }
787 else {
788 close_device(devname);
789 }
790 }
791 event_size = sizeof(*event) + event->len;
792 res -= event_size;
793 event_pos += event_size;
794 }
795#endif
796 return 0;
797}
798
799
800int EventHub::scan_dir(const char *dirname)
801{
802 char devname[PATH_MAX];
803 char *filename;
804 DIR *dir;
805 struct dirent *de;
806 dir = opendir(dirname);
807 if(dir == NULL)
808 return -1;
809 strcpy(devname, dirname);
810 filename = devname + strlen(devname);
811 *filename++ = '/';
812 while((de = readdir(dir))) {
813 if(de->d_name[0] == '.' &&
814 (de->d_name[1] == '\0' ||
815 (de->d_name[1] == '.' && de->d_name[2] == '\0')))
816 continue;
817 strcpy(filename, de->d_name);
818 open_device(devname);
819 }
820 closedir(dir);
821 return 0;
822}
823
824}; // namespace android