summaryrefslogtreecommitdiffstats
path: root/libs/ui/EventHub.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/ui/EventHub.cpp')
-rw-r--r--libs/ui/EventHub.cpp585
1 files changed, 287 insertions, 298 deletions
diff --git a/libs/ui/EventHub.cpp b/libs/ui/EventHub.cpp
index b312cda..8f4bac6 100644
--- a/libs/ui/EventHub.cpp
+++ b/libs/ui/EventHub.cpp
@@ -33,6 +33,8 @@
#include <assert.h>
#include <ui/KeyLayoutMap.h>
+#include <ui/KeyCharacterMap.h>
+#include <ui/VirtualKeyMap.h>
#include <string.h>
#include <stdint.h>
@@ -56,10 +58,6 @@
/* this macro computes the number of bytes needed to represent a bit array of the specified size */
#define sizeof_bit_array(bits) ((bits + 7) / 8)
-#define ID_MASK 0x0000ffff
-#define SEQ_MASK 0x7fff0000
-#define SEQ_SHIFT 16
-
#ifndef ABS_MT_TOUCH_MAJOR
#define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */
#endif
@@ -72,6 +70,9 @@
#define ABS_MT_POSITION_Y 0x36 /* Center Y ellipse position */
#endif
+// Fd at index 0 is always reserved for inotify
+#define FIRST_ACTUAL_DEVICE_INDEX 1
+
#define INDENT " "
#define INDENT2 " "
#define INDENT3 " "
@@ -79,7 +80,7 @@
namespace android {
static const char *WAKE_LOCK_ID = "KeyEvents";
-static const char *device_path = "/dev/input";
+static const char *DEVICE_PATH = "/dev/input";
/* return the larger integer */
static inline int max(int v1, int v2)
@@ -91,63 +92,69 @@ static inline const char* toString(bool value) {
return value ? "true" : "false";
}
-EventHub::device_t::device_t(int32_t _id, const char* _path, const char* name)
- : id(_id), path(_path), name(name), classes(0)
- , keyBitmask(NULL), layoutMap(NULL), configuration(NULL), fd(-1), next(NULL) {
+// --- EventHub::Device ---
+
+EventHub::Device::Device(int fd, int32_t id, const String8& path,
+ const InputDeviceIdentifier& identifier) :
+ next(NULL),
+ fd(fd), id(id), path(path), identifier(identifier),
+ classes(0), keyBitmask(NULL), configuration(NULL), virtualKeyMap(NULL) {
}
-EventHub::device_t::~device_t() {
- delete [] keyBitmask;
- delete layoutMap;
+EventHub::Device::~Device() {
+ close();
+ delete[] keyBitmask;
delete configuration;
+ delete virtualKeyMap;
}
-EventHub::EventHub(void)
- : mError(NO_INIT), mHaveFirstKeyboard(false), mFirstKeyboardId(-1)
- , mDevicesById(0), mNumDevicesById(0)
- , mOpeningDevices(0), mClosingDevices(0)
- , mDevices(0), mFDs(0), mFDCount(0), mOpened(false), mNeedToSendFinishedDeviceScan(false)
- , mInputBufferIndex(0), mInputBufferCount(0), mInputDeviceIndex(0)
-{
+void EventHub::Device::close() {
+ if (fd >= 0) {
+ ::close(fd);
+ fd = -1;
+ }
+}
+
+
+// --- EventHub ---
+
+EventHub::EventHub(void) :
+ mError(NO_INIT), mBuiltInKeyboardId(-1), mNextDeviceId(1),
+ mOpeningDevices(0), mClosingDevices(0),
+ mOpened(false), mNeedToSendFinishedDeviceScan(false),
+ mInputBufferIndex(0), mInputBufferCount(0), mInputFdIndex(0) {
acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
#ifdef EV_SW
memset(mSwitches, 0, sizeof(mSwitches));
#endif
}
-/*
- * Clean up.
- */
-EventHub::~EventHub(void)
-{
+EventHub::~EventHub(void) {
release_wake_lock(WAKE_LOCK_ID);
// we should free stuff here...
}
-status_t EventHub::errorCheck() const
-{
+status_t EventHub::errorCheck() const {
return mError;
}
-String8 EventHub::getDeviceName(int32_t deviceId) const
-{
+String8 EventHub::getDeviceName(int32_t deviceId) const {
AutoMutex _l(mLock);
- device_t* device = getDeviceLocked(deviceId);
+ Device* device = getDeviceLocked(deviceId);
if (device == NULL) return String8();
- return device->name;
+ return device->identifier.name;
}
-uint32_t EventHub::getDeviceClasses(int32_t deviceId) const
-{
+uint32_t EventHub::getDeviceClasses(int32_t deviceId) const {
AutoMutex _l(mLock);
- device_t* device = getDeviceLocked(deviceId);
+ Device* device = getDeviceLocked(deviceId);
if (device == NULL) return 0;
return device->classes;
}
void EventHub::getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const {
AutoMutex _l(mLock);
- device_t* device = getDeviceLocked(deviceId);
+ Device* device = getDeviceLocked(deviceId);
if (device && device->configuration) {
*outConfiguration = *device->configuration;
} else {
@@ -160,14 +167,14 @@ status_t EventHub::getAbsoluteAxisInfo(int32_t deviceId, int axis,
outAxisInfo->clear();
AutoMutex _l(mLock);
- device_t* device = getDeviceLocked(deviceId);
+ Device* device = getDeviceLocked(deviceId);
if (device == NULL) return -1;
struct input_absinfo info;
if(ioctl(device->fd, EVIOCGABS(axis), &info)) {
LOGW("Error reading absolute controller %d for device %s fd %d\n",
- axis, device->name.string(), device->fd);
+ axis, device->identifier.name.string(), device->fd);
return -errno;
}
@@ -185,7 +192,7 @@ int32_t EventHub::getScanCodeState(int32_t deviceId, int32_t scanCode) const {
if (scanCode >= 0 && scanCode <= KEY_MAX) {
AutoMutex _l(mLock);
- device_t* device = getDeviceLocked(deviceId);
+ Device* device = getDeviceLocked(deviceId);
if (device != NULL) {
return getScanCodeStateLocked(device, scanCode);
}
@@ -193,7 +200,7 @@ int32_t EventHub::getScanCodeState(int32_t deviceId, int32_t scanCode) const {
return AKEY_STATE_UNKNOWN;
}
-int32_t EventHub::getScanCodeStateLocked(device_t* device, int32_t scanCode) const {
+int32_t EventHub::getScanCodeStateLocked(Device* device, int32_t scanCode) const {
uint8_t key_bitmask[sizeof_bit_array(KEY_MAX + 1)];
memset(key_bitmask, 0, sizeof(key_bitmask));
if (ioctl(device->fd,
@@ -206,20 +213,20 @@ int32_t EventHub::getScanCodeStateLocked(device_t* device, int32_t scanCode) con
int32_t EventHub::getKeyCodeState(int32_t deviceId, int32_t keyCode) const {
AutoMutex _l(mLock);
- device_t* device = getDeviceLocked(deviceId);
+ Device* device = getDeviceLocked(deviceId);
if (device != NULL) {
return getKeyCodeStateLocked(device, keyCode);
}
return AKEY_STATE_UNKNOWN;
}
-int32_t EventHub::getKeyCodeStateLocked(device_t* device, int32_t keyCode) const {
- if (!device->layoutMap) {
+int32_t EventHub::getKeyCodeStateLocked(Device* device, int32_t keyCode) const {
+ if (!device->keyMap.haveKeyLayout()) {
return AKEY_STATE_UNKNOWN;
}
Vector<int32_t> scanCodes;
- device->layoutMap->findScanCodes(keyCode, &scanCodes);
+ device->keyMap.keyLayoutMap->findScanCodes(keyCode, &scanCodes);
uint8_t key_bitmask[sizeof_bit_array(KEY_MAX + 1)];
memset(key_bitmask, 0, sizeof(key_bitmask));
@@ -247,7 +254,7 @@ int32_t EventHub::getSwitchState(int32_t deviceId, int32_t sw) const {
if (sw >= 0 && sw <= SW_MAX) {
AutoMutex _l(mLock);
- device_t* device = getDeviceLocked(deviceId);
+ Device* device = getDeviceLocked(deviceId);
if (device != NULL) {
return getSwitchStateLocked(device, sw);
}
@@ -256,7 +263,7 @@ int32_t EventHub::getSwitchState(int32_t deviceId, int32_t sw) const {
return AKEY_STATE_UNKNOWN;
}
-int32_t EventHub::getSwitchStateLocked(device_t* device, int32_t sw) const {
+int32_t EventHub::getSwitchStateLocked(Device* device, int32_t sw) const {
uint8_t sw_bitmask[sizeof_bit_array(SW_MAX + 1)];
memset(sw_bitmask, 0, sizeof(sw_bitmask));
if (ioctl(device->fd,
@@ -270,16 +277,16 @@ bool EventHub::markSupportedKeyCodes(int32_t deviceId, size_t numCodes,
const int32_t* keyCodes, uint8_t* outFlags) const {
AutoMutex _l(mLock);
- device_t* device = getDeviceLocked(deviceId);
+ Device* device = getDeviceLocked(deviceId);
if (device != NULL) {
return markSupportedKeyCodesLocked(device, numCodes, keyCodes, outFlags);
}
return false;
}
-bool EventHub::markSupportedKeyCodesLocked(device_t* device, size_t numCodes,
+bool EventHub::markSupportedKeyCodesLocked(Device* device, size_t numCodes,
const int32_t* keyCodes, uint8_t* outFlags) const {
- if (device->layoutMap == NULL || device->keyBitmask == NULL) {
+ if (!device->keyMap.haveKeyLayout() || !device->keyBitmask) {
return false;
}
@@ -287,7 +294,7 @@ bool EventHub::markSupportedKeyCodesLocked(device_t* device, size_t numCodes,
for (size_t codeIndex = 0; codeIndex < numCodes; codeIndex++) {
scanCodes.clear();
- status_t err = device->layoutMap->findScanCodes(keyCodes[codeIndex], &scanCodes);
+ status_t err = device->keyMap.keyLayoutMap->findScanCodes(keyCodes[codeIndex], &scanCodes);
if (! err) {
// check the possible scan codes identified by the layout map against the
// map of codes actually emitted by the driver
@@ -306,20 +313,20 @@ status_t EventHub::scancodeToKeycode(int32_t deviceId, int scancode,
int32_t* outKeycode, uint32_t* outFlags) const
{
AutoMutex _l(mLock);
- device_t* device = getDeviceLocked(deviceId);
+ Device* device = getDeviceLocked(deviceId);
- if (device != NULL && device->layoutMap != NULL) {
- status_t err = device->layoutMap->map(scancode, outKeycode, outFlags);
+ if (device && device->keyMap.haveKeyLayout()) {
+ status_t err = device->keyMap.keyLayoutMap->map(scancode, outKeycode, outFlags);
if (err == NO_ERROR) {
return NO_ERROR;
}
}
- if (mHaveFirstKeyboard) {
- device = getDeviceLocked(mFirstKeyboardId);
+ if (mBuiltInKeyboardId != -1) {
+ device = getDeviceLocked(mBuiltInKeyboardId);
- if (device != NULL && device->layoutMap != NULL) {
- status_t err = device->layoutMap->map(scancode, outKeycode, outFlags);
+ if (device && device->keyMap.haveKeyLayout()) {
+ status_t err = device->keyMap.keyLayoutMap->map(scancode, outKeycode, outFlags);
if (err == NO_ERROR) {
return NO_ERROR;
}
@@ -341,7 +348,7 @@ void EventHub::addExcludedDevice(const char* deviceName)
bool EventHub::hasLed(int32_t deviceId, int32_t led) const {
AutoMutex _l(mLock);
- device_t* device = getDeviceLocked(deviceId);
+ Device* device = getDeviceLocked(deviceId);
if (device) {
uint8_t bitmask[sizeof_bit_array(LED_MAX + 1)];
memset(bitmask, 0, sizeof(bitmask));
@@ -356,7 +363,7 @@ bool EventHub::hasLed(int32_t deviceId, int32_t led) const {
void EventHub::setLedState(int32_t deviceId, int32_t led, bool on) {
AutoMutex _l(mLock);
- device_t* device = getDeviceLocked(deviceId);
+ Device* device = getDeviceLocked(deviceId);
if (device) {
struct input_event ev;
ev.time.tv_sec = 0;
@@ -372,21 +379,33 @@ void EventHub::setLedState(int32_t deviceId, int32_t led, bool on) {
}
}
-EventHub::device_t* EventHub::getDeviceLocked(int32_t deviceId) const
-{
- if (deviceId == 0) deviceId = mFirstKeyboardId;
- int32_t id = deviceId & ID_MASK;
- if (id >= mNumDevicesById || id < 0) return NULL;
- device_t* dev = mDevicesById[id].device;
- if (dev == NULL) return NULL;
- if (dev->id == deviceId) {
- return dev;
+void EventHub::getVirtualKeyDefinitions(int32_t deviceId,
+ Vector<VirtualKeyDefinition>& outVirtualKeys) const {
+ outVirtualKeys.clear();
+
+ AutoMutex _l(mLock);
+ Device* device = getDeviceLocked(deviceId);
+ if (device && device->virtualKeyMap) {
+ outVirtualKeys.appendVector(device->virtualKeyMap->getVirtualKeys());
+ }
+}
+
+EventHub::Device* EventHub::getDeviceLocked(int32_t deviceId) const {
+ if (deviceId == 0) {
+ deviceId = mBuiltInKeyboardId;
+ }
+
+ size_t numDevices = mDevices.size();
+ for (size_t i = FIRST_ACTUAL_DEVICE_INDEX; i < numDevices; i++) {
+ Device* device = mDevices[i];
+ if (device->id == deviceId) {
+ return device;
+ }
}
return NULL;
}
-bool EventHub::getEvent(RawEvent* outEvent)
-{
+bool EventHub::getEvent(RawEvent* outEvent) {
outEvent->deviceId = 0;
outEvent->type = 0;
outEvent->scanCode = 0;
@@ -407,11 +426,11 @@ bool EventHub::getEvent(RawEvent* outEvent)
for (;;) {
// Report any devices that had last been added/removed.
if (mClosingDevices != NULL) {
- device_t* device = mClosingDevices;
- LOGV("Reporting device closed: id=0x%x, name=%s\n",
+ Device* device = mClosingDevices;
+ LOGV("Reporting device closed: id=%d, name=%s\n",
device->id, device->path.string());
mClosingDevices = device->next;
- if (device->id == mFirstKeyboardId) {
+ if (device->id == mBuiltInKeyboardId) {
outEvent->deviceId = 0;
} else {
outEvent->deviceId = device->id;
@@ -424,11 +443,11 @@ bool EventHub::getEvent(RawEvent* outEvent)
}
if (mOpeningDevices != NULL) {
- device_t* device = mOpeningDevices;
- LOGV("Reporting device opened: id=0x%x, name=%s\n",
+ Device* device = mOpeningDevices;
+ LOGV("Reporting device opened: id=%d, name=%s\n",
device->id, device->path.string());
mOpeningDevices = device->next;
- if (device->id == mFirstKeyboardId) {
+ if (device->id == mBuiltInKeyboardId) {
outEvent->deviceId = 0;
} else {
outEvent->deviceId = device->id;
@@ -451,11 +470,11 @@ bool EventHub::getEvent(RawEvent* outEvent)
// Consume buffered input events, if any.
if (mInputBufferIndex < mInputBufferCount) {
const struct input_event& iev = mInputBufferData[mInputBufferIndex++];
- const device_t* device = mDevices[mInputDeviceIndex];
+ const Device* device = mDevices[mInputFdIndex];
LOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, v=%d", device->path.string(),
(int) iev.time.tv_sec, (int) iev.time.tv_usec, iev.type, iev.code, iev.value);
- if (device->id == mFirstKeyboardId) {
+ if (device->id == mBuiltInKeyboardId) {
outEvent->deviceId = 0;
} else {
outEvent->deviceId = device->id;
@@ -465,8 +484,8 @@ bool EventHub::getEvent(RawEvent* outEvent)
outEvent->flags = 0;
if (iev.type == EV_KEY) {
outEvent->keyCode = AKEYCODE_UNKNOWN;
- if (device->layoutMap) {
- status_t err = device->layoutMap->map(iev.code,
+ if (device->keyMap.haveKeyLayout()) {
+ status_t err = device->keyMap.keyLayoutMap->map(iev.code,
&outEvent->keyCode, &outEvent->flags);
LOGV("iev.code=%d keyCode=%d flags=0x%08x err=%d\n",
iev.code, outEvent->keyCode, outEvent->flags, err);
@@ -486,13 +505,13 @@ bool EventHub::getEvent(RawEvent* outEvent)
// Finish reading all events from devices identified in previous poll().
// This code assumes that mInputDeviceIndex is initially 0 and that the
// revents member of pollfd is initialized to 0 when the device is first added.
- // Since mFDs[0] is used for inotify, we process regular events starting at index 1.
- mInputDeviceIndex += 1;
- if (mInputDeviceIndex >= mFDCount) {
+ // Since mFds[0] is used for inotify, we process regular events starting at index 1.
+ mInputFdIndex += 1;
+ if (mInputFdIndex >= mFds.size()) {
break;
}
- const struct pollfd& pfd = mFDs[mInputDeviceIndex];
+ const struct pollfd& pfd = mFds[mInputFdIndex];
if (pfd.revents & POLLIN) {
int32_t readSize = read(pfd.fd, mInputBufferData,
sizeof(struct input_event) * INPUT_BUFFER_SIZE);
@@ -503,7 +522,7 @@ bool EventHub::getEvent(RawEvent* outEvent)
} else if ((readSize % sizeof(struct input_event)) != 0) {
LOGE("could not get event (wrong size: %d)", readSize);
} else {
- mInputBufferCount = readSize / sizeof(struct input_event);
+ mInputBufferCount = size_t(readSize) / sizeof(struct input_event);
mInputBufferIndex = 0;
}
}
@@ -512,14 +531,14 @@ bool EventHub::getEvent(RawEvent* outEvent)
#if HAVE_INOTIFY
// readNotify() will modify mFDs and mFDCount, so this must be done after
// processing all other events.
- if(mFDs[0].revents & POLLIN) {
- readNotify(mFDs[0].fd);
- mFDs[0].revents = 0;
+ if(mFds[0].revents & POLLIN) {
+ readNotify(mFds[0].fd);
+ mFds.editItemAt(0).revents = 0;
continue; // report added or removed devices immediately
}
#endif
- mInputDeviceIndex = 0;
+ mInputFdIndex = 0;
// Poll for events. Mind the wake lock dance!
// We hold a wake lock at all times except during poll(). This works due to some
@@ -531,7 +550,7 @@ bool EventHub::getEvent(RawEvent* outEvent)
// pending or currently being processed.
release_wake_lock(WAKE_LOCK_ID);
- int pollResult = poll(mFDs, mFDCount, -1);
+ int pollResult = poll(mFds.editArray(), mFds.size(), -1);
acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
@@ -547,36 +566,37 @@ bool EventHub::getEvent(RawEvent* outEvent)
/*
* Open the platform-specific input device.
*/
-bool EventHub::openPlatformInput(void)
-{
+bool EventHub::openPlatformInput(void) {
/*
* Open platform-specific input device(s).
*/
- int res;
+ int res, fd;
- mFDCount = 1;
- mFDs = (pollfd *)calloc(1, sizeof(mFDs[0]));
- mDevices = (device_t **)calloc(1, sizeof(mDevices[0]));
- mFDs[0].events = POLLIN;
- mFDs[0].revents = 0;
- mDevices[0] = NULL;
#ifdef HAVE_INOTIFY
- mFDs[0].fd = inotify_init();
- res = inotify_add_watch(mFDs[0].fd, device_path, IN_DELETE | IN_CREATE);
+ fd = inotify_init();
+ res = inotify_add_watch(fd, DEVICE_PATH, IN_DELETE | IN_CREATE);
if(res < 0) {
- LOGE("could not add watch for %s, %s\n", device_path, strerror(errno));
+ LOGE("could not add watch for %s, %s\n", DEVICE_PATH, strerror(errno));
}
#else
/*
* The code in EventHub::getEvent assumes that mFDs[0] is an inotify fd.
* We allocate space for it and set it to something invalid.
*/
- mFDs[0].fd = -1;
+ fd = -1;
#endif
- res = scanDir(device_path);
+ // Reserve fd index 0 for inotify.
+ struct pollfd pollfd;
+ pollfd.fd = fd;
+ pollfd.events = POLLIN;
+ pollfd.revents = 0;
+ mFds.push(pollfd);
+ mDevices.push(NULL);
+
+ res = scanDir(DEVICE_PATH);
if(res < 0) {
- LOGE("scan dir failed for %s\n", device_path);
+ LOGE("scan dir failed for %s\n", DEVICE_PATH);
}
return true;
@@ -604,129 +624,102 @@ static const int32_t GAMEPAD_KEYCODES[] = {
AKEYCODE_BUTTON_START, AKEYCODE_BUTTON_SELECT, AKEYCODE_BUTTON_MODE
};
-int EventHub::openDevice(const char *deviceName) {
- int version;
- int fd;
- struct pollfd *new_mFDs;
- device_t **new_devices;
- char **new_device_names;
- char name[80];
- char location[80];
- char idstr[80];
- struct input_id id;
+int EventHub::openDevice(const char *devicePath) {
+ char buffer[80];
- LOGV("Opening device: %s", deviceName);
+ LOGV("Opening device: %s", devicePath);
AutoMutex _l(mLock);
- fd = open(deviceName, O_RDWR);
+ int fd = open(devicePath, O_RDWR);
if(fd < 0) {
- LOGE("could not open %s, %s\n", deviceName, strerror(errno));
+ LOGE("could not open %s, %s\n", devicePath, strerror(errno));
return -1;
}
- if(ioctl(fd, EVIOCGVERSION, &version)) {
- LOGE("could not get driver version for %s, %s\n", deviceName, strerror(errno));
- return -1;
- }
- if(ioctl(fd, EVIOCGID, &id)) {
- LOGE("could not get driver id for %s, %s\n", deviceName, strerror(errno));
- return -1;
- }
- name[sizeof(name) - 1] = '\0';
- location[sizeof(location) - 1] = '\0';
- idstr[sizeof(idstr) - 1] = '\0';
- if(ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) {
- //fprintf(stderr, "could not get device name for %s, %s\n", deviceName, strerror(errno));
- name[0] = '\0';
+ InputDeviceIdentifier identifier;
+
+ // Get device name.
+ if(ioctl(fd, EVIOCGNAME(sizeof(buffer) - 1), &buffer) < 1) {
+ //fprintf(stderr, "could not get device name for %s, %s\n", devicePath, strerror(errno));
+ } else {
+ buffer[sizeof(buffer) - 1] = '\0';
+ identifier.name.setTo(buffer);
}
- // check to see if the device is on our excluded list
+ // Check to see if the device is on our excluded list
List<String8>::iterator iter = mExcludedDevices.begin();
List<String8>::iterator end = mExcludedDevices.end();
for ( ; iter != end; iter++) {
const char* test = *iter;
- if (strcmp(name, test) == 0) {
- LOGI("ignoring event id %s driver %s\n", deviceName, test);
+ if (identifier.name == test) {
+ LOGI("ignoring event id %s driver %s\n", devicePath, test);
close(fd);
return -1;
}
}
- if(ioctl(fd, EVIOCGPHYS(sizeof(location) - 1), &location) < 1) {
- //fprintf(stderr, "could not get location for %s, %s\n", deviceName, strerror(errno));
- location[0] = '\0';
- }
- if(ioctl(fd, EVIOCGUNIQ(sizeof(idstr) - 1), &idstr) < 1) {
- //fprintf(stderr, "could not get idstring for %s, %s\n", deviceName, strerror(errno));
- idstr[0] = '\0';
- }
-
- if (fcntl(fd, F_SETFL, O_NONBLOCK)) {
- LOGE("Error %d making device file descriptor non-blocking.", errno);
+ // Get device driver version.
+ int driverVersion;
+ if(ioctl(fd, EVIOCGVERSION, &driverVersion)) {
+ LOGE("could not get driver version for %s, %s\n", devicePath, strerror(errno));
close(fd);
return -1;
}
- int devid = 0;
- while (devid < mNumDevicesById) {
- if (mDevicesById[devid].device == NULL) {
- break;
- }
- devid++;
+ // Get device identifier.
+ struct input_id inputId;
+ if(ioctl(fd, EVIOCGID, &inputId)) {
+ LOGE("could not get device input id for %s, %s\n", devicePath, strerror(errno));
+ close(fd);
+ return -1;
}
- if (devid >= mNumDevicesById) {
- device_ent* new_devids = (device_ent*)realloc(mDevicesById,
- sizeof(mDevicesById[0]) * (devid + 1));
- if (new_devids == NULL) {
- LOGE("out of memory");
- return -1;
- }
- mDevicesById = new_devids;
- mNumDevicesById = devid+1;
- mDevicesById[devid].device = NULL;
- mDevicesById[devid].seq = 0;
+ identifier.bus = inputId.bustype;
+ identifier.product = inputId.product;
+ identifier.vendor = inputId.vendor;
+ identifier.version = inputId.version;
+
+ // Get device physical location.
+ if(ioctl(fd, EVIOCGPHYS(sizeof(buffer) - 1), &buffer) < 1) {
+ //fprintf(stderr, "could not get location for %s, %s\n", devicePath, strerror(errno));
+ } else {
+ buffer[sizeof(buffer) - 1] = '\0';
+ identifier.location.setTo(buffer);
}
- mDevicesById[devid].seq = (mDevicesById[devid].seq+(1<<SEQ_SHIFT))&SEQ_MASK;
- if (mDevicesById[devid].seq == 0) {
- mDevicesById[devid].seq = 1<<SEQ_SHIFT;
+ // Get device unique id.
+ if(ioctl(fd, EVIOCGUNIQ(sizeof(buffer) - 1), &buffer) < 1) {
+ //fprintf(stderr, "could not get idstring for %s, %s\n", devicePath, strerror(errno));
+ } else {
+ buffer[sizeof(buffer) - 1] = '\0';
+ identifier.uniqueId.setTo(buffer);
}
- new_mFDs = (pollfd*)realloc(mFDs, sizeof(mFDs[0]) * (mFDCount + 1));
- new_devices = (device_t**)realloc(mDevices, sizeof(mDevices[0]) * (mFDCount + 1));
- if (new_mFDs == NULL || new_devices == NULL) {
- LOGE("out of memory");
+ // Make file descriptor non-blocking for use with poll().
+ if (fcntl(fd, F_SETFL, O_NONBLOCK)) {
+ LOGE("Error %d making device file descriptor non-blocking.", errno);
+ close(fd);
return -1;
}
- mFDs = new_mFDs;
- mDevices = new_devices;
+
+ // Allocate device. (The device object takes ownership of the fd at this point.)
+ int32_t deviceId = mNextDeviceId++;
+ Device* device = new Device(fd, deviceId, String8(devicePath), identifier);
#if 0
- LOGI("add device %d: %s\n", mFDCount, deviceName);
- LOGI(" bus: %04x\n"
- " vendor %04x\n"
- " product %04x\n"
- " version %04x\n",
- id.bustype, id.vendor, id.product, id.version);
- LOGI(" name: \"%s\"\n", name);
- LOGI(" location: \"%s\"\n"
- " id: \"%s\"\n", location, idstr);
- LOGI(" version: %d.%d.%d\n",
- version >> 16, (version >> 8) & 0xff, version & 0xff);
+ LOGI("add device %d: %s\n", deviceId, devicePath);
+ LOGI(" bus: %04x\n"
+ " vendor %04x\n"
+ " product %04x\n"
+ " version %04x\n",
+ identifier.bus, identifier.vendor, identifier.product, identifier.version);
+ LOGI(" name: \"%s\"\n", identifier.name.string());
+ LOGI(" location: \"%s\"\n", identifier.location.string());
+ LOGI(" unique id: \"%s\"\n", identifier.uniqueId.string());
+ LOGI(" driver: v%d.%d.%d\n",
+ driverVersion >> 16, (driverVersion >> 8) & 0xff, driverVersion & 0xff);
#endif
- device_t* device = new device_t(devid|mDevicesById[devid].seq, deviceName, name);
- if (device == NULL) {
- LOGE("out of memory");
- return -1;
- }
-
- device->fd = fd;
- mFDs[mFDCount].fd = fd;
- mFDs[mFDCount].events = POLLIN;
- mFDs[mFDCount].revents = 0;
-
// Load the configuration file for the device.
loadConfiguration(device);
@@ -798,7 +791,7 @@ int EventHub::openDevice(const char *deviceName) {
bool hasSwitches = false;
if (ioctl(fd, EVIOCGBIT(EV_SW, sizeof(sw_bitmask)), sw_bitmask) >= 0) {
for (int i=0; i<EV_SW; i++) {
- //LOGI("Device 0x%x sw %d: has=%d", device->id, i, test_bit(i, sw_bitmask));
+ //LOGI("Device %d sw %d: has=%d", device->id, i, test_bit(i, sw_bitmask));
if (test_bit(i, sw_bitmask)) {
hasSwitches = true;
if (mSwitches[i] == 0) {
@@ -812,37 +805,29 @@ int EventHub::openDevice(const char *deviceName) {
}
#endif
- if ((device->classes & INPUT_DEVICE_CLASS_KEYBOARD) != 0) {
- // a more descriptive name
- device->name = name;
-
- // Configure the keymap for the device.
- configureKeyMap(device);
-
- // Tell the world about the devname (the descriptive name)
- if (!mHaveFirstKeyboard && !device->keyMapInfo.isDefaultKeyMap && strstr(name, "-keypad")) {
- // the built-in keyboard has a well-known device ID of 0,
- // this device better not go away.
- mHaveFirstKeyboard = true;
- mFirstKeyboardId = device->id;
- setKeyboardProperties(device, true);
- } else {
- // ensure mFirstKeyboardId is set to -something-.
- if (mFirstKeyboardId == -1) {
- mFirstKeyboardId = device->id;
- setKeyboardProperties(device, true);
- }
+ if ((device->classes & INPUT_DEVICE_CLASS_TOUCHSCREEN)) {
+ // Load the virtual keys for the touch screen, if any.
+ // We do this now so that we can make sure to load the keymap if necessary.
+ status_t status = loadVirtualKeyMap(device);
+ if (!status) {
+ device->classes |= INPUT_DEVICE_CLASS_KEYBOARD;
}
+ }
+
+ if ((device->classes & INPUT_DEVICE_CLASS_KEYBOARD) != 0) {
+ // Load the keymap for the device.
+ status_t status = loadKeyMap(device);
+
+ // Set system properties for the keyboard.
setKeyboardProperties(device, false);
- // Load the keylayout.
- if (!device->keyMapInfo.keyLayoutFile.isEmpty()) {
- status_t status = KeyLayoutMap::load(device->keyMapInfo.keyLayoutFile,
- &device->layoutMap);
- if (status) {
- LOGE("Error %d loading key layout file '%s'.", status,
- device->keyMapInfo.keyLayoutFile.string());
- }
+ // Register the keyboard as a built-in keyboard if it is eligible.
+ if (!status
+ && mBuiltInKeyboardId == -1
+ && isEligibleBuiltInKeyboard(device->identifier,
+ device->configuration, &device->keyMap)) {
+ mBuiltInKeyboardId = device->id;
+ setKeyboardProperties(device, true);
}
// 'Q' key support = cheap test of whether this is an alpha-capable kbd
@@ -866,76 +851,87 @@ int EventHub::openDevice(const char *deviceName) {
break;
}
}
-
- LOGI("New keyboard: device->id=0x%x devname='%s' keylayout='%s' keycharactermap='%s'\n",
- device->id, name,
- device->keyMapInfo.keyLayoutFile.string(),
- device->keyMapInfo.keyCharacterMapFile.string());
}
// If the device isn't recognized as something we handle, don't monitor it.
if (device->classes == 0) {
- LOGV("Dropping device %s %p, id = %d\n", deviceName, device, devid);
- close(fd);
+ LOGV("Dropping device: id=%d, path='%s', name='%s'",
+ deviceId, devicePath, device->identifier.name.string());
delete device;
return -1;
}
- LOGI("New device: path=%s name=%s id=0x%x (of 0x%x) index=%d fd=%d classes=0x%x "
- "configuration='%s'\n",
- deviceName, name, device->id, mNumDevicesById, mFDCount, fd, device->classes,
- device->configurationFile.string());
-
- LOGV("Adding device %s %p at %d, id = %d, classes = 0x%x\n",
- deviceName, device, mFDCount, devid, device->classes);
+ LOGI("New device: id=%d, fd=%d, path='%s', name='%s', classes=0x%x, "
+ "configuration='%s', keyLayout='%s', keyCharacterMap='%s', builtinKeyboard=%s",
+ deviceId, fd, devicePath, device->identifier.name.string(),
+ device->classes,
+ device->configurationFile.string(),
+ device->keyMap.keyLayoutFile.string(),
+ device->keyMap.keyCharacterMapFile.string(),
+ toString(mBuiltInKeyboardId == deviceId));
+
+ struct pollfd pollfd;
+ pollfd.fd = fd;
+ pollfd.events = POLLIN;
+ pollfd.revents = 0;
+ mFds.push(pollfd);
+ mDevices.push(device);
- mDevicesById[devid].device = device;
device->next = mOpeningDevices;
mOpeningDevices = device;
- mDevices[mFDCount] = device;
-
- mFDCount++;
return 0;
}
-void EventHub::loadConfiguration(device_t* device) {
- device->configurationFile = getInputDeviceConfigurationFilePath(device->name,
- INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION);
+void EventHub::loadConfiguration(Device* device) {
+ device->configurationFile = getInputDeviceConfigurationFilePathByDeviceIdentifier(
+ device->identifier, INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION);
if (device->configurationFile.isEmpty()) {
- LOGI("No input device configuration file found for device '%s'.",
- device->name.string());
+ LOGD("No input device configuration file found for device '%s'.",
+ device->identifier.name.string());
} else {
status_t status = PropertyMap::load(device->configurationFile,
&device->configuration);
if (status) {
- LOGE("Error loading input device configuration file for device '%s'.",
- device->name.string());
+ LOGE("Error loading input device configuration file for device '%s'. "
+ "Using default configuration.",
+ device->identifier.name.string());
}
}
}
-void EventHub::configureKeyMap(device_t* device) {
- android::resolveKeyMap(device->name, device->configuration, device->keyMapInfo);
+status_t EventHub::loadVirtualKeyMap(Device* device) {
+ // The virtual key map is supplied by the kernel as a system board property file.
+ String8 path;
+ path.append("/sys/board_properties/virtualkeys.");
+ path.append(device->identifier.name);
+ if (access(path.string(), R_OK)) {
+ return NAME_NOT_FOUND;
+ }
+ return VirtualKeyMap::load(path, &device->virtualKeyMap);
}
-void EventHub::setKeyboardProperties(device_t* device, bool firstKeyboard) {
- int32_t id = firstKeyboard ? 0 : device->id;
- android::setKeyboardProperties(id, device->name, device->keyMapInfo);
+status_t EventHub::loadKeyMap(Device* device) {
+ return device->keyMap.load(device->identifier, device->configuration);
}
-void EventHub::clearKeyboardProperties(device_t* device, bool firstKeyboard) {
- int32_t id = firstKeyboard ? 0 : device->id;
+void EventHub::setKeyboardProperties(Device* device, bool builtInKeyboard) {
+ int32_t id = builtInKeyboard ? 0 : device->id;
+ android::setKeyboardProperties(id, device->identifier,
+ device->keyMap.keyLayoutFile, device->keyMap.keyCharacterMapFile);
+}
+
+void EventHub::clearKeyboardProperties(Device* device, bool builtInKeyboard) {
+ int32_t id = builtInKeyboard ? 0 : device->id;
android::clearKeyboardProperties(id);
}
-bool EventHub::hasKeycodeLocked(device_t* device, int keycode) const
-{
- if (device->keyBitmask == NULL || device->layoutMap == NULL) {
+bool EventHub::hasKeycodeLocked(Device* device, int keycode) const {
+ if (!device->keyMap.haveKeyLayout() || !device->keyBitmask) {
return false;
}
Vector<int32_t> scanCodes;
- device->layoutMap->findScanCodes(keycode, &scanCodes);
+ device->keyMap.keyLayoutMap->findScanCodes(keycode, &scanCodes);
const size_t N = scanCodes.size();
for (size_t i=0; i<N && i<=KEY_MAX; i++) {
int32_t sc = scanCodes.itemAt(i);
@@ -947,29 +943,15 @@ bool EventHub::hasKeycodeLocked(device_t* device, int keycode) const
return false;
}
-int EventHub::closeDevice(const char *deviceName) {
+int EventHub::closeDevice(const char *devicePath) {
AutoMutex _l(mLock);
- int i;
- for(i = 1; i < mFDCount; i++) {
- if(strcmp(mDevices[i]->path.string(), deviceName) == 0) {
- //LOGD("remove device %d: %s\n", i, deviceName);
- device_t* device = mDevices[i];
-
- LOGI("Removed device: path=%s name=%s id=0x%x (of 0x%x) index=%d fd=%d classes=0x%x\n",
- device->path.string(), device->name.string(), device->id,
- mNumDevicesById, mFDCount, mFDs[i].fd, device->classes);
-
- // Clear this device's entry.
- int index = (device->id&ID_MASK);
- mDevicesById[index].device = NULL;
-
- // Close the file descriptor and compact the fd array.
- close(mFDs[i].fd);
- int count = mFDCount - i - 1;
- memmove(mDevices + i, mDevices + i + 1, sizeof(mDevices[0]) * count);
- memmove(mFDs + i, mFDs + i + 1, sizeof(mFDs[0]) * count);
- mFDCount--;
+ for (size_t i = FIRST_ACTUAL_DEVICE_INDEX; i < mDevices.size(); i++) {
+ Device* device = mDevices[i];
+ if (device->path == devicePath) {
+ LOGI("Removed device: path=%s name=%s id=%d fd=%d classes=0x%x\n",
+ device->path.string(), device->identifier.name.string(), device->id,
+ device->fd, device->classes);
#ifdef EV_SW
for (int j=0; j<EV_SW; j++) {
@@ -978,21 +960,25 @@ int EventHub::closeDevice(const char *deviceName) {
}
}
#endif
-
- device->next = mClosingDevices;
- mClosingDevices = device;
- if (device->id == mFirstKeyboardId) {
+ if (device->id == mBuiltInKeyboardId) {
LOGW("built-in keyboard device %s (id=%d) is closing! the apps will not like this",
- device->path.string(), mFirstKeyboardId);
- mFirstKeyboardId = -1;
+ device->path.string(), mBuiltInKeyboardId);
+ mBuiltInKeyboardId = -1;
clearKeyboardProperties(device, true);
}
clearKeyboardProperties(device, false);
+
+ mFds.removeAt(i);
+ mDevices.removeAt(i);
+ device->close();
+
+ device->next = mClosingDevices;
+ mClosingDevices = device;
return 0;
}
}
- LOGE("remove device: %s not found\n", deviceName);
+ LOGE("remove device: %s not found\n", devicePath);
return -1;
}
@@ -1016,7 +1002,7 @@ int EventHub::readNotify(int nfd) {
}
//printf("got %d bytes of event information\n", res);
- strcpy(devname, device_path);
+ strcpy(devname, DEVICE_PATH);
filename = devname + strlen(devname);
*filename++ = '/';
@@ -1040,7 +1026,6 @@ int EventHub::readNotify(int nfd) {
return 0;
}
-
int EventHub::scanDir(const char *dirname)
{
char devname[PATH_MAX];
@@ -1071,28 +1056,32 @@ void EventHub::dump(String8& dump) {
{ // acquire lock
AutoMutex _l(mLock);
- dump.appendFormat(INDENT "HaveFirstKeyboard: %s\n", toString(mHaveFirstKeyboard));
- dump.appendFormat(INDENT "FirstKeyboardId: 0x%x\n", mFirstKeyboardId);
+ dump.appendFormat(INDENT "BuiltInKeyboardId: %d\n", mBuiltInKeyboardId);
dump.append(INDENT "Devices:\n");
- for (int i = 0; i < mNumDevicesById; i++) {
- const device_t* device = mDevicesById[i].device;
+ for (size_t i = FIRST_ACTUAL_DEVICE_INDEX; i < mDevices.size(); i++) {
+ const Device* device = mDevices[i];
if (device) {
- if (mFirstKeyboardId == device->id) {
- dump.appendFormat(INDENT2 "0x%x: %s (aka device 0 - first keyboard)\n",
- device->id, device->name.string());
+ if (mBuiltInKeyboardId == device->id) {
+ dump.appendFormat(INDENT2 "%d: %s (aka device 0 - built-in keyboard)\n",
+ device->id, device->identifier.name.string());
} else {
- dump.appendFormat(INDENT2 "0x%x: %s\n", device->id, device->name.string());
+ dump.appendFormat(INDENT2 "%d: %s\n", device->id,
+ device->identifier.name.string());
}
dump.appendFormat(INDENT3 "Classes: 0x%08x\n", device->classes);
dump.appendFormat(INDENT3 "Path: %s\n", device->path.string());
- dump.appendFormat(INDENT3 "IsDefaultKeyMap: %s\n",
- toString(device->keyMapInfo.isDefaultKeyMap));
+ dump.appendFormat(INDENT3 "Location: %s\n", device->identifier.location.string());
+ dump.appendFormat(INDENT3 "UniqueId: %s\n", device->identifier.uniqueId.string());
+ dump.appendFormat(INDENT3 "Identifier: bus=0x%04x, vendor=0x%04x, "
+ "product=0x%04x, version=0x%04x\n",
+ device->identifier.bus, device->identifier.vendor,
+ device->identifier.product, device->identifier.version);
dump.appendFormat(INDENT3 "KeyLayoutFile: %s\n",
- device->keyMapInfo.keyLayoutFile.string());
+ device->keyMap.keyLayoutFile.string());
dump.appendFormat(INDENT3 "KeyCharacterMapFile: %s\n",
- device->keyMapInfo.keyCharacterMapFile.string());
+ device->keyMap.keyCharacterMapFile.string());
dump.appendFormat(INDENT3 "ConfigurationFile: %s\n",
device->configurationFile.string());
}